diff options
Diffstat (limited to 'gcc-4.8.1/libgo/runtime/sigqueue.goc')
-rw-r--r-- | gcc-4.8.1/libgo/runtime/sigqueue.goc | 161 |
1 files changed, 0 insertions, 161 deletions
diff --git a/gcc-4.8.1/libgo/runtime/sigqueue.goc b/gcc-4.8.1/libgo/runtime/sigqueue.goc deleted file mode 100644 index 82b0400d6..000000000 --- a/gcc-4.8.1/libgo/runtime/sigqueue.goc +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// This file implements runtime support for signal handling. -// -// Most synchronization primitives are not available from -// the signal handler (it cannot block, allocate memory, or use locks) -// so the handler communicates with a processing goroutine -// via struct sig, below. -// -// sigsend() is called by the signal handler to queue a new signal. -// signal_recv() is called by the Go program to receive a newly queued signal. -// Synchronization between sigsend() and signal_recv() is based on the sig.state -// variable. It can be in 3 states: 0, HASWAITER and HASSIGNAL. -// HASWAITER means that signal_recv() is blocked on sig.Note and there are no -// new pending signals. -// HASSIGNAL means that sig.mask *may* contain new pending signals, -// signal_recv() can't be blocked in this state. -// 0 means that there are no new pending signals and signal_recv() is not blocked. -// Transitions between states are done atomically with CAS. -// When signal_recv() is unblocked, it resets sig.Note and rechecks sig.mask. -// If several sigsend()'s and signal_recv() execute concurrently, it can lead to -// unnecessary rechecks of sig.mask, but must not lead to missed signals -// nor deadlocks. - -package signal -#include "config.h" -#include "runtime.h" -#include "arch.h" -#include "malloc.h" -#include "defs.h" - -static struct { - Note; - uint32 mask[(NSIG+31)/32]; - uint32 wanted[(NSIG+31)/32]; - uint32 state; - bool inuse; -} sig; - -enum { - HASWAITER = 1, - HASSIGNAL = 2, -}; - -// Called from sighandler to send a signal back out of the signal handling thread. -bool -__go_sigsend(int32 s) -{ - uint32 bit, mask, old, new; - - if(!sig.inuse || s < 0 || (size_t)s >= 32*nelem(sig.wanted) || !(sig.wanted[s/32]&(1U<<(s&31)))) - return false; - bit = 1 << (s&31); - for(;;) { - mask = sig.mask[s/32]; - if(mask & bit) - break; // signal already in queue - if(runtime_cas(&sig.mask[s/32], mask, mask|bit)) { - // Added to queue. - // Only send a wakeup if the receiver needs a kick. - for(;;) { - old = runtime_atomicload(&sig.state); - if(old == HASSIGNAL) - break; - if(old == HASWAITER) - new = 0; - else // if(old == 0) - new = HASSIGNAL; - if(runtime_cas(&sig.state, old, new)) { - if (old == HASWAITER) - runtime_notewakeup(&sig); - break; - } - } - break; - } - } - return true; -} - -// Called to receive the next queued signal. -// Must only be called from a single goroutine at a time. -func signal_recv() (m uint32) { - static uint32 recv[nelem(sig.mask)]; - uint32 i, old, new; - - for(;;) { - // Serve from local copy if there are bits left. - for(i=0; i<NSIG; i++) { - if(recv[i/32]&(1U<<(i&31))) { - recv[i/32] ^= 1U<<(i&31); - m = i; - goto done; - } - } - - // Check and update sig.state. - for(;;) { - old = runtime_atomicload(&sig.state); - if(old == HASWAITER) - runtime_throw("inconsistent state in signal_recv"); - if(old == HASSIGNAL) - new = 0; - else // if(old == 0) - new = HASWAITER; - if(runtime_cas(&sig.state, old, new)) { - if (new == HASWAITER) { - runtime_entersyscall(); - runtime_notesleep(&sig); - runtime_exitsyscall(); - runtime_noteclear(&sig); - } - break; - } - } - - // Get a new local copy. - for(i=0; (size_t)i<nelem(sig.mask); i++) { - for(;;) { - m = sig.mask[i]; - if(runtime_cas(&sig.mask[i], m, 0)) - break; - } - recv[i] = m; - } - } - -done:; - // goc requires that we fall off the end of functions - // that return values instead of using our own return - // statements. -} - -// Must only be called from a single goroutine at a time. -func signal_enable(s uint32) { - int32 i; - - if(!sig.inuse) { - // The first call to signal_enable is for us - // to use for initialization. It does not pass - // signal information in m. - sig.inuse = true; // enable reception of signals; cannot disable - runtime_noteclear(&sig); - return; - } - - if(~s == 0) { - // Special case: want everything. - for(i=0; (size_t)i<nelem(sig.wanted); i++) - sig.wanted[i] = ~(uint32)0; - runtime_sigenable(s); - return; - } - - if(s >= nelem(sig.wanted)*32) - return; - sig.wanted[s/32] |= 1U<<(s&31); - runtime_sigenable(s); -} |