1
// Copyright 2009 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
7
#include "defs_GOOS_GOARCH.h"
10
#pragma dynimport runtime·CloseHandle CloseHandle "kernel32.dll"
11
#pragma dynimport runtime·CreateEvent CreateEventA "kernel32.dll"
12
#pragma dynimport runtime·CreateThread CreateThread "kernel32.dll"
13
#pragma dynimport runtime·CreateWaitableTimer CreateWaitableTimerA "kernel32.dll"
14
#pragma dynimport runtime·DuplicateHandle DuplicateHandle "kernel32.dll"
15
#pragma dynimport runtime·ExitProcess ExitProcess "kernel32.dll"
16
#pragma dynimport runtime·FreeEnvironmentStringsW FreeEnvironmentStringsW "kernel32.dll"
17
#pragma dynimport runtime·GetEnvironmentStringsW GetEnvironmentStringsW "kernel32.dll"
18
#pragma dynimport runtime·GetProcAddress GetProcAddress "kernel32.dll"
19
#pragma dynimport runtime·GetStdHandle GetStdHandle "kernel32.dll"
20
#pragma dynimport runtime·GetSystemInfo GetSystemInfo "kernel32.dll"
21
#pragma dynimport runtime·GetSystemTimeAsFileTime GetSystemTimeAsFileTime "kernel32.dll"
22
#pragma dynimport runtime·GetThreadContext GetThreadContext "kernel32.dll"
23
#pragma dynimport runtime·LoadLibrary LoadLibraryW "kernel32.dll"
24
#pragma dynimport runtime·ResumeThread ResumeThread "kernel32.dll"
25
#pragma dynimport runtime·SetConsoleCtrlHandler SetConsoleCtrlHandler "kernel32.dll"
26
#pragma dynimport runtime·SetEvent SetEvent "kernel32.dll"
27
#pragma dynimport runtime·SetThreadPriority SetThreadPriority "kernel32.dll"
28
#pragma dynimport runtime·SetWaitableTimer SetWaitableTimer "kernel32.dll"
29
#pragma dynimport runtime·Sleep Sleep "kernel32.dll"
30
#pragma dynimport runtime·SuspendThread SuspendThread "kernel32.dll"
31
#pragma dynimport runtime·timeBeginPeriod timeBeginPeriod "winmm.dll"
32
#pragma dynimport runtime·WaitForSingleObject WaitForSingleObject "kernel32.dll"
33
#pragma dynimport runtime·WriteFile WriteFile "kernel32.dll"
35
extern void *runtime·CloseHandle;
36
extern void *runtime·CreateEvent;
37
extern void *runtime·CreateThread;
38
extern void *runtime·CreateWaitableTimer;
39
extern void *runtime·DuplicateHandle;
40
extern void *runtime·ExitProcess;
41
extern void *runtime·FreeEnvironmentStringsW;
42
extern void *runtime·GetEnvironmentStringsW;
43
extern void *runtime·GetProcAddress;
44
extern void *runtime·GetStdHandle;
45
extern void *runtime·GetSystemInfo;
46
extern void *runtime·GetSystemTimeAsFileTime;
47
extern void *runtime·GetThreadContext;
48
extern void *runtime·LoadLibrary;
49
extern void *runtime·ResumeThread;
50
extern void *runtime·SetConsoleCtrlHandler;
51
extern void *runtime·SetEvent;
52
extern void *runtime·SetThreadPriority;
53
extern void *runtime·SetWaitableTimer;
54
extern void *runtime·Sleep;
55
extern void *runtime·SuspendThread;
56
extern void *runtime·timeBeginPeriod;
57
extern void *runtime·WaitForSingleObject;
58
extern void *runtime·WriteFile;
65
runtime·stdcall(runtime·GetSystemInfo, 1, &info);
66
return info.dwNumberOfProcessors;
72
// -1 = current process, -2 = current thread
73
runtime·stdcall(runtime·DuplicateHandle, 7,
74
(uintptr)-1, (uintptr)-2, (uintptr)-1, &m->thread,
75
(uintptr)0, (uintptr)0, (uintptr)DUPLICATE_SAME_ACCESS);
76
runtime·stdcall(runtime·SetConsoleCtrlHandler, 2, runtime·ctrlhandler, (uintptr)1);
77
runtime·stdcall(runtime·timeBeginPeriod, 1, (uintptr)1);
78
runtime·ncpu = getproccount();
84
extern Slice syscall·envs;
91
env = runtime·stdcall(runtime·GetEnvironmentStringsW, 0);
95
p += runtime·findnullw(p)+1;
97
s = runtime·malloc(n*sizeof s[0]);
101
s[i] = runtime·gostringw(p);
102
p += runtime·findnullw(p)+1;
104
syscall·envs.array = (byte*)s;
105
syscall·envs.len = n;
106
syscall·envs.cap = n;
108
runtime·stdcall(runtime·FreeEnvironmentStringsW, 1, env);
112
runtime·exit(int32 code)
114
runtime·stdcall(runtime·ExitProcess, 1, (uintptr)code);
118
runtime·write(int32 fd, void *buf, int32 n)
126
handle = runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-11);
129
handle = runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-12);
134
runtime·stdcall(runtime·WriteFile, 5, handle, buf, (uintptr)n, &written, (uintptr)0);
139
runtime·osyield(void)
141
runtime·stdcall(runtime·Sleep, 1, (uintptr)0);
145
runtime·usleep(uint32 us)
150
runtime·stdcall(runtime·Sleep, 1, (uintptr)us);
153
#define INFINITE ((uintptr)0xFFFFFFFF)
156
runtime·semasleep(int64 ns)
162
else if(ns/1000000 > 0x7fffffffLL)
169
if(runtime·stdcall(runtime·WaitForSingleObject, 2, m->waitsema, ms) != 0)
170
return -1; // timeout
175
runtime·semawakeup(M *mp)
177
runtime·stdcall(runtime·SetEvent, 1, mp->waitsema);
181
runtime·semacreate(void)
183
return (uintptr)runtime·stdcall(runtime·CreateEvent, 4, (uintptr)0, (uintptr)0, (uintptr)0, (uintptr)0);
186
#define STACK_SIZE_PARAM_IS_A_RESERVATION ((uintptr)0x00010000)
189
runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
194
USED(g); // assuming g = m->g0
195
USED(fn); // assuming fn = mstart
197
thandle = runtime·stdcall(runtime·CreateThread, 6,
198
nil, (uintptr)0x20000, runtime·tstart_stdcall, m,
199
STACK_SIZE_PARAM_IS_A_RESERVATION, nil);
201
runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), runtime·getlasterror());
202
runtime·throw("runtime.newosproc");
204
runtime·atomicstorep(&m->thread, thandle);
207
// Called to initialize a new m (including the bootstrap m).
214
runtime·nanotime(void)
218
runtime·stdcall(runtime·GetSystemTimeAsFileTime, 1, &filetime);
220
// Filetime is 100s of nanoseconds since January 1, 1601.
221
// Convert to nanoseconds since January 1, 1970.
222
return (filetime - 116444736000000000LL) * 100LL;
226
time·now(int64 sec, int32 usec)
230
ns = runtime·nanotime();
231
sec = ns / 1000000000LL;
232
usec = ns - sec * 1000000000LL;
237
// Calling stdcall on os stack.
240
runtime·stdcall(void *fn, int32 count, ...)
246
c.args = (uintptr*)&count + 1;
247
runtime·asmcgocall(runtime·asmstdcall, &c);
252
runtime·issigpanic(uint32 code)
255
case EXCEPTION_ACCESS_VIOLATION:
256
case EXCEPTION_INT_DIVIDE_BY_ZERO:
257
case EXCEPTION_INT_OVERFLOW:
258
case EXCEPTION_FLT_DENORMAL_OPERAND:
259
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
260
case EXCEPTION_FLT_INEXACT_RESULT:
261
case EXCEPTION_FLT_OVERFLOW:
262
case EXCEPTION_FLT_UNDERFLOW:
269
runtime·sigpanic(void)
272
case EXCEPTION_ACCESS_VIOLATION:
273
if(g->sigcode1 < 0x1000) {
275
runtime·panicstring("call of nil func value");
276
runtime·panicstring("invalid memory address or nil pointer dereference");
278
runtime·printf("unexpected fault address %p\n", g->sigcode1);
279
runtime·throw("fault");
280
case EXCEPTION_INT_DIVIDE_BY_ZERO:
281
runtime·panicstring("integer divide by zero");
282
case EXCEPTION_INT_OVERFLOW:
283
runtime·panicstring("integer overflow");
284
case EXCEPTION_FLT_DENORMAL_OPERAND:
285
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
286
case EXCEPTION_FLT_INEXACT_RESULT:
287
case EXCEPTION_FLT_OVERFLOW:
288
case EXCEPTION_FLT_UNDERFLOW:
289
runtime·panicstring("floating point error");
291
runtime·throw("fault");
294
extern void *runtime·sigtramp;
297
runtime·initsig(void)
299
// following line keeps sigtramp alive at link stage
300
// if there's a better way please write it here
301
void *p = runtime·sigtramp;
306
runtime·ctrlhandler1(uint32 type)
312
case CTRL_BREAK_EVENT:
319
if(runtime·sigsend(s))
321
runtime·exit(2); // SIGINT, SIGTERM, etc
325
extern void runtime·dosigprof(Context *r, G *gp);
326
extern void runtime·profileloop(void);
327
static void *profiletimer;
333
extern uint32 runtime·tls0[];
334
byte rbuf[sizeof(Context)+15];
340
if(mp == &runtime·m0)
344
if(gp != nil && gp != mp->g0 && gp->status != Gsyscall) {
345
// align Context to 16 bytes
346
r = (Context*)((uintptr)(&rbuf[15]) & ~15);
347
r->ContextFlags = CONTEXT_CONTROL;
348
runtime·stdcall(runtime·GetThreadContext, 2, mp->thread, r);
349
runtime·dosigprof(r, gp);
354
runtime·profileloop1(void)
359
runtime·stdcall(runtime·SetThreadPriority, 2,
360
(uintptr)-2, (uintptr)THREAD_PRIORITY_HIGHEST);
363
runtime·stdcall(runtime·WaitForSingleObject, 2, profiletimer, (uintptr)-1);
364
allm = runtime·atomicloadp(&runtime·allm);
365
for(mp = allm; mp != nil; mp = mp->alllink) {
366
thread = runtime·atomicloadp(&mp->thread);
369
runtime·stdcall(runtime·SuspendThread, 1, thread);
370
if(mp->profilehz != 0)
372
runtime·stdcall(runtime·ResumeThread, 1, thread);
378
runtime·resetcpuprofiler(int32 hz)
381
void *timer, *thread;
386
if(profiletimer == nil) {
387
timer = runtime·stdcall(runtime·CreateWaitableTimer, 3, nil, nil, nil);
388
runtime·atomicstorep(&profiletimer, timer);
389
thread = runtime·stdcall(runtime·CreateThread, 6,
390
nil, nil, runtime·profileloop, nil, nil, nil);
391
runtime·stdcall(runtime·CloseHandle, 1, thread);
393
runtime·unlock(&lock);
403
runtime·stdcall(runtime·SetWaitableTimer, 6,
404
profiletimer, &due, (uintptr)ms, nil, nil, nil);
405
runtime·atomicstore((uint32*)&m->profilehz, hz);
411
runtime·throw("too many writes on closed pipe");
415
runtime·memlimit(void)
421
runtime·setprof(bool on)
426
int8 runtime·badcallbackmsg[] = "runtime: cgo callback on thread not created by Go.\n";
427
int32 runtime·badcallbacklen = sizeof runtime·badcallbackmsg - 1;
429
int8 runtime·badsignalmsg[] = "runtime: signal received on thread not created by Go.\n";
430
int32 runtime·badsignallen = sizeof runtime·badsignalmsg - 1;