Commit 73f5010d authored by Dmitriy Vyukov's avatar Dmitriy Vyukov

runtime: allow to call stdcall from Go on windows

I've started with just one function with 8 arguments,
but stdcall is called from nosplit functions
and 8 args overflow nosplit area.

LGTM=aram, alex.brainman
R=golang-codereviews, aram, alex.brainman, dave
CC=golang-codereviews, iant, khr, rsc
https://golang.org/cl/135090043
parent 9f0b749b
...@@ -29,7 +29,7 @@ void* ...@@ -29,7 +29,7 @@ void*
runtime·SysAlloc(uintptr n, uint64 *stat) runtime·SysAlloc(uintptr n, uint64 *stat)
{ {
runtime·xadd64(stat, n); runtime·xadd64(stat, n);
return runtime·stdcall(runtime·VirtualAlloc, 4, nil, n, (uintptr)(MEM_COMMIT|MEM_RESERVE), (uintptr)PAGE_READWRITE); return runtime·stdcall4(runtime·VirtualAlloc, 0, n, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
} }
void void
...@@ -38,7 +38,7 @@ runtime·SysUnused(void *v, uintptr n) ...@@ -38,7 +38,7 @@ runtime·SysUnused(void *v, uintptr n)
void *r; void *r;
uintptr small; uintptr small;
r = runtime·stdcall(runtime·VirtualFree, 3, v, n, (uintptr)MEM_DECOMMIT); r = runtime·stdcall3(runtime·VirtualFree, (uintptr)v, n, MEM_DECOMMIT);
if(r != nil) if(r != nil)
return; return;
...@@ -53,7 +53,7 @@ runtime·SysUnused(void *v, uintptr n) ...@@ -53,7 +53,7 @@ runtime·SysUnused(void *v, uintptr n)
// in the worst case, but that's fast enough. // in the worst case, but that's fast enough.
while(n > 0) { while(n > 0) {
small = n; small = n;
while(small >= 4096 && runtime·stdcall(runtime·VirtualFree, 3, v, small, (uintptr)MEM_DECOMMIT) == nil) while(small >= 4096 && runtime·stdcall3(runtime·VirtualFree, (uintptr)v, small, MEM_DECOMMIT) == nil)
small = (small / 2) & ~(4096-1); small = (small / 2) & ~(4096-1);
if(small < 4096) if(small < 4096)
runtime·throw("runtime: failed to decommit pages"); runtime·throw("runtime: failed to decommit pages");
...@@ -67,7 +67,7 @@ runtime·SysUsed(void *v, uintptr n) ...@@ -67,7 +67,7 @@ runtime·SysUsed(void *v, uintptr n)
{ {
void *r; void *r;
r = runtime·stdcall(runtime·VirtualAlloc, 4, v, n, (uintptr)MEM_COMMIT, (uintptr)PAGE_READWRITE); r = runtime·stdcall4(runtime·VirtualAlloc, (uintptr)v, n, MEM_COMMIT, PAGE_READWRITE);
if(r != v) if(r != v)
runtime·throw("runtime: failed to commit pages"); runtime·throw("runtime: failed to commit pages");
} }
...@@ -78,7 +78,7 @@ runtime·SysFree(void *v, uintptr n, uint64 *stat) ...@@ -78,7 +78,7 @@ runtime·SysFree(void *v, uintptr n, uint64 *stat)
uintptr r; uintptr r;
runtime·xadd64(stat, -(uint64)n); runtime·xadd64(stat, -(uint64)n);
r = (uintptr)runtime·stdcall(runtime·VirtualFree, 3, v, (uintptr)0, (uintptr)MEM_RELEASE); r = (uintptr)runtime·stdcall3(runtime·VirtualFree, (uintptr)v, 0, MEM_RELEASE);
if(r == 0) if(r == 0)
runtime·throw("runtime: failed to release pages"); runtime·throw("runtime: failed to release pages");
} }
...@@ -96,12 +96,12 @@ runtime·SysReserve(void *v, uintptr n, bool *reserved) ...@@ -96,12 +96,12 @@ runtime·SysReserve(void *v, uintptr n, bool *reserved)
*reserved = true; *reserved = true;
// v is just a hint. // v is just a hint.
// First try at v. // First try at v.
v = runtime·stdcall(runtime·VirtualAlloc, 4, v, n, (uintptr)MEM_RESERVE, (uintptr)PAGE_READWRITE); v = runtime·stdcall4(runtime·VirtualAlloc, (uintptr)v, n, MEM_RESERVE, PAGE_READWRITE);
if(v != nil) if(v != nil)
return v; return v;
// Next let the kernel choose the address. // Next let the kernel choose the address.
return runtime·stdcall(runtime·VirtualAlloc, 4, nil, n, (uintptr)MEM_RESERVE, (uintptr)PAGE_READWRITE); return runtime·stdcall4(runtime·VirtualAlloc, 0, n, MEM_RESERVE, PAGE_READWRITE);
} }
void void
...@@ -112,7 +112,7 @@ runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat) ...@@ -112,7 +112,7 @@ runtime·SysMap(void *v, uintptr n, bool reserved, uint64 *stat)
USED(reserved); USED(reserved);
runtime·xadd64(stat, n); runtime·xadd64(stat, n);
p = runtime·stdcall(runtime·VirtualAlloc, 4, v, n, (uintptr)MEM_COMMIT, (uintptr)PAGE_READWRITE); p = runtime·stdcall4(runtime·VirtualAlloc, (uintptr)v, n, MEM_COMMIT, PAGE_READWRITE);
if(p != v) if(p != v)
runtime·throw("runtime: cannot map pages in arena address space"); runtime·throw("runtime: cannot map pages in arena address space");
} }
...@@ -47,7 +47,7 @@ static uintptr iocphandle = INVALID_HANDLE_VALUE; // completion port io handle ...@@ -47,7 +47,7 @@ static uintptr iocphandle = INVALID_HANDLE_VALUE; // completion port io handle
void void
runtime·netpollinit(void) runtime·netpollinit(void)
{ {
iocphandle = (uintptr)runtime·stdcall(runtime·CreateIoCompletionPort, 4, INVALID_HANDLE_VALUE, (uintptr)0, (uintptr)0, (uintptr)DWORD_MAX); iocphandle = (uintptr)runtime·stdcall4(runtime·CreateIoCompletionPort, INVALID_HANDLE_VALUE, 0, 0, DWORD_MAX);
if(iocphandle == 0) { if(iocphandle == 0) {
runtime·printf("netpoll: failed to create iocp handle (errno=%d)\n", runtime·getlasterror()); runtime·printf("netpoll: failed to create iocp handle (errno=%d)\n", runtime·getlasterror());
runtime·throw("netpoll: failed to create iocp handle"); runtime·throw("netpoll: failed to create iocp handle");
...@@ -59,7 +59,7 @@ int32 ...@@ -59,7 +59,7 @@ int32
runtime·netpollopen(uintptr fd, PollDesc *pd) runtime·netpollopen(uintptr fd, PollDesc *pd)
{ {
USED(pd); USED(pd);
if(runtime·stdcall(runtime·CreateIoCompletionPort, 4, fd, iocphandle, (uintptr)0, (uintptr)0) == 0) if(runtime·stdcall4(runtime·CreateIoCompletionPort, fd, iocphandle, 0, 0) == 0)
return -runtime·getlasterror(); return -runtime·getlasterror();
return 0; return 0;
} }
...@@ -103,7 +103,7 @@ retry: ...@@ -103,7 +103,7 @@ retry:
n = 8; n = 8;
if(block) if(block)
g->m->blocked = true; g->m->blocked = true;
if(runtime·stdcall(runtime·GetQueuedCompletionStatusEx, 6, iocphandle, entries, (uintptr)n, &n, (uintptr)wait, (uintptr)0) == 0) { if(runtime·stdcall6(runtime·GetQueuedCompletionStatusEx, iocphandle, (uintptr)entries, n, (uintptr)&n, wait, 0) == 0) {
g->m->blocked = false; g->m->blocked = false;
errno = runtime·getlasterror(); errno = runtime·getlasterror();
if(!block && errno == WAIT_TIMEOUT) if(!block && errno == WAIT_TIMEOUT)
...@@ -116,7 +116,7 @@ retry: ...@@ -116,7 +116,7 @@ retry:
op = entries[i].op; op = entries[i].op;
errno = 0; errno = 0;
qty = 0; qty = 0;
if(runtime·stdcall(runtime·WSAGetOverlappedResult, 5, runtime·netpollfd(op->pd), op, &qty, (uintptr)0, (uintptr)&flags) == 0) if(runtime·stdcall5(runtime·WSAGetOverlappedResult, runtime·netpollfd(op->pd), (uintptr)op, (uintptr)&qty, 0, (uintptr)&flags) == 0)
errno = runtime·getlasterror(); errno = runtime·getlasterror();
handlecompletion(&gp, op, errno, qty); handlecompletion(&gp, op, errno, qty);
} }
...@@ -126,7 +126,7 @@ retry: ...@@ -126,7 +126,7 @@ retry:
qty = 0; qty = 0;
if(block) if(block)
g->m->blocked = true; g->m->blocked = true;
if(runtime·stdcall(runtime·GetQueuedCompletionStatus, 5, iocphandle, &qty, &key, &op, (uintptr)wait) == 0) { if(runtime·stdcall5(runtime·GetQueuedCompletionStatus, iocphandle, (uintptr)&qty, (uintptr)&key, (uintptr)&op, wait) == 0) {
g->m->blocked = false; g->m->blocked = false;
errno = runtime·getlasterror(); errno = runtime·getlasterror();
if(!block && errno == WAIT_TIMEOUT) if(!block && errno == WAIT_TIMEOUT)
......
...@@ -81,7 +81,7 @@ getproccount(void) ...@@ -81,7 +81,7 @@ getproccount(void)
{ {
SystemInfo info; SystemInfo info;
runtime·stdcall(runtime·GetSystemInfo, 1, &info); runtime·stdcall1(runtime·GetSystemInfo, (uintptr)&info);
return info.dwNumberOfProcessors; return info.dwNumberOfProcessors;
} }
...@@ -92,20 +92,20 @@ runtime·osinit(void) ...@@ -92,20 +92,20 @@ runtime·osinit(void)
runtime·externalthreadhandlerp = (uintptr)runtime·externalthreadhandler; runtime·externalthreadhandlerp = (uintptr)runtime·externalthreadhandler;
runtime·stdcall(runtime·AddVectoredExceptionHandler, 2, (uintptr)1, (uintptr)runtime·sigtramp); runtime·stdcall2(runtime·AddVectoredExceptionHandler, 1, (uintptr)runtime·sigtramp);
runtime·stdcall(runtime·SetConsoleCtrlHandler, 2, runtime·ctrlhandler, (uintptr)1); runtime·stdcall2(runtime·SetConsoleCtrlHandler, (uintptr)runtime·ctrlhandler, 1);
runtime·stdcall(runtime·timeBeginPeriod, 1, (uintptr)1); runtime·stdcall1(runtime·timeBeginPeriod, 1);
runtime·ncpu = getproccount(); runtime·ncpu = getproccount();
// Windows dynamic priority boosting assumes that a process has different types // Windows dynamic priority boosting assumes that a process has different types
// of dedicated threads -- GUI, IO, computational, etc. Go processes use // of dedicated threads -- GUI, IO, computational, etc. Go processes use
// equivalent threads that all do a mix of GUI, IO, computations, etc. // equivalent threads that all do a mix of GUI, IO, computations, etc.
// In such context dynamic priority boosting does nothing but harm, so we turn it off. // In such context dynamic priority boosting does nothing but harm, so we turn it off.
runtime·stdcall(runtime·SetProcessPriorityBoost, 2, (uintptr)-1, (uintptr)1); runtime·stdcall2(runtime·SetProcessPriorityBoost, -1, 1);
kernel32 = runtime·stdcall(runtime·LoadLibraryA, 1, "kernel32.dll"); kernel32 = runtime·stdcall1(runtime·LoadLibraryA, (uintptr)"kernel32.dll");
if(kernel32 != nil) { if(kernel32 != nil) {
runtime·GetQueuedCompletionStatusEx = runtime·stdcall(runtime·GetProcAddress, 2, kernel32, "GetQueuedCompletionStatusEx"); runtime·GetQueuedCompletionStatusEx = runtime·stdcall2(runtime·GetProcAddress, (uintptr)kernel32, (uintptr)"GetQueuedCompletionStatusEx");
} }
} }
...@@ -115,15 +115,15 @@ runtime·get_random_data(byte **rnd, int32 *rnd_len) ...@@ -115,15 +115,15 @@ runtime·get_random_data(byte **rnd, int32 *rnd_len)
uintptr handle; uintptr handle;
*rnd = nil; *rnd = nil;
*rnd_len = 0; *rnd_len = 0;
if(runtime·stdcall(runtime·CryptAcquireContextW, 5, &handle, nil, nil, if(runtime·stdcall5(runtime·CryptAcquireContextW, (uintptr)&handle, (uintptr)nil, (uintptr)nil,
(uintptr)1 /* PROV_RSA_FULL */, 1 /* PROV_RSA_FULL */,
(uintptr)0xf0000000U /* CRYPT_VERIFYCONTEXT */) != 0) { 0xf0000000U /* CRYPT_VERIFYCONTEXT */) != 0) {
static byte random_data[HashRandomBytes]; static byte random_data[HashRandomBytes];
if(runtime·stdcall(runtime·CryptGenRandom, 3, handle, (uintptr)HashRandomBytes, random_data)) { if(runtime·stdcall3(runtime·CryptGenRandom, handle, HashRandomBytes, (uintptr)&random_data[0])) {
*rnd = random_data; *rnd = random_data;
*rnd_len = HashRandomBytes; *rnd_len = HashRandomBytes;
} }
runtime·stdcall(runtime·CryptReleaseContext, 2, handle, (uintptr)0); runtime·stdcall2(runtime·CryptReleaseContext, handle, 0);
} }
} }
...@@ -137,7 +137,7 @@ runtime·goenvs(void) ...@@ -137,7 +137,7 @@ runtime·goenvs(void)
int32 i, n; int32 i, n;
uint16 *p; uint16 *p;
env = runtime·stdcall(runtime·GetEnvironmentStringsW, 0); env = runtime·stdcall0(runtime·GetEnvironmentStringsW);
n = 0; n = 0;
for(p=env; *p; n++) for(p=env; *p; n++)
...@@ -154,13 +154,13 @@ runtime·goenvs(void) ...@@ -154,13 +154,13 @@ runtime·goenvs(void)
syscall·envs.len = n; syscall·envs.len = n;
syscall·envs.cap = n; syscall·envs.cap = n;
runtime·stdcall(runtime·FreeEnvironmentStringsW, 1, env); runtime·stdcall1(runtime·FreeEnvironmentStringsW, (uintptr)env);
} }
void void
runtime·exit(int32 code) runtime·exit(int32 code)
{ {
runtime·stdcall(runtime·ExitProcess, 1, (uintptr)code); runtime·stdcall1(runtime·ExitProcess, code);
} }
int32 int32
...@@ -172,17 +172,17 @@ runtime·write(uintptr fd, void *buf, int32 n) ...@@ -172,17 +172,17 @@ runtime·write(uintptr fd, void *buf, int32 n)
written = 0; written = 0;
switch(fd) { switch(fd) {
case 1: case 1:
handle = runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-11); handle = runtime·stdcall1(runtime·GetStdHandle, -11);
break; break;
case 2: case 2:
handle = runtime·stdcall(runtime·GetStdHandle, 1, (uintptr)-12); handle = runtime·stdcall1(runtime·GetStdHandle, -12);
break; break;
default: default:
// assume fd is real windows handle. // assume fd is real windows handle.
handle = (void*)fd; handle = (void*)fd;
break; break;
} }
runtime·stdcall(runtime·WriteFile, 5, handle, buf, (uintptr)n, &written, (uintptr)0); runtime·stdcall5(runtime·WriteFile, (uintptr)handle, (uintptr)buf, n, (uintptr)&written, 0);
return written; return written;
} }
...@@ -200,7 +200,7 @@ runtime·semasleep(int64 ns) ...@@ -200,7 +200,7 @@ runtime·semasleep(int64 ns)
if(ns == 0) if(ns == 0)
ns = 1; ns = 1;
} }
if(runtime·stdcall(runtime·WaitForSingleObject, 2, g->m->waitsema, (uintptr)ns) != 0) if(runtime·stdcall2(runtime·WaitForSingleObject, (uintptr)g->m->waitsema, ns) != 0)
return -1; // timeout return -1; // timeout
return 0; return 0;
} }
...@@ -208,13 +208,13 @@ runtime·semasleep(int64 ns) ...@@ -208,13 +208,13 @@ runtime·semasleep(int64 ns)
void void
runtime·semawakeup(M *mp) runtime·semawakeup(M *mp)
{ {
runtime·stdcall(runtime·SetEvent, 1, mp->waitsema); runtime·stdcall1(runtime·SetEvent, mp->waitsema);
} }
uintptr uintptr
runtime·semacreate(void) runtime·semacreate(void)
{ {
return (uintptr)runtime·stdcall(runtime·CreateEvent, 4, (uintptr)0, (uintptr)0, (uintptr)0, (uintptr)0); return (uintptr)runtime·stdcall4(runtime·CreateEvent, 0, 0, 0, 0);
} }
#define STACK_SIZE_PARAM_IS_A_RESERVATION ((uintptr)0x00010000) #define STACK_SIZE_PARAM_IS_A_RESERVATION ((uintptr)0x00010000)
...@@ -226,9 +226,9 @@ runtime·newosproc(M *mp, void *stk) ...@@ -226,9 +226,9 @@ runtime·newosproc(M *mp, void *stk)
USED(stk); USED(stk);
thandle = runtime·stdcall(runtime·CreateThread, 6, thandle = runtime·stdcall6(runtime·CreateThread,
nil, (uintptr)0x20000, runtime·tstart_stdcall, mp, (uintptr)nil, 0x20000, (uintptr)runtime·tstart_stdcall, (uintptr)mp,
STACK_SIZE_PARAM_IS_A_RESERVATION, nil); STACK_SIZE_PARAM_IS_A_RESERVATION, (uintptr)nil);
if(thandle == nil) { if(thandle == nil) {
runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), runtime·getlasterror()); runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), runtime·getlasterror());
runtime·throw("runtime.newosproc"); runtime·throw("runtime.newosproc");
...@@ -251,9 +251,7 @@ runtime·minit(void) ...@@ -251,9 +251,7 @@ runtime·minit(void)
void *thandle; void *thandle;
// -1 = current process, -2 = current thread // -1 = current process, -2 = current thread
runtime·stdcall(runtime·DuplicateHandle, 7, runtime·stdcall7(runtime·DuplicateHandle, -1, -2, -1, (uintptr)&thandle, 0, 0, DUPLICATE_SAME_ACCESS);
(uintptr)-1, (uintptr)-2, (uintptr)-1, &thandle,
(uintptr)0, (uintptr)0, (uintptr)DUPLICATE_SAME_ACCESS);
runtime·atomicstorep(&g->m->thread, thandle); runtime·atomicstorep(&g->m->thread, thandle);
} }
...@@ -318,12 +316,10 @@ time·now(int64 sec, int32 usec) ...@@ -318,12 +316,10 @@ time·now(int64 sec, int32 usec)
// Calling stdcall on os stack. // Calling stdcall on os stack.
#pragma textflag NOSPLIT #pragma textflag NOSPLIT
void * static void*
runtime·stdcall(void *fn, int32 count, ...) stdcall(void *fn)
{ {
g->m->libcall.fn = fn; g->m->libcall.fn = fn;
g->m->libcall.n = count;
g->m->libcall.args = (uintptr*)&count + 1;
if(g->m->profilehz != 0) { if(g->m->profilehz != 0) {
// leave pc/sp for cpu profiler // leave pc/sp for cpu profiler
g->m->libcallg = g; g->m->libcallg = g;
...@@ -337,6 +333,85 @@ runtime·stdcall(void *fn, int32 count, ...) ...@@ -337,6 +333,85 @@ runtime·stdcall(void *fn, int32 count, ...)
return (void*)g->m->libcall.r1; return (void*)g->m->libcall.r1;
} }
#pragma textflag NOSPLIT
void*
runtime·stdcall0(void *fn)
{
g->m->libcall.n = 0;
g->m->libcall.args = &fn; // it's unused but must be non-nil, otherwise crashes
return stdcall(fn);
}
#pragma textflag NOSPLIT
void*
runtime·stdcall1(void *fn, uintptr a0)
{
USED(a0);
g->m->libcall.n = 1;
g->m->libcall.args = &a0;
return stdcall(fn);
}
#pragma textflag NOSPLIT
void*
runtime·stdcall2(void *fn, uintptr a0, uintptr a1)
{
USED(a0, a1);
g->m->libcall.n = 2;
g->m->libcall.args = &a0;
return stdcall(fn);
}
#pragma textflag NOSPLIT
void*
runtime·stdcall3(void *fn, uintptr a0, uintptr a1, uintptr a2)
{
USED(a0, a1, a2);
g->m->libcall.n = 3;
g->m->libcall.args = &a0;
return stdcall(fn);
}
#pragma textflag NOSPLIT
void*
runtime·stdcall4(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3)
{
USED(a0, a1, a2, a3);
g->m->libcall.n = 4;
g->m->libcall.args = &a0;
return stdcall(fn);
}
#pragma textflag NOSPLIT
void*
runtime·stdcall5(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4)
{
USED(a0, a1, a2, a3, a4);
g->m->libcall.n = 5;
g->m->libcall.args = &a0;
return stdcall(fn);
}
#pragma textflag NOSPLIT
void*
runtime·stdcall6(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5)
{
USED(a0, a1, a2, a3, a4, a5);
g->m->libcall.n = 6;
g->m->libcall.args = &a0;
return stdcall(fn);
}
#pragma textflag NOSPLIT
void*
runtime·stdcall7(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5, uintptr a6)
{
USED(a0, a1, a2, a3, a4, a5, a6);
g->m->libcall.n = 7;
g->m->libcall.args = &a0;
return stdcall(fn);
}
extern void runtime·usleep1(uint32); extern void runtime·usleep1(uint32);
#pragma textflag NOSPLIT #pragma textflag NOSPLIT
...@@ -451,7 +526,7 @@ profilem(M *mp) ...@@ -451,7 +526,7 @@ profilem(M *mp)
// align Context to 16 bytes // align Context to 16 bytes
r = (Context*)((uintptr)(&rbuf[15]) & ~15); r = (Context*)((uintptr)(&rbuf[15]) & ~15);
r->ContextFlags = CONTEXT_CONTROL; r->ContextFlags = CONTEXT_CONTROL;
runtime·stdcall(runtime·GetThreadContext, 2, mp->thread, r); runtime·stdcall2(runtime·GetThreadContext, (uintptr)mp->thread, (uintptr)r);
runtime·dosigprof(r, gp, mp); runtime·dosigprof(r, gp, mp);
} }
...@@ -461,11 +536,10 @@ runtime·profileloop1(void) ...@@ -461,11 +536,10 @@ runtime·profileloop1(void)
M *mp, *allm; M *mp, *allm;
void *thread; void *thread;
runtime·stdcall(runtime·SetThreadPriority, 2, runtime·stdcall2(runtime·SetThreadPriority, -2, THREAD_PRIORITY_HIGHEST);
(uintptr)-2, (uintptr)THREAD_PRIORITY_HIGHEST);
for(;;) { for(;;) {
runtime·stdcall(runtime·WaitForSingleObject, 2, profiletimer, (uintptr)-1); runtime·stdcall2(runtime·WaitForSingleObject, (uintptr)profiletimer, -1);
allm = runtime·atomicloadp(&runtime·allm); allm = runtime·atomicloadp(&runtime·allm);
for(mp = allm; mp != nil; mp = mp->alllink) { for(mp = allm; mp != nil; mp = mp->alllink) {
thread = runtime·atomicloadp(&mp->thread); thread = runtime·atomicloadp(&mp->thread);
...@@ -474,10 +548,10 @@ runtime·profileloop1(void) ...@@ -474,10 +548,10 @@ runtime·profileloop1(void)
// idle timer thread, idle heap scavenger, etc. // idle timer thread, idle heap scavenger, etc.
if(thread == nil || mp->profilehz == 0 || mp->blocked) if(thread == nil || mp->profilehz == 0 || mp->blocked)
continue; continue;
runtime·stdcall(runtime·SuspendThread, 1, thread); runtime·stdcall1(runtime·SuspendThread, (uintptr)thread);
if(mp->profilehz != 0 && !mp->blocked) if(mp->profilehz != 0 && !mp->blocked)
profilem(mp); profilem(mp);
runtime·stdcall(runtime·ResumeThread, 1, thread); runtime·stdcall1(runtime·ResumeThread, (uintptr)thread);
} }
} }
} }
...@@ -492,11 +566,11 @@ runtime·resetcpuprofiler(int32 hz) ...@@ -492,11 +566,11 @@ runtime·resetcpuprofiler(int32 hz)
runtime·lock(&lock); runtime·lock(&lock);
if(profiletimer == nil) { if(profiletimer == nil) {
timer = runtime·stdcall(runtime·CreateWaitableTimer, 3, nil, nil, nil); timer = runtime·stdcall3(runtime·CreateWaitableTimer, (uintptr)nil, (uintptr)nil, (uintptr)nil);
runtime·atomicstorep(&profiletimer, timer); runtime·atomicstorep(&profiletimer, timer);
thread = runtime·stdcall(runtime·CreateThread, 6, thread = runtime·stdcall6(runtime·CreateThread,
nil, nil, runtime·profileloop, nil, nil, nil); (uintptr)nil, (uintptr)nil, (uintptr)runtime·profileloop, (uintptr)nil, (uintptr)nil, (uintptr)nil);
runtime·stdcall(runtime·CloseHandle, 1, thread); runtime·stdcall1(runtime·CloseHandle, (uintptr)thread);
} }
runtime·unlock(&lock); runtime·unlock(&lock);
...@@ -508,8 +582,8 @@ runtime·resetcpuprofiler(int32 hz) ...@@ -508,8 +582,8 @@ runtime·resetcpuprofiler(int32 hz)
ms = 1; ms = 1;
due = ms * -10000; due = ms * -10000;
} }
runtime·stdcall(runtime·SetWaitableTimer, 6, runtime·stdcall6(runtime·SetWaitableTimer,
profiletimer, &due, (uintptr)ms, nil, nil, nil); (uintptr)profiletimer, (uintptr)&due, ms, (uintptr)nil, (uintptr)nil, (uintptr)nil);
runtime·atomicstore((uint32*)&g->m->profilehz, hz); runtime·atomicstore((uint32*)&g->m->profilehz, hz);
} }
......
...@@ -6,6 +6,17 @@ package runtime ...@@ -6,6 +6,17 @@ package runtime
import "unsafe" import "unsafe"
type stdFunction *byte
func stdcall0(fn stdFunction) uintptr
func stdcall1(fn stdFunction, a0 uintptr) uintptr
func stdcall2(fn stdFunction, a0, a1 uintptr) uintptr
func stdcall3(fn stdFunction, a0, a1, a2 uintptr) uintptr
func stdcall4(fn stdFunction, a0, a1, a2, a3 uintptr) uintptr
func stdcall5(fn stdFunction, a0, a1, a2, a3, a4 uintptr) uintptr
func stdcall6(fn stdFunction, a0, a1, a2, a3, a4, a5 uintptr) uintptr
func stdcall7(fn stdFunction, a0, a1, a2, a3, a4, a5, a6 uintptr) uintptr
func asmstdcall(fn unsafe.Pointer) func asmstdcall(fn unsafe.Pointer)
func getlasterror() uint32 func getlasterror() uint32
func setlasterror(err uint32) func setlasterror(err uint32)
......
...@@ -8,11 +8,15 @@ extern void *runtime·GetQueuedCompletionStatusEx; ...@@ -8,11 +8,15 @@ extern void *runtime·GetQueuedCompletionStatusEx;
// Call a Windows function with stdcall conventions, // Call a Windows function with stdcall conventions,
// and switch to os stack during the call. // and switch to os stack during the call.
#pragma varargck countpos runtime·stdcall 2
#pragma varargck type runtime·stdcall void*
#pragma varargck type runtime·stdcall uintptr
void runtime·asmstdcall(void *c); void runtime·asmstdcall(void *c);
void *runtime·stdcall(void *fn, int32 count, ...); void *runtime·stdcall0(void *fn);
void *runtime·stdcall1(void *fn, uintptr a0);
void *runtime·stdcall2(void *fn, uintptr a0, uintptr a1);
void *runtime·stdcall3(void *fn, uintptr a0, uintptr a1, uintptr a2);
void *runtime·stdcall4(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3);
void *runtime·stdcall5(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4);
void *runtime·stdcall6(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5);
void *runtime·stdcall7(void *fn, uintptr a0, uintptr a1, uintptr a2, uintptr a3, uintptr a4, uintptr a5, uintptr a6);
uint32 runtime·getlasterror(void); uint32 runtime·getlasterror(void);
void runtime·setlasterror(uint32 err); void runtime·setlasterror(uint32 err);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment