summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/os_netbsd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/os_netbsd.c')
-rw-r--r--src/pkg/runtime/os_netbsd.c70
1 files changed, 63 insertions, 7 deletions
diff --git a/src/pkg/runtime/os_netbsd.c b/src/pkg/runtime/os_netbsd.c
index 29ea0cb42..cee96ebed 100644
--- a/src/pkg/runtime/os_netbsd.c
+++ b/src/pkg/runtime/os_netbsd.c
@@ -57,18 +57,23 @@ getncpu(void)
return 1;
}
+#pragma textflag NOSPLIT
uintptr
runtime·semacreate(void)
{
return 1;
}
-#pragma textflag NOSPLIT
-int32
-runtime·semasleep(int64 ns)
+static void
+semasleep(void)
{
+ int64 ns;
Timespec ts;
+ ns = (int64)(uint32)g->m->scalararg[0] | (int64)(uint32)g->m->scalararg[1]<<32;
+ g->m->scalararg[0] = 0;
+ g->m->scalararg[1] = 0;
+
// spin-mutex lock
while(runtime·xchg(&g->m->waitsemalock, 1))
runtime·osyield();
@@ -115,7 +120,8 @@ runtime·semasleep(int64 ns)
g->m->waitsemacount--;
// spin-mutex unlock
runtime·atomicstore(&g->m->waitsemalock, 0);
- return 0; // semaphore acquired
+ g->m->scalararg[0] = 0; // semaphore acquired
+ return;
}
// semaphore not available.
@@ -128,13 +134,36 @@ runtime·semasleep(int64 ns)
// lock held but giving up
// spin-mutex unlock
runtime·atomicstore(&g->m->waitsemalock, 0);
- return -1;
+ g->m->scalararg[0] = -1;
+ return;
+}
+
+#pragma textflag NOSPLIT
+int32
+runtime·semasleep(int64 ns)
+{
+ int32 r;
+ void (*fn)(void);
+
+ g->m->scalararg[0] = (uint32)ns;
+ g->m->scalararg[1] = (uint32)(ns>>32);
+ fn = semasleep;
+ runtime·onM(&fn);
+ r = g->m->scalararg[0];
+ g->m->scalararg[0] = 0;
+ return r;
}
+static void badsemawakeup(void);
+
+#pragma textflag NOSPLIT
void
runtime·semawakeup(M *mp)
{
uint32 ret;
+ void (*fn)(void);
+ void *oldptr;
+ uintptr oldscalar;
// spin-mutex lock
while(runtime·xchg(&mp->waitsemalock, 1))
@@ -143,12 +172,39 @@ runtime·semawakeup(M *mp)
// TODO(jsing) - potential deadlock, see semasleep() for details.
// Confirm that LWP is parked before unparking...
ret = runtime·lwp_unpark(mp->procid, &mp->waitsemacount);
- if(ret != 0 && ret != ESRCH)
- runtime·printf("thrwakeup addr=%p sem=%d ret=%d\n", &mp->waitsemacount, mp->waitsemacount, ret);
+ if(ret != 0 && ret != ESRCH) {
+ // semawakeup can be called on signal stack.
+ // Save old ptrarg/scalararg so we can restore them.
+ oldptr = g->m->ptrarg[0];
+ oldscalar = g->m->scalararg[0];
+ g->m->ptrarg[0] = mp;
+ g->m->scalararg[0] = ret;
+ fn = badsemawakeup;
+ if(g == g->m->gsignal)
+ fn();
+ else
+ runtime·onM(&fn);
+ g->m->ptrarg[0] = oldptr;
+ g->m->scalararg[0] = oldscalar;
+ }
// spin-mutex unlock
runtime·atomicstore(&mp->waitsemalock, 0);
}
+static void
+badsemawakeup(void)
+{
+ M *mp;
+ int32 ret;
+
+ mp = g->m->ptrarg[0];
+ g->m->ptrarg[0] = nil;
+ ret = g->m->scalararg[0];
+ g->m->scalararg[0] = 0;
+
+ runtime·printf("thrwakeup addr=%p sem=%d ret=%d\n", &mp->waitsemacount, mp->waitsemacount, ret);
+}
+
void
runtime·newosproc(M *mp, void *stk)
{