LEFT | RIGHT |
1 // Use of this source file is governed by a BSD-style | 1 // Use of this source file is governed by a BSD-style |
2 // license that can be found in the LICENSE file.` | 2 // license that can be found in the LICENSE file.` |
3 | 3 |
4 #include "runtime.h" | 4 #include "runtime.h" |
5 #include "defs.h" | 5 #include "defs.h" |
6 #include "os.h" | 6 #include "os.h" |
7 #include "stack.h" | 7 #include "stack.h" |
8 | 8 |
9 enum | 9 enum |
10 { | 10 { |
11 MUTEX_UNLOCKED = 0, | 11 MUTEX_UNLOCKED = 0, |
12 MUTEX_LOCKED = 1, | 12 MUTEX_LOCKED = 1, |
13 MUTEX_SLEEPING = 2, | 13 MUTEX_SLEEPING = 2, |
14 | 14 |
15 ACTIVE_SPIN = 4, | 15 ACTIVE_SPIN = 4, |
16 ACTIVE_SPIN_CNT = 30, | 16 ACTIVE_SPIN_CNT = 30, |
17 PASSIVE_SPIN = 1, | 17 PASSIVE_SPIN = 1, |
18 | 18 |
19 ESRCH = 3, | 19 ESRCH = 3, |
20 ENOTSUP = 91, | 20 ENOTSUP = 91, |
| 21 |
| 22 // From OpenBSD's sys/time.h |
| 23 CLOCK_REALTIME = 0, |
| 24 CLOCK_VIRTUAL = 1, |
| 25 CLOCK_PROF = 2, |
| 26 CLOCK_MONOTONIC = 3 |
21 }; | 27 }; |
22 | 28 |
23 extern SigTab runtime·sigtab[]; | 29 extern SigTab runtime·sigtab[]; |
24 | 30 |
25 extern int64 runtime·rfork_thread(int32 flags, void *stack, M *m, G *g, void (*f
n)(void)); | 31 extern int64 runtime·rfork_thread(int32 flags, void *stack, M *m, G *g, void (*f
n)(void)); |
26 extern int32 runtime·thrsleep(void *, void *, void*, void *); | 32 extern int32 runtime·thrsleep(void *ident, int32 clock_id, void *tsp, void *lock
); |
27 extern int32 runtime·thrwakeup(void *, int32); | 33 extern int32 runtime·thrwakeup(void *ident, int32 n); |
28 | 34 |
29 // From OpenBSD's <sys/sysctl.h> | 35 // From OpenBSD's <sys/sysctl.h> |
30 #define CTL_HW 6 | 36 #define CTL_HW 6 |
31 #define HW_NCPU 3 | 37 #define HW_NCPU 3 |
32 | 38 |
33 static int32 | 39 static int32 |
34 getncpu(void) | 40 getncpu(void) |
35 { | 41 { |
36 uint32 mib[2]; | 42 uint32 mib[2]; |
37 uint32 out; | 43 uint32 out; |
(...skipping 11 matching lines...) Expand all Loading... |
49 else | 55 else |
50 return 1; | 56 return 1; |
51 } | 57 } |
52 | 58 |
53 uintptr | 59 uintptr |
54 runtime·semacreate(void) | 60 runtime·semacreate(void) |
55 { | 61 { |
56 return 1; | 62 return 1; |
57 } | 63 } |
58 | 64 |
59 void | 65 int32 |
60 runtime·semasleep(int64 ns) | 66 runtime·semasleep(int64 ns) |
61 { | 67 { |
62 XXX ns | 68 » Timespec ts; |
63 retry: | 69 |
64 // spin-mutex lock | 70 // spin-mutex lock |
65 while(runtime·xchg(&m->waitsemalock, 1)) | 71 while(runtime·xchg(&m->waitsemalock, 1)) |
66 runtime·osyield(); | 72 runtime·osyield(); |
67 » if(m->waitsemacount == 0) { | 73 |
68 » » // the function unlocks the spinlock | 74 » for(;;) { |
69 » » runtime·thrsleep(&m->waitsemacount, 0, 0, &m->waitsemalock); | 75 » » // lock held |
70 » » goto retry; | 76 » » if(m->waitsemacount == 0) { |
71 » } | 77 » » » // sleep until semaphore != 0 or timeout. |
72 » m->waitsemacount--; | 78 » » » // thrsleep unlocks m->waitsemalock. |
| 79 » » » if(ns < 0) |
| 80 » » » » runtime·thrsleep(&m->waitsemacount, 0, nil, &m->
waitsemalock); |
| 81 » » » else { |
| 82 » » » » ts.tv_sec = ns/1000000000LL; |
| 83 » » » » ts.tv_nsec = ns%1000000000LL; |
| 84 » » » » runtime·thrsleep(&m->waitsemacount, CLOCK_REALTI
ME, &ts, &m->waitsemalock); |
| 85 » » » } |
| 86 » » » // reacquire lock |
| 87 » » » while(runtime·xchg(&m->waitsemalock, 1)) |
| 88 » » » » runtime·osyield(); |
| 89 » » } |
| 90 |
| 91 » » // lock held (again) |
| 92 » » if(m->waitsemacount != 0) { |
| 93 » » » // semaphore is available. |
| 94 » » » m->waitsemacount--; |
| 95 » » » // spin-mutex unlock |
| 96 » » » runtime·atomicstore(&m->waitsemalock, 0); |
| 97 » » » return 0; // semaphore acquired |
| 98 » » } |
| 99 |
| 100 » » // semaphore not available. |
| 101 » » // if there is a timeout, stop now. |
| 102 » » // otherwise keep trying. |
| 103 » » if(ns >= 0) |
| 104 » » » break; |
| 105 » } |
| 106 |
| 107 » // lock held but giving up |
73 // spin-mutex unlock | 108 // spin-mutex unlock |
74 runtime·atomicstore(&m->waitsemalock, 0); | 109 runtime·atomicstore(&m->waitsemalock, 0); |
| 110 return -1; |
75 } | 111 } |
76 | 112 |
77 void | 113 void |
78 runtime·semawakeup(M *mp) | 114 runtime·semawakeup(M *mp) |
79 { | 115 { |
80 uint32 ret; | 116 uint32 ret; |
81 | 117 |
82 // spin-mutex lock | 118 // spin-mutex lock |
83 while(runtime·xchg(&mp->waitsemalock, 1)) | 119 while(runtime·xchg(&mp->waitsemalock, 1)) |
84 runtime·osyield(); | 120 runtime·osyield(); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 switch(g->sigcode0) { | 195 switch(g->sigcode0) { |
160 case FPE_INTDIV: | 196 case FPE_INTDIV: |
161 runtime·panicstring("integer divide by zero"); | 197 runtime·panicstring("integer divide by zero"); |
162 case FPE_INTOVF: | 198 case FPE_INTOVF: |
163 runtime·panicstring("integer overflow"); | 199 runtime·panicstring("integer overflow"); |
164 } | 200 } |
165 runtime·panicstring("floating point error"); | 201 runtime·panicstring("floating point error"); |
166 } | 202 } |
167 runtime·panicstring(runtime·sigtab[g->sig].name); | 203 runtime·panicstring(runtime·sigtab[g->sig].name); |
168 } | 204 } |
LEFT | RIGHT |