// 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 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.note);
					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_notetsleepg(&sig.note, -1);
					runtime_noteclear(&sig.note);
				}
				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) {
	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.note);
		return;
	}
	
	if(s >= nelem(sig.wanted)*32)
		return;
	sig.wanted[s/32] |= 1U<<(s&31);
	runtime_sigenable(s);
}

// Must only be called from a single goroutine at a time.
func signal_disable(s uint32) {
	if(s >= nelem(sig.wanted)*32)
		return;
	sig.wanted[s/32] &= ~(1U<<(s&31));
	runtime_sigdisable(s);
}

// Must only be called from a single goroutine at a time.
func signal_ignore(s uint32) {
	if (s >= nelem(sig.wanted)*32)
		return;
	sig.wanted[s/32] &= ~(1U<<(s&31));
	runtime_sigignore(s);
}

// This runs on a foreign stack, without an m or a g.  No stack split.
void
runtime_badsignal(int sig)
{
	__go_sigsend(sig);
}
