// 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 "os.h" extern void *get_kernel_module(void); // Also referenced by external packages void *CloseHandle; void *ExitProcess; void *GetStdHandle; void *SetEvent; void *WriteFile; void *VirtualAlloc; void *LoadLibraryEx; void *GetProcAddress; void *GetLastError; static void *CreateEvent; static void *CreateThread; static void *GetModuleHandle; static void *WaitForSingleObject; static void* get_proc_addr2(byte *base, byte *name) { byte *pe_header, *exports; uint32 entries, *addr, *names, i; uint16 *ordinals; pe_header = base+*(uint32*)(base+0x3c); exports = base+*(uint32*)(pe_header+0x78); entries = *(uint32*)(exports+0x18); addr = (uint32*)(base+*(uint32*)(exports+0x1c)); names = (uint32*)(base+*(uint32*)(exports+0x20)); ordinals = (uint16*)(base+*(uint32*)(exports+0x24)); for(i=0; ievent == 0) initevent(&l->event); if(xadd(&l->key, 1) > 1) // someone else has it; wait stdcall(WaitForSingleObject, 2, l->event, -1); } static void eventunlock(Lock *l) { if(xadd(&l->key, -1) > 0) // someone else is waiting stdcall(SetEvent, 1, l->event); } void lock(Lock *l) { if(m->locks < 0) throw("lock count"); m->locks++; eventlock(l); } void unlock(Lock *l) { m->locks--; if(m->locks < 0) throw("lock count"); eventunlock(l); } void destroylock(Lock *l) { if(l->event != 0) stdcall(CloseHandle, 1, l->event); } void noteclear(Note *n) { eventlock(&n->lock); } void notewakeup(Note *n) { eventunlock(&n->lock); } void notesleep(Note *n) { eventlock(&n->lock); eventunlock(&n->lock); // Let other sleepers find out too. } void newosproc(M *m, G *g, void *stk, void (*fn)(void)) { struct { void *args; void *event_handle; } param = { &m }; extern uint32 threadstart(void *p); USED(g, stk, fn); param.event_handle = stdcall(CreateEvent, 4, 0, 0, 0, 0); stdcall(CreateThread, 6, 0, 0, threadstart, ¶m, 0, 0); stdcall(WaitForSingleObject, 2, param.event_handle, -1); stdcall(CloseHandle, 1, param.event_handle); } // Called to initialize a new m (including the bootstrap m). void minit(void) { } // Calling stdcall on os stack. #pragma textflag 7 void * stdcall(void *fn, int32 count, ...) { uintptr *a; StdcallParams p; p.fn = fn; a = (uintptr*)(&count + 1); while(count > 0) { count--; p.args[count] = a[count]; } syscall(&p); return (void*)(p.r); } void call_syscall(void *args) { StdcallParams *p = (StdcallParams*)args; p->r = (uintptr)stdcall_raw((void*)p->fn, p->args[0], p->args[1], p->args[2], p->args[3], p->args[4], p->args[5], p->args[6], p->args[7], p->args[8], p->args[9], p->args[10], p->args[11]); p->err = (uintptr)stdcall_raw(GetLastError); return; }