LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 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 "type.h" | 6 #include "type.h" |
7 #include "defs.h" | 7 #include "defs.h" |
8 #include "os.h" | 8 #include "os.h" |
9 | 9 |
10 #pragma dynimport runtime·CloseHandle CloseHandle "kernel32.dll" | 10 #pragma dynimport runtime·CloseHandle CloseHandle "kernel32.dll" |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 void | 226 void |
227 runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void)) | 227 runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void)) |
228 { | 228 { |
229 void *thandle; | 229 void *thandle; |
230 | 230 |
231 USED(stk); | 231 USED(stk); |
232 USED(g); // assuming g = m->g0 | 232 USED(g); // assuming g = m->g0 |
233 USED(fn); // assuming fn = mstart | 233 USED(fn); // assuming fn = mstart |
234 | 234 |
235 thandle = runtime·stdcall(runtime·CreateThread, 6, | 235 thandle = runtime·stdcall(runtime·CreateThread, 6, |
236 » » nil, (uintptr)0, runtime·tstart_stdcall, | 236 » » nil, nil, runtime·tstart_stdcall, m, nil, nil); |
237 » » m, (uintptr)CREATE_SUSPENDED, nil); | |
238 if(thandle == nil) { | 237 if(thandle == nil) { |
239 runtime·printf("runtime: failed to create new OS thread (have %d
already; errno=%d)\n", runtime·mcount(), runtime·getlasterror()); | 238 runtime·printf("runtime: failed to create new OS thread (have %d
already; errno=%d)\n", runtime·mcount(), runtime·getlasterror()); |
240 runtime·throw("runtime.newosproc"); | 239 runtime·throw("runtime.newosproc"); |
241 } | 240 } |
242 » m->thread = thandle; | 241 » runtime·atomicstorep(&m->thread, thandle); |
243 » runtime·stdcall(runtime·ResumeThread, 1, thandle); | |
244 } | 242 } |
245 | 243 |
246 // Called to initialize a new m (including the bootstrap m). | 244 // Called to initialize a new m (including the bootstrap m). |
247 void | 245 void |
248 runtime·minit(void) | 246 runtime·minit(void) |
249 { | 247 { |
250 } | 248 } |
251 | 249 |
252 void | 250 void |
253 runtime·gettime(int64 *sec, int32 *usec) | 251 runtime·gettime(int64 *sec, int32 *usec) |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 byte rbuf[sizeof(Context)+15]; | 359 byte rbuf[sizeof(Context)+15]; |
362 Context *r; | 360 Context *r; |
363 void *tls; | 361 void *tls; |
364 G *gp; | 362 G *gp; |
365 | 363 |
366 tls = mp->tls; | 364 tls = mp->tls; |
367 if(mp == &runtime·m0) | 365 if(mp == &runtime·m0) |
368 tls = runtime·tls0; | 366 tls = runtime·tls0; |
369 gp = *(G**)tls; | 367 gp = *(G**)tls; |
370 | 368 |
371 » if(gp != nil) { | 369 » if(gp != nil && gp != mp->g0 && gp->status != Gsyscall) { |
372 // align Context to 16 bytes | 370 // align Context to 16 bytes |
373 r = (Context*)((uintptr)(&rbuf[15]) & ~15); | 371 r = (Context*)((uintptr)(&rbuf[15]) & ~15); |
374 r->ContextFlags = CONTEXT_CONTROL; | 372 r->ContextFlags = CONTEXT_CONTROL; |
375 runtime·stdcall(runtime·GetThreadContext, 2, mp->thread, r); | 373 runtime·stdcall(runtime·GetThreadContext, 2, mp->thread, r); |
376 runtime·dosigprof(r, gp); | 374 runtime·dosigprof(r, gp); |
377 } | 375 } |
378 } | 376 } |
379 | 377 |
380 void | 378 void |
381 runtime·profileloop1(void) | 379 runtime·profileloop1(void) |
382 { | 380 { |
383 M *mp, *allm; | 381 M *mp, *allm; |
| 382 void *thread; |
384 | 383 |
385 runtime·stdcall(runtime·SetThreadPriority, 2, | 384 runtime·stdcall(runtime·SetThreadPriority, 2, |
386 (uintptr)-2, (uintptr)THREAD_PRIORITY_HIGHEST); | 385 (uintptr)-2, (uintptr)THREAD_PRIORITY_HIGHEST); |
387 | 386 |
388 for(;;) { | 387 for(;;) { |
389 runtime·stdcall(runtime·WaitForSingleObject, 2, profiletimer, (u
intptr)-1); | 388 runtime·stdcall(runtime·WaitForSingleObject, 2, profiletimer, (u
intptr)-1); |
390 allm = runtime·atomicloadp(&runtime·allm); | 389 allm = runtime·atomicloadp(&runtime·allm); |
391 for(mp = allm; mp != nil; mp = mp->alllink) { | 390 for(mp = allm; mp != nil; mp = mp->alllink) { |
392 » » » runtime·stdcall(runtime·SuspendThread, 1, mp->thread); | 391 » » » thread = runtime·atomicloadp(&mp->thread); |
| 392 » » » if(thread == nil) |
| 393 » » » » continue; |
| 394 » » » runtime·stdcall(runtime·SuspendThread, 1, thread); |
393 if(mp->profilehz != 0) | 395 if(mp->profilehz != 0) |
394 profilem(mp); | 396 profilem(mp); |
395 » » » runtime·stdcall(runtime·ResumeThread, 1, mp->thread); | 397 » » » runtime·stdcall(runtime·ResumeThread, 1, thread); |
396 } | 398 } |
397 } | 399 } |
398 } | 400 } |
399 | 401 |
400 void | 402 void |
401 runtime·resetcpuprofiler(int32 hz) | 403 runtime·resetcpuprofiler(int32 hz) |
402 { | 404 { |
403 static Lock lock; | 405 static Lock lock; |
404 void *timer, *thread; | 406 void *timer, *thread; |
405 int32 ms; | 407 int32 ms; |
(...skipping 20 matching lines...) Expand all Loading... |
426 runtime·stdcall(runtime·SetWaitableTimer, 6, | 428 runtime·stdcall(runtime·SetWaitableTimer, 6, |
427 profiletimer, &due, (uintptr)ms, nil, nil, nil); | 429 profiletimer, &due, (uintptr)ms, nil, nil, nil); |
428 runtime·atomicstore((uint32*)&m->profilehz, hz); | 430 runtime·atomicstore((uint32*)&m->profilehz, hz); |
429 } | 431 } |
430 | 432 |
431 void | 433 void |
432 os·sigpipe(void) | 434 os·sigpipe(void) |
433 { | 435 { |
434 runtime·throw("too many writes on closed pipe"); | 436 runtime·throw("too many writes on closed pipe"); |
435 } | 437 } |
LEFT | RIGHT |