2010-01-06 18:58:55 -07:00
|
|
|
// Copyright 2009 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
#include "runtime.h"
|
2011-02-01 09:49:24 -07:00
|
|
|
#include "type.h"
|
2011-12-16 13:33:58 -07:00
|
|
|
#include "defs_GOOS_GOARCH.h"
|
|
|
|
#include "os_GOOS.h"
|
2010-01-06 18:58:55 -07:00
|
|
|
|
2010-12-07 13:28:33 -07:00
|
|
|
#pragma dynimport runtime·CloseHandle CloseHandle "kernel32.dll"
|
2011-02-01 09:49:24 -07:00
|
|
|
#pragma dynimport runtime·CreateEvent CreateEventA "kernel32.dll"
|
|
|
|
#pragma dynimport runtime·CreateThread CreateThread "kernel32.dll"
|
2011-09-17 01:57:59 -06:00
|
|
|
#pragma dynimport runtime·CreateWaitableTimer CreateWaitableTimerA "kernel32.dll"
|
|
|
|
#pragma dynimport runtime·DuplicateHandle DuplicateHandle "kernel32.dll"
|
2010-12-07 13:28:33 -07:00
|
|
|
#pragma dynimport runtime·ExitProcess ExitProcess "kernel32.dll"
|
2011-02-01 09:49:24 -07:00
|
|
|
#pragma dynimport runtime·FreeEnvironmentStringsW FreeEnvironmentStringsW "kernel32.dll"
|
|
|
|
#pragma dynimport runtime·GetEnvironmentStringsW GetEnvironmentStringsW "kernel32.dll"
|
|
|
|
#pragma dynimport runtime·GetProcAddress GetProcAddress "kernel32.dll"
|
2010-12-07 13:28:33 -07:00
|
|
|
#pragma dynimport runtime·GetStdHandle GetStdHandle "kernel32.dll"
|
2011-09-30 12:33:13 -06:00
|
|
|
#pragma dynimport runtime·GetSystemInfo GetSystemInfo "kernel32.dll"
|
2011-11-03 15:35:28 -06:00
|
|
|
#pragma dynimport runtime·GetSystemTimeAsFileTime GetSystemTimeAsFileTime "kernel32.dll"
|
2011-09-17 01:57:59 -06:00
|
|
|
#pragma dynimport runtime·GetThreadContext GetThreadContext "kernel32.dll"
|
2011-10-15 00:29:25 -06:00
|
|
|
#pragma dynimport runtime·LoadLibrary LoadLibraryW "kernel32.dll"
|
2011-09-17 01:57:59 -06:00
|
|
|
#pragma dynimport runtime·ResumeThread ResumeThread "kernel32.dll"
|
2011-02-14 10:15:13 -07:00
|
|
|
#pragma dynimport runtime·SetConsoleCtrlHandler SetConsoleCtrlHandler "kernel32.dll"
|
2010-12-07 13:28:33 -07:00
|
|
|
#pragma dynimport runtime·SetEvent SetEvent "kernel32.dll"
|
2011-09-17 01:57:59 -06:00
|
|
|
#pragma dynimport runtime·SetThreadPriority SetThreadPriority "kernel32.dll"
|
|
|
|
#pragma dynimport runtime·SetWaitableTimer SetWaitableTimer "kernel32.dll"
|
2011-09-30 12:33:13 -06:00
|
|
|
#pragma dynimport runtime·Sleep Sleep "kernel32.dll"
|
2011-09-17 01:57:59 -06:00
|
|
|
#pragma dynimport runtime·SuspendThread SuspendThread "kernel32.dll"
|
|
|
|
#pragma dynimport runtime·timeBeginPeriod timeBeginPeriod "winmm.dll"
|
2011-02-01 09:49:24 -07:00
|
|
|
#pragma dynimport runtime·WaitForSingleObject WaitForSingleObject "kernel32.dll"
|
2010-12-07 13:28:33 -07:00
|
|
|
#pragma dynimport runtime·WriteFile WriteFile "kernel32.dll"
|
2010-01-06 18:58:55 -07:00
|
|
|
|
2010-12-12 22:41:02 -07:00
|
|
|
extern void *runtime·CloseHandle;
|
2011-02-01 09:49:24 -07:00
|
|
|
extern void *runtime·CreateEvent;
|
|
|
|
extern void *runtime·CreateThread;
|
2011-09-17 01:57:59 -06:00
|
|
|
extern void *runtime·CreateWaitableTimer;
|
|
|
|
extern void *runtime·DuplicateHandle;
|
2010-12-12 22:41:02 -07:00
|
|
|
extern void *runtime·ExitProcess;
|
2011-02-01 09:49:24 -07:00
|
|
|
extern void *runtime·FreeEnvironmentStringsW;
|
|
|
|
extern void *runtime·GetEnvironmentStringsW;
|
|
|
|
extern void *runtime·GetProcAddress;
|
2010-12-12 22:41:02 -07:00
|
|
|
extern void *runtime·GetStdHandle;
|
2011-09-30 12:33:13 -06:00
|
|
|
extern void *runtime·GetSystemInfo;
|
2011-11-03 15:35:28 -06:00
|
|
|
extern void *runtime·GetSystemTimeAsFileTime;
|
2011-09-17 01:57:59 -06:00
|
|
|
extern void *runtime·GetThreadContext;
|
2011-10-15 00:29:25 -06:00
|
|
|
extern void *runtime·LoadLibrary;
|
2011-09-17 01:57:59 -06:00
|
|
|
extern void *runtime·ResumeThread;
|
2011-02-14 10:15:13 -07:00
|
|
|
extern void *runtime·SetConsoleCtrlHandler;
|
2010-12-12 22:41:02 -07:00
|
|
|
extern void *runtime·SetEvent;
|
2011-09-17 01:57:59 -06:00
|
|
|
extern void *runtime·SetThreadPriority;
|
|
|
|
extern void *runtime·SetWaitableTimer;
|
2011-09-30 12:33:13 -06:00
|
|
|
extern void *runtime·Sleep;
|
2011-09-17 01:57:59 -06:00
|
|
|
extern void *runtime·SuspendThread;
|
|
|
|
extern void *runtime·timeBeginPeriod;
|
2011-02-01 09:49:24 -07:00
|
|
|
extern void *runtime·WaitForSingleObject;
|
2010-12-12 22:41:02 -07:00
|
|
|
extern void *runtime·WriteFile;
|
2010-01-06 18:58:55 -07:00
|
|
|
|
2011-09-30 12:33:13 -06:00
|
|
|
static int32
|
|
|
|
getproccount(void)
|
|
|
|
{
|
|
|
|
SystemInfo info;
|
|
|
|
|
|
|
|
runtime·stdcall(runtime·GetSystemInfo, 1, &info);
|
|
|
|
return info.dwNumberOfProcessors;
|
|
|
|
}
|
|
|
|
|
2010-01-06 18:58:55 -07:00
|
|
|
void
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·osinit(void)
|
2010-01-06 18:58:55 -07:00
|
|
|
{
|
2011-09-17 01:57:59 -06:00
|
|
|
// -1 = current process, -2 = current thread
|
|
|
|
runtime·stdcall(runtime·DuplicateHandle, 7,
|
|
|
|
(uintptr)-1, (uintptr)-2, (uintptr)-1, &m->thread,
|
|
|
|
(uintptr)0, (uintptr)0, (uintptr)DUPLICATE_SAME_ACCESS);
|
2011-06-27 20:46:16 -06:00
|
|
|
runtime·stdcall(runtime·SetConsoleCtrlHandler, 2, runtime·ctrlhandler, (uintptr)1);
|
2011-09-17 01:57:59 -06:00
|
|
|
runtime·stdcall(runtime·timeBeginPeriod, 1, (uintptr)1);
|
2011-09-30 12:33:13 -06:00
|
|
|
runtime·ncpu = getproccount();
|
2010-01-06 18:58:55 -07:00
|
|
|
}
|
|
|
|
|
2011-01-11 17:48:15 -07:00
|
|
|
void
|
|
|
|
runtime·goenvs(void)
|
|
|
|
{
|
2011-11-15 10:48:22 -07:00
|
|
|
extern Slice syscall·envs;
|
2011-01-11 17:48:15 -07:00
|
|
|
|
|
|
|
uint16 *env;
|
|
|
|
String *s;
|
|
|
|
int32 i, n;
|
|
|
|
uint16 *p;
|
|
|
|
|
|
|
|
env = runtime·stdcall(runtime·GetEnvironmentStringsW, 0);
|
|
|
|
|
|
|
|
n = 0;
|
|
|
|
for(p=env; *p; n++)
|
|
|
|
p += runtime·findnullw(p)+1;
|
|
|
|
|
|
|
|
s = runtime·malloc(n*sizeof s[0]);
|
|
|
|
|
|
|
|
p = env;
|
|
|
|
for(i=0; i<n; i++) {
|
|
|
|
s[i] = runtime·gostringw(p);
|
|
|
|
p += runtime·findnullw(p)+1;
|
|
|
|
}
|
2011-11-15 10:48:22 -07:00
|
|
|
syscall·envs.array = (byte*)s;
|
|
|
|
syscall·envs.len = n;
|
|
|
|
syscall·envs.cap = n;
|
2011-01-11 17:48:15 -07:00
|
|
|
|
|
|
|
runtime·stdcall(runtime·FreeEnvironmentStringsW, 1, env);
|
|
|
|
}
|
|
|
|
|
2010-01-06 18:58:55 -07:00
|
|
|
void
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·exit(int32 code)
|
2010-01-06 18:58:55 -07:00
|
|
|
{
|
2011-06-27 20:46:16 -06:00
|
|
|
runtime·stdcall(runtime·ExitProcess, 1, (uintptr)code);
|
2010-01-06 18:58:55 -07:00
|
|
|
}
|
|
|
|
|
2012-03-08 22:10:34 -07:00
|
|
|
int32
|
|
|
|
runtime·write(int32 fd, void *buf, int32 n)
|
|
|
|
{
|
|
|
|
void *handle;
|
|
|
|
uint32 written;
|
|
|
|
|
|
|
|
written = 0;
|
|
|
|
switch(fd) {
|
|
|
|
case 1:
|
|
|
|
handle = runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-11);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
handle = runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-12);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
runtime·stdcall(runtime·WriteFile, 5, handle, buf, (uintptr)n, &written, (uintptr)0);
|
|
|
|
return written;
|
|
|
|
}
|
|
|
|
|
2011-09-30 12:33:13 -06:00
|
|
|
void
|
|
|
|
runtime·osyield(void)
|
|
|
|
{
|
|
|
|
runtime·stdcall(runtime·Sleep, 1, (uintptr)0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
runtime·usleep(uint32 us)
|
|
|
|
{
|
|
|
|
us /= 1000;
|
|
|
|
if(us == 0)
|
|
|
|
us = 1;
|
|
|
|
runtime·stdcall(runtime·Sleep, 1, (uintptr)us);
|
|
|
|
}
|
|
|
|
|
runtime: add timer support, use for package time
This looks like it is just moving some code from
time to runtime (and translating it to C), but the
runtime can do a better job managing the goroutines,
and it needs this functionality for its own maintenance
(for example, for the garbage collector to hand back
unused memory to the OS on a time delay).
Might as well have just one copy of the timer logic,
and runtime can't depend on time, so vice versa.
It also unifies Sleep, NewTicker, and NewTimer behind
one mechanism, so that there are no claims that one
is more efficient than another. (For example, today
people recommend using time.After instead of time.Sleep
to avoid blocking an OS thread.)
Fixes #1644.
Fixes #1731.
Fixes #2190.
R=golang-dev, r, hectorchu, iant, iant, jsing, alex.brainman, dvyukov
CC=golang-dev
https://golang.org/cl/5334051
2011-11-09 13:17:05 -07:00
|
|
|
#define INFINITE ((uintptr)0xFFFFFFFF)
|
|
|
|
|
|
|
|
int32
|
|
|
|
runtime·semasleep(int64 ns)
|
2010-01-06 18:58:55 -07:00
|
|
|
{
|
runtime: add timer support, use for package time
This looks like it is just moving some code from
time to runtime (and translating it to C), but the
runtime can do a better job managing the goroutines,
and it needs this functionality for its own maintenance
(for example, for the garbage collector to hand back
unused memory to the OS on a time delay).
Might as well have just one copy of the timer logic,
and runtime can't depend on time, so vice versa.
It also unifies Sleep, NewTicker, and NewTimer behind
one mechanism, so that there are no claims that one
is more efficient than another. (For example, today
people recommend using time.After instead of time.Sleep
to avoid blocking an OS thread.)
Fixes #1644.
Fixes #1731.
Fixes #2190.
R=golang-dev, r, hectorchu, iant, iant, jsing, alex.brainman, dvyukov
CC=golang-dev
https://golang.org/cl/5334051
2011-11-09 13:17:05 -07:00
|
|
|
uintptr ms;
|
|
|
|
|
|
|
|
if(ns < 0)
|
|
|
|
ms = INFINITE;
|
|
|
|
else if(ns/1000000 > 0x7fffffffLL)
|
|
|
|
ms = 0x7fffffff;
|
|
|
|
else {
|
|
|
|
ms = ns/1000000;
|
|
|
|
if(ms == 0)
|
|
|
|
ms = 1;
|
|
|
|
}
|
|
|
|
if(runtime·stdcall(runtime·WaitForSingleObject, 2, m->waitsema, ms) != 0)
|
|
|
|
return -1; // timeout
|
|
|
|
return 0;
|
2010-01-06 18:58:55 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2011-11-02 07:42:01 -06:00
|
|
|
runtime·semawakeup(M *mp)
|
2010-01-06 18:58:55 -07:00
|
|
|
{
|
2011-11-02 07:42:01 -06:00
|
|
|
runtime·stdcall(runtime·SetEvent, 1, mp->waitsema);
|
2010-01-06 18:58:55 -07:00
|
|
|
}
|
|
|
|
|
2011-11-02 07:42:01 -06:00
|
|
|
uintptr
|
|
|
|
runtime·semacreate(void)
|
2010-01-06 18:58:55 -07:00
|
|
|
{
|
2011-11-02 07:42:01 -06:00
|
|
|
return (uintptr)runtime·stdcall(runtime·CreateEvent, 4, (uintptr)0, (uintptr)0, (uintptr)0, (uintptr)0);
|
2010-01-06 18:58:55 -07:00
|
|
|
}
|
|
|
|
|
2011-12-07 06:53:17 -07:00
|
|
|
#define STACK_SIZE_PARAM_IS_A_RESERVATION ((uintptr)0x00010000)
|
|
|
|
|
2010-01-06 18:58:55 -07:00
|
|
|
void
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
|
2010-01-06 18:58:55 -07:00
|
|
|
{
|
2011-02-14 15:42:25 -07:00
|
|
|
void *thandle;
|
|
|
|
|
2010-09-11 19:45:16 -06:00
|
|
|
USED(stk);
|
|
|
|
USED(g); // assuming g = m->g0
|
|
|
|
USED(fn); // assuming fn = mstart
|
|
|
|
|
2011-09-17 01:57:59 -06:00
|
|
|
thandle = runtime·stdcall(runtime·CreateThread, 6,
|
2011-12-07 06:53:17 -07:00
|
|
|
nil, (uintptr)0x20000, runtime·tstart_stdcall, m,
|
|
|
|
STACK_SIZE_PARAM_IS_A_RESERVATION, nil);
|
2011-09-17 01:57:59 -06:00
|
|
|
if(thandle == nil) {
|
2011-02-14 15:42:25 -07:00
|
|
|
runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), runtime·getlasterror());
|
|
|
|
runtime·throw("runtime.newosproc");
|
|
|
|
}
|
2011-09-17 01:57:59 -06:00
|
|
|
runtime·atomicstorep(&m->thread, thandle);
|
2010-01-06 18:58:55 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Called to initialize a new m (including the bootstrap m).
|
|
|
|
void
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·minit(void)
|
2010-01-06 18:58:55 -07:00
|
|
|
{
|
2012-05-29 23:10:54 -06:00
|
|
|
runtime·install_exception_handler();
|
2010-01-06 18:58:55 -07:00
|
|
|
}
|
2010-06-11 02:38:12 -06:00
|
|
|
|
2011-11-03 15:35:28 -06:00
|
|
|
int64
|
|
|
|
runtime·nanotime(void)
|
2011-02-01 09:49:24 -07:00
|
|
|
{
|
2011-11-03 15:35:28 -06:00
|
|
|
int64 filetime;
|
2011-02-01 09:49:24 -07:00
|
|
|
|
2011-11-03 15:35:28 -06:00
|
|
|
runtime·stdcall(runtime·GetSystemTimeAsFileTime, 1, &filetime);
|
runtime: add timer support, use for package time
This looks like it is just moving some code from
time to runtime (and translating it to C), but the
runtime can do a better job managing the goroutines,
and it needs this functionality for its own maintenance
(for example, for the garbage collector to hand back
unused memory to the OS on a time delay).
Might as well have just one copy of the timer logic,
and runtime can't depend on time, so vice versa.
It also unifies Sleep, NewTicker, and NewTimer behind
one mechanism, so that there are no claims that one
is more efficient than another. (For example, today
people recommend using time.After instead of time.Sleep
to avoid blocking an OS thread.)
Fixes #1644.
Fixes #1731.
Fixes #2190.
R=golang-dev, r, hectorchu, iant, iant, jsing, alex.brainman, dvyukov
CC=golang-dev
https://golang.org/cl/5334051
2011-11-09 13:17:05 -07:00
|
|
|
|
2011-11-03 15:35:28 -06:00
|
|
|
// Filetime is 100s of nanoseconds since January 1, 1601.
|
|
|
|
// Convert to nanoseconds since January 1, 1970.
|
|
|
|
return (filetime - 116444736000000000LL) * 100LL;
|
2011-02-01 09:49:24 -07:00
|
|
|
}
|
|
|
|
|
2011-11-30 09:59:44 -07:00
|
|
|
void
|
|
|
|
time·now(int64 sec, int32 usec)
|
|
|
|
{
|
|
|
|
int64 ns;
|
2012-02-28 14:18:24 -07:00
|
|
|
|
2011-11-30 09:59:44 -07:00
|
|
|
ns = runtime·nanotime();
|
|
|
|
sec = ns / 1000000000LL;
|
|
|
|
usec = ns - sec * 1000000000LL;
|
|
|
|
FLUSH(&sec);
|
|
|
|
FLUSH(&usec);
|
|
|
|
}
|
|
|
|
|
2010-06-11 02:38:12 -06:00
|
|
|
// Calling stdcall on os stack.
|
|
|
|
#pragma textflag 7
|
|
|
|
void *
|
runtime: ,s/[a-zA-Z0-9_]+/runtime·&/g, almost
Prefix all external symbols in runtime by runtime·,
to avoid conflicts with possible symbols of the same
name in linked-in C libraries. The obvious conflicts
are printf, malloc, and free, but hide everything to
avoid future pain.
The symbols left alone are:
** known to cgo **
_cgo_free
_cgo_malloc
libcgo_thread_start
initcgo
ncgocall
** known to linker **
_rt0_$GOARCH
_rt0_$GOARCH_$GOOS
text
etext
data
end
pclntab
epclntab
symtab
esymtab
** known to C compiler **
_divv
_modv
_div64by32
etc (arch specific)
Tested on darwin/386, darwin/amd64, linux/386, linux/amd64.
Built (but not tested) for freebsd/386, freebsd/amd64, linux/arm, windows/386.
R=r, PeterGo
CC=golang-dev
https://golang.org/cl/2899041
2010-11-04 12:00:19 -06:00
|
|
|
runtime·stdcall(void *fn, int32 count, ...)
|
2010-06-11 02:38:12 -06:00
|
|
|
{
|
2011-08-27 07:17:00 -06:00
|
|
|
WinCall c;
|
|
|
|
|
|
|
|
c.fn = fn;
|
|
|
|
c.n = count;
|
|
|
|
c.args = (uintptr*)&count + 1;
|
|
|
|
runtime·asmcgocall(runtime·asmstdcall, &c);
|
2011-09-14 00:19:45 -06:00
|
|
|
return (void*)c.r1;
|
2010-06-11 02:38:12 -06:00
|
|
|
}
|
2011-01-19 13:10:15 -07:00
|
|
|
|
|
|
|
uint32
|
|
|
|
runtime·issigpanic(uint32 code)
|
|
|
|
{
|
|
|
|
switch(code) {
|
|
|
|
case EXCEPTION_ACCESS_VIOLATION:
|
|
|
|
case EXCEPTION_INT_DIVIDE_BY_ZERO:
|
|
|
|
case EXCEPTION_INT_OVERFLOW:
|
|
|
|
case EXCEPTION_FLT_DENORMAL_OPERAND:
|
|
|
|
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
|
|
|
|
case EXCEPTION_FLT_INEXACT_RESULT:
|
|
|
|
case EXCEPTION_FLT_OVERFLOW:
|
|
|
|
case EXCEPTION_FLT_UNDERFLOW:
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
runtime·sigpanic(void)
|
|
|
|
{
|
|
|
|
switch(g->sig) {
|
|
|
|
case EXCEPTION_ACCESS_VIOLATION:
|
2012-01-10 12:46:57 -07:00
|
|
|
if(g->sigcode1 < 0x1000) {
|
|
|
|
if(g->sigpc == 0)
|
|
|
|
runtime·panicstring("call of nil func value");
|
2011-01-19 13:10:15 -07:00
|
|
|
runtime·panicstring("invalid memory address or nil pointer dereference");
|
2012-01-10 12:46:57 -07:00
|
|
|
}
|
2011-01-19 13:10:15 -07:00
|
|
|
runtime·printf("unexpected fault address %p\n", g->sigcode1);
|
|
|
|
runtime·throw("fault");
|
|
|
|
case EXCEPTION_INT_DIVIDE_BY_ZERO:
|
|
|
|
runtime·panicstring("integer divide by zero");
|
|
|
|
case EXCEPTION_INT_OVERFLOW:
|
|
|
|
runtime·panicstring("integer overflow");
|
|
|
|
case EXCEPTION_FLT_DENORMAL_OPERAND:
|
|
|
|
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
|
|
|
|
case EXCEPTION_FLT_INEXACT_RESULT:
|
|
|
|
case EXCEPTION_FLT_OVERFLOW:
|
|
|
|
case EXCEPTION_FLT_UNDERFLOW:
|
|
|
|
runtime·panicstring("floating point error");
|
|
|
|
}
|
|
|
|
runtime·throw("fault");
|
|
|
|
}
|
2011-01-21 19:55:53 -07:00
|
|
|
|
2012-02-13 19:51:38 -07:00
|
|
|
extern void *runtime·sigtramp;
|
|
|
|
|
|
|
|
void
|
|
|
|
runtime·initsig(void)
|
|
|
|
{
|
|
|
|
// following line keeps sigtramp alive at link stage
|
|
|
|
// if there's a better way please write it here
|
|
|
|
void *p = runtime·sigtramp;
|
|
|
|
USED(p);
|
|
|
|
}
|
|
|
|
|
2011-02-14 10:15:13 -07:00
|
|
|
uint32
|
|
|
|
runtime·ctrlhandler1(uint32 type)
|
|
|
|
{
|
|
|
|
int32 s;
|
|
|
|
|
|
|
|
switch(type) {
|
|
|
|
case CTRL_C_EVENT:
|
|
|
|
case CTRL_BREAK_EVENT:
|
|
|
|
s = SIGINT;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(runtime·sigsend(s))
|
|
|
|
return 1;
|
|
|
|
runtime·exit(2); // SIGINT, SIGTERM, etc
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-09-17 01:57:59 -06:00
|
|
|
extern void runtime·dosigprof(Context *r, G *gp);
|
|
|
|
extern void runtime·profileloop(void);
|
|
|
|
static void *profiletimer;
|
|
|
|
|
|
|
|
static void
|
|
|
|
profilem(M *mp)
|
|
|
|
{
|
|
|
|
extern M runtime·m0;
|
|
|
|
extern uint32 runtime·tls0[];
|
|
|
|
byte rbuf[sizeof(Context)+15];
|
|
|
|
Context *r;
|
|
|
|
void *tls;
|
|
|
|
G *gp;
|
|
|
|
|
|
|
|
tls = mp->tls;
|
|
|
|
if(mp == &runtime·m0)
|
|
|
|
tls = runtime·tls0;
|
|
|
|
gp = *(G**)tls;
|
|
|
|
|
|
|
|
if(gp != nil && gp != mp->g0 && gp->status != Gsyscall) {
|
|
|
|
// align Context to 16 bytes
|
|
|
|
r = (Context*)((uintptr)(&rbuf[15]) & ~15);
|
|
|
|
r->ContextFlags = CONTEXT_CONTROL;
|
|
|
|
runtime·stdcall(runtime·GetThreadContext, 2, mp->thread, r);
|
|
|
|
runtime·dosigprof(r, gp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
runtime·profileloop1(void)
|
|
|
|
{
|
|
|
|
M *mp, *allm;
|
|
|
|
void *thread;
|
|
|
|
|
|
|
|
runtime·stdcall(runtime·SetThreadPriority, 2,
|
|
|
|
(uintptr)-2, (uintptr)THREAD_PRIORITY_HIGHEST);
|
|
|
|
|
|
|
|
for(;;) {
|
|
|
|
runtime·stdcall(runtime·WaitForSingleObject, 2, profiletimer, (uintptr)-1);
|
|
|
|
allm = runtime·atomicloadp(&runtime·allm);
|
|
|
|
for(mp = allm; mp != nil; mp = mp->alllink) {
|
|
|
|
thread = runtime·atomicloadp(&mp->thread);
|
|
|
|
if(thread == nil)
|
|
|
|
continue;
|
|
|
|
runtime·stdcall(runtime·SuspendThread, 1, thread);
|
|
|
|
if(mp->profilehz != 0)
|
|
|
|
profilem(mp);
|
|
|
|
runtime·stdcall(runtime·ResumeThread, 1, thread);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
runtime·resetcpuprofiler(int32 hz)
|
|
|
|
{
|
|
|
|
static Lock lock;
|
|
|
|
void *timer, *thread;
|
|
|
|
int32 ms;
|
|
|
|
int64 due;
|
|
|
|
|
|
|
|
runtime·lock(&lock);
|
|
|
|
if(profiletimer == nil) {
|
|
|
|
timer = runtime·stdcall(runtime·CreateWaitableTimer, 3, nil, nil, nil);
|
|
|
|
runtime·atomicstorep(&profiletimer, timer);
|
|
|
|
thread = runtime·stdcall(runtime·CreateThread, 6,
|
|
|
|
nil, nil, runtime·profileloop, nil, nil, nil);
|
|
|
|
runtime·stdcall(runtime·CloseHandle, 1, thread);
|
|
|
|
}
|
|
|
|
runtime·unlock(&lock);
|
|
|
|
|
|
|
|
ms = 0;
|
|
|
|
due = 1LL<<63;
|
|
|
|
if(hz > 0) {
|
|
|
|
ms = 1000 / hz;
|
|
|
|
if(ms == 0)
|
|
|
|
ms = 1;
|
|
|
|
due = ms * -10000;
|
|
|
|
}
|
|
|
|
runtime·stdcall(runtime·SetWaitableTimer, 6,
|
|
|
|
profiletimer, &due, (uintptr)ms, nil, nil, nil);
|
|
|
|
runtime·atomicstore((uint32*)&m->profilehz, hz);
|
|
|
|
}
|
|
|
|
|
2011-04-25 14:58:00 -06:00
|
|
|
void
|
|
|
|
os·sigpipe(void)
|
|
|
|
{
|
|
|
|
runtime·throw("too many writes on closed pipe");
|
|
|
|
}
|
2012-02-24 13:28:51 -07:00
|
|
|
|
|
|
|
uintptr
|
|
|
|
runtime·memlimit(void)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2012-02-28 14:18:24 -07:00
|
|
|
|
|
|
|
void
|
|
|
|
runtime·setprof(bool on)
|
|
|
|
{
|
|
|
|
USED(on);
|
|
|
|
}
|
2012-03-08 10:12:40 -07:00
|
|
|
|
2012-03-08 13:53:11 -07:00
|
|
|
int8 runtime·badcallbackmsg[] = "runtime: cgo callback on thread not created by Go.\n";
|
|
|
|
int32 runtime·badcallbacklen = sizeof runtime·badcallbackmsg - 1;
|
2012-03-12 13:55:18 -06:00
|
|
|
|
|
|
|
int8 runtime·badsignalmsg[] = "runtime: signal received on thread not created by Go.\n";
|
|
|
|
int32 runtime·badsignallen = sizeof runtime·badsignalmsg - 1;
|