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.c137
1 files changed, 16 insertions, 121 deletions
diff --git a/src/pkg/runtime/windows/thread.c b/src/pkg/runtime/windows/thread.c
index e08d1b6f0..b76eaac59 100644
--- a/src/pkg/runtime/windows/thread.c
+++ b/src/pkg/runtime/windows/thread.c
@@ -6,6 +6,7 @@
#include "type.h"
#include "defs.h"
#include "os.h"
+#include "cgocall.h"
#pragma dynimport runtime·CloseHandle CloseHandle "kernel32.dll"
#pragma dynimport runtime·CreateEvent CreateEventA "kernel32.dll"
@@ -221,34 +222,27 @@ runtime·gettime(int64 *sec, int32 *usec)
void *
runtime·stdcall(void *fn, int32 count, ...)
{
- return runtime·stdcall_raw(fn, count, (uintptr*)&count + 1);
+ WinCall c;
+
+ c.fn = fn;
+ c.n = count;
+ c.args = (uintptr*)&count + 1;
+ runtime·asmcgocall(runtime·asmstdcall, &c);
+ return (void*)c.r;
}
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;
+ WinCall c;
- return ret;
+ c.fn = fn;
+ c.n = nargs;
+ c.args = args;
+ runtime·cgocall(runtime·asmstdcall, &c);
+ if(err)
+ *err = c.err;
+ return c.r;
}
uint32
@@ -326,105 +320,6 @@ runtime·ctrlhandler1(uint32 type)
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)
-{
- FuncType *ft;
- Type *t;
- int32 argsize, i, n;
- byte *p;
- Callback *c;
-
- if(fn.type == nil || fn.type->kind != KindFunc)
- runtime·panicstring("compilecallback: not a function");
- ft = (FuncType*)fn.type;
- if(ft->out.len != 1)
- runtime·panicstring("compilecallback: function must have one output parameter");
- if(((Type**)ft->out.array)[0]->size != sizeof(uintptr))
- runtime·panicstring("compilecallback: output parameter size is wrong");
- argsize = 0;
- for(i=0; i<ft->in.len; i++) {
- t = ((Type**)ft->in.array)[i];
- if(t->size != sizeof(uintptr))
- runtime·panicstring("compilecallback: input parameter size is wrong");
- argsize += t->size;
- }
-
- // 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)
{