aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/runtime.c
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2008-08-04 16:43:49 -0700
committerRuss Cox <rsc@golang.org>2008-08-04 16:43:49 -0700
commitd28acc42ec0f8dff9471e4663cfe55aa5da86656 (patch)
tree9bbd3f46848f10a65f701fb12cbddadf5e59b114 /src/runtime/runtime.c
parentf439299035bbdb4ac7c1c684214b7bf8b4347474 (diff)
downloadgo-d28acc42ec0f8dff9471e4663cfe55aa5da86656.tar.xz
first cut at multithreading. works on Linux.
* kick off new os procs (machs) as needed * add sys·sleep for testing * add Lock, Rendez * properly lock mal, sys·newproc, scheduler * linux syscall arg #4 is in R10, not CX * chans are not multithread-safe yet * multithreading disabled by default; set $gomaxprocs=2 (or 1000) to turn it on This should build on OS X but may not. Rob and I will fix soon after submitting. TBR=r OCL=13784 CL=13842
Diffstat (limited to 'src/runtime/runtime.c')
-rw-r--r--src/runtime/runtime.c118
1 files changed, 93 insertions, 25 deletions
diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c
index b53f857cb0..75d23d50d8 100644
--- a/src/runtime/runtime.c
+++ b/src/runtime/runtime.c
@@ -4,7 +4,6 @@
#include "runtime.h"
-G g0; // idle goroutine
int32 debug = 0;
void
@@ -24,10 +23,6 @@ sys·panicl(int32 lno)
sys·exit(2);
}
-static uint8* hunk;
-static uint32 nhunk;
-static uint64 nmmap;
-static uint64 nmal;
enum
{
NHUNK = 20<<20,
@@ -76,42 +71,51 @@ rnd(uint32 n, uint32 m)
return n;
}
-static byte*
+static void*
brk(uint32 n)
{
- byte* v;
+ byte *v;
v = sys·mmap(nil, n, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0);
- sys·memclr(v, n);
- nmmap += n;
+ m->mem.nmmap += n;
return v;
}
+
void*
mal(uint32 n)
{
byte* v;
+ Mem *mem;
// round to keep everything 64-bit aligned
n = rnd(n, 8);
- nmal += n;
-
- // do we have enough in contiguous hunk
- if(n > nhunk) {
- // if it is big allocate it separately
- if(n > NHUNK)
- return brk(n);
-
- // allocate a new contiguous hunk
- hunk = brk(NHUNK);
- nhunk = NHUNK;
+ // be careful. calling any function might invoke
+ // mal to allocate more stack.
+ if(n > NHUNK) {
+ // this call is okay - calling mal recursively
+ // won't change anything we depend on.
+ v = brk(n);
+ } else {
+ // allocate a new hunk if this one is too small
+ if(n > m->mem.nhunk) {
+ // better not to call brk here - it might grow the stack,
+ // causing a call to mal and the allocation of a
+ // new hunk behind our backs. then we'd toss away
+ // almost all of that new hunk and replace it.
+ // that'd just be a memory leak - the code would still run.
+ m->mem.hunk =
+ sys·mmap(nil, NHUNK, PROT_READ|PROT_WRITE,
+ MAP_ANON|MAP_PRIVATE, 0, 0);
+ m->mem.nhunk = NHUNK;
+ m->mem.nmmap += NHUNK;
+ }
+ v = m->mem.hunk;
+ m->mem.hunk += n;
+ m->mem.nhunk -= n;
}
-
- // allocate from the contiguous hunk
- v = hunk;
- hunk += n;
- nhunk -= n;
+ m->mem.nmal += n;
return v;
}
@@ -491,6 +495,44 @@ args(int32 c, uint8 **v)
;
}
+int32
+getenvc(void)
+{
+ return envc;
+}
+
+byte*
+getenv(int8 *s)
+{
+ int32 i, j, len;
+ byte *v, *bs;
+
+ bs = (byte*)s;
+ len = findnull(s);
+ for(i=0; i<envc; i++){
+ v = envv[i];
+ for(j=0; j<len; j++)
+ if(bs[j] != v[j])
+ goto nomatch;
+ if(v[len] != '=')
+ goto nomatch;
+ return v+len+1;
+ nomatch:;
+ }
+ return nil;
+}
+
+int32
+atoi(byte *p)
+{
+ int32 n;
+
+ n = 0;
+ while('0' <= *p && *p <= '9')
+ n = n*10 + *p++ - '0';
+ return n;
+}
+
//func argc() int32; // return number of arguments
void
sys·argc(int32 v)
@@ -579,9 +621,35 @@ check(void)
if(sizeof(k) != 8) throw("bad k");
if(sizeof(l) != 8) throw("bad l");
// prints(1"check ok\n");
+
+ uint32 z;
+ z = 1;
+ if(!cas(&z, 1, 2))
+ throw("cas1");
+ if(z != 2)
+ throw("cas2");
+
+ z = 4;
+ if(cas(&z, 5, 6))
+ throw("cas3");
+ if(z != 4)
+ throw("cas4");
+
initsig();
}
+uint32
+xadd(uint32 *val, uint32 delta)
+{
+ uint32 v;
+
+ for(;;){
+ v = *val;
+ if(cas(val, v, v+delta))
+ return v+delta;
+ }
+}
+
/*
* map and chan helpers for
* dealing with unknown types