diff options
| author | Dmitriy Vyukov <dvyukov@google.com> | 2013-07-29 22:22:34 +0400 |
|---|---|---|
| committer | Dmitriy Vyukov <dvyukov@google.com> | 2013-07-29 22:22:34 +0400 |
| commit | e84d9e1fb3a0d87abd60d31afb9cd0ddfb7d9bfa (patch) | |
| tree | 1a0213f1250994c0734456bdcd81bb1bf5e56ee4 /src/pkg/runtime/runtime.c | |
| parent | b8734748b6b151a7fd724fc41e2555e6cd34385f (diff) | |
| download | go-e84d9e1fb3a0d87abd60d31afb9cd0ddfb7d9bfa.tar.xz | |
runtime: do not split stacks in syscall status
Split stack checks (morestack) corrupt g->sched,
but g->sched must be preserved consistent for GC/traceback.
The change implements runtime.notetsleepg function,
which does entersyscall/exitsyscall and is carefully arranged
to not call any split functions in between.
R=rsc
CC=golang-dev
https://golang.org/cl/11575044
Diffstat (limited to 'src/pkg/runtime/runtime.c')
| -rw-r--r-- | src/pkg/runtime/runtime.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/src/pkg/runtime/runtime.c b/src/pkg/runtime/runtime.c index 9b5f6c8ca3..03a9daf4c2 100644 --- a/src/pkg/runtime/runtime.c +++ b/src/pkg/runtime/runtime.c @@ -220,6 +220,9 @@ runtime·check(void) if(offsetof(struct y1, y) != 1) runtime·throw("bad offsetof y1.y"); if(sizeof(struct y1) != 2) runtime·throw("bad sizeof y1"); + if(runtime·timediv(12345LL*1000000000+54321, 1000000000, &e) != 12345 || e != 54321) + runtime·throw("bad timediv"); + uint32 z; z = 1; if(!runtime·cas(&z, 1, 2)) @@ -407,3 +410,30 @@ runtime·parsedebugvars(void) p++; } } + +// Poor mans 64-bit division. +// This is a very special function, do not use it if you are not sure what you are doing. +// int64 division is lowered into _divv() call on 386, which does not fit into nosplit functions. +// Handles overflow in a time-specific manner. +#pragma textflag 7 +int32 +runtime·timediv(int64 v, int32 div, int32 *rem) +{ + int32 res, bit; + + if(v >= div*0x7fffffffLL) { + if(rem != nil) + *rem = 0; + return 0x7fffffff; + } + res = 0; + for(bit = 0x40000000; bit != 0; bit >>= 1) { + if(v >= (int64)bit*div) { + v -= (int64)bit*div; + res += bit; + } + } + if(rem != nil) + *rem = v; + return res; +} |
