summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/windows/thread.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/windows/thread.c')
-rw-r--r--src/pkg/runtime/windows/thread.c420
1 files changed, 0 insertions, 420 deletions
diff --git a/src/pkg/runtime/windows/thread.c b/src/pkg/runtime/windows/thread.c
deleted file mode 100644
index 5644fd5dd..000000000
--- a/src/pkg/runtime/windows/thread.c
+++ /dev/null
@@ -1,420 +0,0 @@
-// 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"
-#include "type.h"
-#include "defs.h"
-#include "os.h"
-
-#pragma dynimport runtime·CloseHandle CloseHandle "kernel32.dll"
-#pragma dynimport runtime·CreateEvent CreateEventA "kernel32.dll"
-#pragma dynimport runtime·CreateThread CreateThread "kernel32.dll"
-#pragma dynimport runtime·ExitProcess ExitProcess "kernel32.dll"
-#pragma dynimport runtime·FreeEnvironmentStringsW FreeEnvironmentStringsW "kernel32.dll"
-#pragma dynimport runtime·GetEnvironmentStringsW GetEnvironmentStringsW "kernel32.dll"
-#pragma dynimport runtime·GetProcAddress GetProcAddress "kernel32.dll"
-#pragma dynimport runtime·GetStdHandle GetStdHandle "kernel32.dll"
-#pragma dynimport runtime·LoadLibraryEx LoadLibraryExA "kernel32.dll"
-#pragma dynimport runtime·QueryPerformanceCounter QueryPerformanceCounter "kernel32.dll"
-#pragma dynimport runtime·QueryPerformanceFrequency QueryPerformanceFrequency "kernel32.dll"
-#pragma dynimport runtime·SetConsoleCtrlHandler SetConsoleCtrlHandler "kernel32.dll"
-#pragma dynimport runtime·SetEvent SetEvent "kernel32.dll"
-#pragma dynimport runtime·WaitForSingleObject WaitForSingleObject "kernel32.dll"
-#pragma dynimport runtime·WriteFile WriteFile "kernel32.dll"
-
-extern void *runtime·CloseHandle;
-extern void *runtime·CreateEvent;
-extern void *runtime·CreateThread;
-extern void *runtime·ExitProcess;
-extern void *runtime·FreeEnvironmentStringsW;
-extern void *runtime·GetEnvironmentStringsW;
-extern void *runtime·GetProcAddress;
-extern void *runtime·GetStdHandle;
-extern void *runtime·LoadLibraryEx;
-extern void *runtime·QueryPerformanceCounter;
-extern void *runtime·QueryPerformanceFrequency;
-extern void *runtime·SetConsoleCtrlHandler;
-extern void *runtime·SetEvent;
-extern void *runtime·WaitForSingleObject;
-extern void *runtime·WriteFile;
-
-static int64 timerfreq;
-
-void
-runtime·osinit(void)
-{
- runtime·stdcall(runtime·QueryPerformanceFrequency, 1, &timerfreq);
- runtime·stdcall(runtime·SetConsoleCtrlHandler, 2, runtime·ctrlhandler, (uintptr)1);
-}
-
-void
-runtime·goenvs(void)
-{
- extern Slice os·Envs;
-
- 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;
- }
- os·Envs.array = (byte*)s;
- os·Envs.len = n;
- os·Envs.cap = n;
-
- runtime·stdcall(runtime·FreeEnvironmentStringsW, 1, env);
-}
-
-void
-runtime·exit(int32 code)
-{
- runtime·stdcall(runtime·ExitProcess, 1, (uintptr)code);
-}
-
-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;
-}
-
-// Thread-safe allocation of an event.
-static void
-initevent(void **pevent)
-{
- void *event;
-
- event = runtime·stdcall(runtime·CreateEvent, 4, (uintptr)0, (uintptr)0, (uintptr)0, (uintptr)0);
- if(!runtime·casp(pevent, 0, event)) {
- // Someone else filled it in. Use theirs.
- runtime·stdcall(runtime·CloseHandle, 1, event);
- }
-}
-
-static void
-eventlock(Lock *l)
-{
- // Allocate event if needed.
- if(l->event == 0)
- initevent(&l->event);
-
- if(runtime·xadd(&l->key, 1) > 1) // someone else has it; wait
- runtime·stdcall(runtime·WaitForSingleObject, 2, l->event, (uintptr)-1);
-}
-
-static void
-eventunlock(Lock *l)
-{
- if(runtime·xadd(&l->key, -1) > 0) // someone else is waiting
- runtime·stdcall(runtime·SetEvent, 1, l->event);
-}
-
-void
-runtime·lock(Lock *l)
-{
- if(m->locks < 0)
- runtime·throw("lock count");
- m->locks++;
- eventlock(l);
-}
-
-void
-runtime·unlock(Lock *l)
-{
- m->locks--;
- if(m->locks < 0)
- runtime·throw("lock count");
- eventunlock(l);
-}
-
-void
-runtime·destroylock(Lock *l)
-{
- if(l->event != 0)
- runtime·stdcall(runtime·CloseHandle, 1, l->event);
-}
-
-void
-runtime·noteclear(Note *n)
-{
- n->lock.key = 0; // memset(n, 0, sizeof *n)
- eventlock(&n->lock);
-}
-
-void
-runtime·notewakeup(Note *n)
-{
- eventunlock(&n->lock);
-}
-
-void
-runtime·notesleep(Note *n)
-{
- eventlock(&n->lock);
- eventunlock(&n->lock); // Let other sleepers find out too.
-}
-
-void
-runtime·newosproc(M *m, G *g, void *stk, void (*fn)(void))
-{
- void *thandle;
-
- USED(stk);
- USED(g); // assuming g = m->g0
- USED(fn); // assuming fn = mstart
-
- thandle = runtime·stdcall(runtime·CreateThread, 6, (uintptr)0, (uintptr)0, runtime·tstart_stdcall, m, (uintptr)0, (uintptr)0);
- if(thandle == 0) {
- runtime·printf("runtime: failed to create new OS thread (have %d already; errno=%d)\n", runtime·mcount(), runtime·getlasterror());
- runtime·throw("runtime.newosproc");
- }
-}
-
-// Called to initialize a new m (including the bootstrap m).
-void
-runtime·minit(void)
-{
-}
-
-void
-runtime·gettime(int64 *sec, int32 *usec)
-{
- int64 count;
-
- runtime·stdcall(runtime·QueryPerformanceCounter, 1, &count);
- *sec = count / timerfreq;
- count %= timerfreq;
- *usec = count*1000000 / timerfreq;
-}
-
-// Calling stdcall on os stack.
-#pragma textflag 7
-void *
-runtime·stdcall(void *fn, int32 count, ...)
-{
- return runtime·stdcall_raw(fn, count, (uintptr*)&count + 1);
-}
-
-uintptr
-runtime·syscall(void *fn, uintptr nargs, void *args, uintptr *err)
-{
- G *oldlock;
- uintptr ret;
-
- /*
- * Lock g to m to ensure we stay on the same stack if we do a callback.
- */
- oldlock = m->lockedg;
- m->lockedg = g;
- g->lockedm = m;
-
- runtime·entersyscall();
- runtime·setlasterror(0);
- ret = (uintptr)runtime·stdcall_raw(fn, nargs, args);
- if(err)
- *err = runtime·getlasterror();
- runtime·exitsyscall();
-
- m->lockedg = oldlock;
- if(oldlock == nil)
- g->lockedm = nil;
-
- return ret;
-}
-
-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:
- if(g->sigcode1 < 0x1000)
- runtime·panicstring("invalid memory address or nil pointer dereference");
- 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");
-}
-
-String
-runtime·signame(int32 sig)
-{
- int8 *s;
-
- switch(sig) {
- case SIGINT:
- s = "SIGINT: interrupt";
- break;
- default:
- return runtime·emptystring;
- }
- return runtime·gostringnocopy((byte*)s);
-}
-
-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;
-}
-
-// Will keep all callbacks in a linked list, so they don't get garbage collected.
-typedef struct Callback Callback;
-struct Callback {
- Callback* link;
- void* gobody;
- byte asmbody;
-};
-
-typedef struct Callbacks Callbacks;
-struct Callbacks {
- Lock;
- Callback* link;
- int32 n;
-};
-
-static Callbacks cbs;
-
-// Call back from windows dll into go.
-byte *
-runtime·compilecallback(Eface fn, bool cleanstack)
-{
- Func *f;
- int32 argsize, n;
- byte *p;
- Callback *c;
-
- if(fn.type->kind != KindFunc)
- runtime·panicstring("not a function");
- if((f = runtime·findfunc((uintptr)fn.data)) == nil)
- runtime·throw("cannot find function");
- argsize = (f->args-2) * 4;
-
- // compute size of new fn.
- // must match code laid out below.
- n = 1+4; // MOVL fn, AX
- n += 1+4; // MOVL argsize, DX
- n += 1+4; // MOVL callbackasm, CX
- n += 2; // CALL CX
- n += 1; // RET
- if(cleanstack)
- n += 2; // ... argsize
-
- runtime·lock(&cbs);
- for(c = cbs.link; c != nil; c = c->link) {
- if(c->gobody == fn.data) {
- runtime·unlock(&cbs);
- return &c->asmbody;
- }
- }
- if(cbs.n >= 2000)
- runtime·throw("too many callback functions");
- c = runtime·mal(sizeof *c + n);
- c->gobody = fn.data;
- c->link = cbs.link;
- cbs.link = c;
- cbs.n++;
- runtime·unlock(&cbs);
-
- p = &c->asmbody;
-
- // MOVL fn, AX
- *p++ = 0xb8;
- *(uint32*)p = (uint32)fn.data;
- p += 4;
-
- // MOVL argsize, DX
- *p++ = 0xba;
- *(uint32*)p = argsize;
- p += 4;
-
- // MOVL callbackasm, CX
- *p++ = 0xb9;
- *(uint32*)p = (uint32)runtime·callbackasm;
- p += 4;
-
- // CALL CX
- *p++ = 0xff;
- *p++ = 0xd1;
-
- // RET argsize?
- if(cleanstack) {
- *p++ = 0xc2;
- *(uint16*)p = argsize;
- } else
- *p = 0xc3;
-
- return &c->asmbody;
-}
-
-void
-os·sigpipe(void)
-{
- runtime·throw("too many writes on closed pipe");
-}