Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1905)

Delta Between Two Patch Sets: src/pkg/runtime/plan9/thread.c

Issue 5327063: code review 5327063: runtime: add nanotime for Plan 9 (Closed)
Left Patch Set: diff -r e6a7e56f806b https://code.google.com/p/go/ Created 13 years, 5 months ago
Right Patch Set: diff -r 33a9fcc0f1ed https://code.google.com/p/go/ Created 13 years, 4 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/pkg/runtime/plan9/os.h ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // Copyright 2010 The Go Authors. All rights reserved. 1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 #include "runtime.h" 5 #include "runtime.h"
6 #include "os.h" 6 #include "os.h"
7 #include "arch.h" 7 #include "arch.h"
8 8
9 int8 *goos = "plan9"; 9 int8 *goos = "plan9";
10 10
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 runtime·usleep(uint32 µs) 62 runtime·usleep(uint32 µs)
63 { 63 {
64 uint32 ms; 64 uint32 ms;
65 65
66 ms = µs/1000; 66 ms = µs/1000;
67 if(ms == 0) 67 if(ms == 0)
68 ms = 1; 68 ms = 1;
69 runtime·sleep(ms); 69 runtime·sleep(ms);
70 } 70 }
71 71
72 void 72 int64
73 runtime·gettime(int64 *sec, int32 *usec) 73 runtime·nanotime(void)
74 { 74 {
75 » static int32 fd = -1;
75 byte b[8]; 76 byte b[8];
76 » int32 fd, n; 77 » uint32 hi, lo;
77 » int64 t; 78
78 79 » // As long as all goroutines share the same file
79 » fd = runtime·open((byte*)"/dev/bintime", OREAD|OCEXEC); 80 » // descriptor table we can get away with using
80 » if(fd < 0) 81 » // just a static fd. Without a lock the file can
81 » » return; 82 » // be opened twice but that's okay.
82 » n = runtime·pread(fd, b, sizeof b, 0); 83 » //
83 » runtime·close(fd); 84 » // Using /dev/bintime gives us a latency on the
84 » if(n != sizeof b) 85 » // order of ten microseconds between two calls.
85 » » return; 86 » //
86 » t = ((int64)b[0])<<56 | 87 » // The naïve implementation (without the cached
87 » » ((int64)b[1])<<48 | 88 » // file descriptor) is roughly four times slower
88 » » ((int64)b[2])<<40 | 89 » // in 9vx on a 2.16 GHz Intel Core 2 Duo.
89 » » ((int64)b[3])<<32 | 90 »·······
90 » » ((int64)b[4])<<24 | 91 » if(fd < 0 && (fd = runtime·open((byte*)"/dev/bintime", OREAD|OCEXEC)) < 0)
91 » » ((int64)b[5])<<16 | 92 » » return 0;
92 » » ((int64)b[6])<<8 | 93 » if(runtime·pread(fd, b, sizeof b, 0) != sizeof b)
93 » » ((int64)b[7]); 94 » » return 0;
94 » *sec = t/1000000000; 95 » hi = b[0]<<24 | b[1]<<16 | b[2]<<8 | b[3];
95 » *usec = t%1000000000 / 1000; 96 » lo = b[4]<<24 | b[5]<<16 | b[6]<<8 | b[7];
96 » return; 97 » return (int64)hi<<32 | (int64)lo;
97 } 98 }
98 99
99 extern Tos *_tos; 100 extern Tos *_tos;
100 void 101 void
101 runtime·exit(int32) 102 runtime·exit(int32)
102 { 103 {
103 int32 fd; 104 int32 fd;
104 uint8 buf[128]; 105 uint8 buf[128];
105 uint8 tmp[16]; 106 uint8 tmp[16];
106 uint8 *p, *q; 107 uint8 *p, *q;
107 int32 pid; 108 int32 pid;
108 » 109
109 runtime·memclr(buf, sizeof buf); 110 runtime·memclr(buf, sizeof buf);
110 runtime·memclr(tmp, sizeof tmp); 111 runtime·memclr(tmp, sizeof tmp);
111 pid = _tos->pid; 112 pid = _tos->pid;
112 113
113 /* build path string /proc/pid/notepg */ 114 /* build path string /proc/pid/notepg */
114 for(q=tmp; pid > 0;) { 115 for(q=tmp; pid > 0;) {
115 *q++ = '0' + (pid%10); 116 *q++ = '0' + (pid%10);
116 pid = pid/10; 117 pid = pid/10;
117 } 118 }
118 p = buf; 119 p = buf;
119 runtime·memmove((void*)p, (void*)"/proc/", 6); 120 runtime·memmove((void*)p, (void*)"/proc/", 6);
120 p += 6; 121 p += 6;
121 for(q--; q >= tmp;) 122 for(q--; q >= tmp;)
122 *p++ = *q--; 123 *p++ = *q--;
123 runtime·memmove((void*)p, (void*)"/notepg", 7); 124 runtime·memmove((void*)p, (void*)"/notepg", 7);
124 » 125
125 /* post interrupt note */ 126 /* post interrupt note */
126 fd = runtime·open(buf, OWRITE); 127 fd = runtime·open(buf, OWRITE);
127 runtime·write(fd, "interrupt", 9); 128 runtime·write(fd, "interrupt", 9);
128 runtime·exits(nil); 129 runtime·exits(nil);
129 } 130 }
130 131
131 void 132 void
132 runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void)) 133 runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
133 { 134 {
134 m->tls[0] = m->id; // so 386 asm can find it 135 m->tls[0] = m->id; // so 386 asm can find it
135 if(0){ 136 if(0){
136 runtime·printf("newosproc stk=%p m=%p g=%p fn=%p rfork=%p id=%d/ %d ostk=%p\n", 137 runtime·printf("newosproc stk=%p m=%p g=%p fn=%p rfork=%p id=%d/ %d ostk=%p\n",
137 stk, m, g, fn, runtime·rfork, m->id, m->tls[0], &m); 138 stk, m, g, fn, runtime·rfork, m->id, m->tls[0], &m);
138 » }········ 139 » }
139 »······· 140
140 if(runtime·rfork(RFPROC|RFMEM|RFNOWAIT, stk, m, g, fn) < 0) 141 if(runtime·rfork(RFPROC|RFMEM|RFNOWAIT, stk, m, g, fn) < 0)
141 runtime·throw("newosproc: rfork failed"); 142 runtime·throw("newosproc: rfork failed");
142 } 143 }
143 144
144 uintptr 145 uintptr
145 runtime·semacreate(void) 146 runtime·semacreate(void)
146 { 147 {
147 return 1; 148 return 1;
148 } 149 }
149 150
150 void 151 int32
151 runtime·semasleep(void) 152 runtime·semasleep(int64 ns)
152 { 153 {
154 » int32 ret;
155 » int32 ms;
156
157 » if(ns >= 0) {
158 » » // TODO: Plan 9 needs a new system call, tsemacquire.
159 » » // The kernel implementation is the same as semacquire
160 » » // except with a tsleep and check for timeout.
161 » » // It would be great if the implementation returned the
162 » » // value that was added to the semaphore, so that on
163 » » // timeout the return value would be 0, on success 1.
164 » » // Then the error string does not have to be parsed
165 » » // to detect timeout.
166 » » //
167 » » // If a negative time indicates no timeout, then
168 » » // semacquire can be implemented (in the kernel)
169 » » // as tsemacquire(p, v, -1).
170 » » runtime·throw("semasleep: timed sleep not implemented on Plan 9" );
171
172 » » /*
173 » » if(ns < 0)
174 » » » ms = -1;
175 » » else if(ns/1000 > 0x7fffffffll)
176 » » » ms = 0x7fffffff;
177 » » else
178 » » » ms = ns/1000;
179 » » ret = runtime·plan9_tsemacquire(&m->waitsemacount, 1, ms);
180 » » if(ret == 1)
181 » » » return 0; // success
182 » » return -1; // timeout or interrupted
183 » » */
184 » }
185
153 while(runtime·plan9_semacquire(&m->waitsemacount, 1) < 0) { 186 while(runtime·plan9_semacquire(&m->waitsemacount, 1) < 0) {
154 /* interrupted; try again */ 187 /* interrupted; try again */
155 } 188 }
189 return 0; // success
156 } 190 }
157 191
158 void 192 void
159 runtime·semawakeup(M *mp) 193 runtime·semawakeup(M *mp)
160 { 194 {
161 runtime·plan9_semrelease(&mp->waitsemacount, 1); 195 runtime·plan9_semrelease(&mp->waitsemacount, 1);
162 } 196 }
163 197
164 void 198 void
165 os·sigpipe(void) 199 os·sigpipe(void)
(...skipping 16 matching lines...) Expand all
182 runtime·read(int32 fd, void *buf, int32 nbytes) 216 runtime·read(int32 fd, void *buf, int32 nbytes)
183 { 217 {
184 return runtime·pread(fd, buf, nbytes, -1LL); 218 return runtime·pread(fd, buf, nbytes, -1LL);
185 } 219 }
186 220
187 int32 221 int32
188 runtime·write(int32 fd, void *buf, int32 nbytes) 222 runtime·write(int32 fd, void *buf, int32 nbytes)
189 { 223 {
190 return runtime·pwrite(fd, buf, nbytes, -1LL); 224 return runtime·pwrite(fd, buf, nbytes, -1LL);
191 } 225 }
192
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b