github.com/miolini/go@v0.0.0-20160405192216-fca68c8cb408/src/runtime/cgo/gcc_libinit_windows.c (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build cgo 6 #define WIN64_LEAN_AND_MEAN 7 #include <windows.h> 8 #include <process.h> 9 10 #include <stdio.h> 11 #include <stdlib.h> 12 13 static volatile long runtime_init_once_gate = 0; 14 static volatile long runtime_init_once_done = 0; 15 16 static CRITICAL_SECTION runtime_init_cs; 17 18 static HANDLE runtime_init_wait; 19 static int runtime_init_done; 20 21 // Pre-initialize the runtime synchronization objects 22 void 23 _cgo_preinit_init() { 24 runtime_init_wait = CreateEvent(NULL, TRUE, FALSE, NULL); 25 if (runtime_init_wait == NULL) { 26 fprintf(stderr, "runtime: failed to create runtime initialization wait event.\n"); 27 abort(); 28 } 29 30 InitializeCriticalSection(&runtime_init_cs); 31 } 32 33 // Make sure that the preinit sequence has run. 34 void 35 _cgo_maybe_run_preinit() { 36 if (!InterlockedExchangeAdd(&runtime_init_once_done, 0)) { 37 if (InterlockedIncrement(&runtime_init_once_gate) == 1) { 38 _cgo_preinit_init(); 39 InterlockedIncrement(&runtime_init_once_done); 40 } else { 41 // Decrement to avoid overflow. 42 InterlockedDecrement(&runtime_init_once_gate); 43 while(!InterlockedExchangeAdd(&runtime_init_once_done, 0)) { 44 Sleep(0); 45 } 46 } 47 } 48 } 49 50 void 51 x_cgo_sys_thread_create(void (*func)(void*), void* arg) { 52 uintptr_t thandle; 53 54 thandle = _beginthread(func, 0, arg); 55 if(thandle == -1) { 56 fprintf(stderr, "runtime: failed to create new OS thread (%d)\n", errno); 57 abort(); 58 } 59 } 60 61 int 62 _cgo_is_runtime_initialized() { 63 EnterCriticalSection(&runtime_init_cs); 64 int status = runtime_init_done; 65 LeaveCriticalSection(&runtime_init_cs); 66 return status; 67 } 68 69 void 70 _cgo_wait_runtime_init_done() { 71 _cgo_maybe_run_preinit(); 72 while (!_cgo_is_runtime_initialized()) { 73 WaitForSingleObject(runtime_init_wait, INFINITE); 74 } 75 } 76 77 void 78 x_cgo_notify_runtime_init_done(void* dummy) { 79 _cgo_maybe_run_preinit(); 80 81 EnterCriticalSection(&runtime_init_cs); 82 runtime_init_done = 1; 83 LeaveCriticalSection(&runtime_init_cs); 84 85 if (!SetEvent(runtime_init_wait)) { 86 fprintf(stderr, "runtime: failed to signal runtime initialization complete.\n"); 87 abort(); 88 } 89 } 90