From 651d0cf204da51eddec88c32c039d750ef7edbbd Mon Sep 17 00:00:00 2001 From: Dmitriy Vyukov Date: Sun, 24 Aug 2014 11:50:37 +0400 Subject: [PATCH] runtime: convert sigqueue to Go LGTM=rsc R=golang-codereviews, rsc CC=golang-codereviews, khr https://golang.org/cl/132090043 --- src/pkg/runtime/runtime.h | 1 + src/pkg/runtime/{sigqueue.goc => sigqueue.c} | 66 +++++++++++++------- src/pkg/runtime/sigqueue.go | 42 +++++++++++++ 3 files changed, 85 insertions(+), 24 deletions(-) rename src/pkg/runtime/{sigqueue.goc => sigqueue.c} (84%) create mode 100644 src/pkg/runtime/sigqueue.go diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h index 35574f4cd6..dcce369a5c 100644 --- a/src/pkg/runtime/runtime.h +++ b/src/pkg/runtime/runtime.h @@ -781,6 +781,7 @@ extern DebugVars runtime·debug; extern uintptr runtime·maxstacksize; extern byte* runtime·gcdatamask; extern byte* runtime·gcbssmask; +extern Note runtime·signote; /* * common functions and data diff --git a/src/pkg/runtime/sigqueue.goc b/src/pkg/runtime/sigqueue.c similarity index 84% rename from src/pkg/runtime/sigqueue.goc rename to src/pkg/runtime/sigqueue.c index fa0eb51a1c..e5617bde7d 100644 --- a/src/pkg/runtime/sigqueue.goc +++ b/src/pkg/runtime/sigqueue.c @@ -24,22 +24,26 @@ // unnecessary rechecks of sig.mask, but must not lead to missed signals // nor deadlocks. -package runtime #include "runtime.h" #include "defs_GOOS_GOARCH.h" #include "os_GOOS.h" #include "cgocall.h" #include "../../cmd/ld/textflag.h" -#pragma textflag NOPTR -static struct { - Note note; +typedef struct Sig Sig; +struct Sig { uint32 mask[(NSIG+31)/32]; uint32 wanted[(NSIG+31)/32]; uint32 recv[(NSIG+31)/32]; uint32 state; bool inuse; -} sig; + bool afterwait; +}; + +#pragma dataflag NOPTR +static Sig sig; + +Note runtime·signote; enum { HASWAITER = 1, @@ -72,7 +76,7 @@ runtime·sigsend(int32 s) new = HASSIGNAL; if(runtime·cas(&sig.state, old, new)) { if (old == HASWAITER) - runtime·notewakeup(&sig.note); + runtime·notewakeup(&runtime·signote); break; } } @@ -84,16 +88,23 @@ runtime·sigsend(int32 s) // Called to receive the next queued signal. // Must only be called from a single goroutine at a time. -func signal_recv() (m uint32) { +void +runtime·signal_recv_m(void) +{ uint32 i, old, new; - + + if(sig.afterwait) { + sig.afterwait = false; + goto update; + } for(;;) { // Serve from local copy if there are bits left. for(i=0; im->scalararg[0] = true; + g->m->scalararg[1] = i; + return; } } @@ -108,41 +119,43 @@ func signal_recv() (m uint32) { new = HASWAITER; if(runtime·cas(&sig.state, old, new)) { if (new == HASWAITER) { - runtime·notetsleepg(&sig.note, -1); - runtime·noteclear(&sig.note); + sig.afterwait = true; + g->m->scalararg[0] = false; + g->m->scalararg[1] = 0; + return; } break; } } // Get a new local copy. + update: for(i=0; im->scalararg[0]; if(s >= nelem(sig.wanted)*32) return; sig.wanted[s/32] |= 1U<<(s&31); @@ -150,7 +163,12 @@ func signal_enable(s uint32) { } // Must only be called from a single goroutine at a time. -func signal_disable(s uint32) { +void +runtime·signal_disable_m(void) +{ + uint32 s; + + s = g->m->scalararg[0]; if(s >= nelem(sig.wanted)*32) return; sig.wanted[s/32] &= ~(1U<<(s&31)); diff --git a/src/pkg/runtime/sigqueue.go b/src/pkg/runtime/sigqueue.go new file mode 100644 index 0000000000..5976e57352 --- /dev/null +++ b/src/pkg/runtime/sigqueue.go @@ -0,0 +1,42 @@ +// 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. + +package runtime + +func signal_recv() (m uint32) { + for { + mp := acquirem() + onM(&signal_recv_m) + ok := mp.scalararg[0] != 0 + m = uint32(mp.scalararg[1]) + releasem(mp) + if ok { + return + } + gonotetsleepg(&signote, -1) + gonoteclear(&signote) + } +} + +func signal_enable(s uint32) { + mp := acquirem() + mp.scalararg[0] = uint(s) + onM(&signal_enable_m) + releasem(mp) +} + +func signal_disable(s uint32) { + mp := acquirem() + mp.scalararg[0] = uint(s) + onM(&signal_disable_m) + releasem(mp) +} + +var ( + signal_recv_m, + signal_enable_m, + signal_disable_m mFunction +) -- 2.48.1