1 // GNU D Compiler thread support for emulated TLS routines. 2 // Copyright (C) 2019 Free Software Foundation, Inc. 3 4 // GCC is free software; you can redistribute it and/or modify it under 5 // the terms of the GNU General Public License as published by the Free 6 // Software Foundation; either version 3, or (at your option) any later 7 // version. 8 9 // GCC is distributed in the hope that it will be useful, but WITHOUT ANY 10 // WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 // for more details. 13 14 // Under Section 7 of GPL version 3, you are granted additional 15 // permissions described in the GCC Runtime Library Exception, version 16 // 3.1, as published by the Free Software Foundation. 17 18 // You should have received a copy of the GNU General Public License and 19 // a copy of the GCC Runtime Library Exception along with this program; 20 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 21 // <http://www.gnu.org/licenses/>. 22 23 module gcc.gthread; 24 import gcc.config; 25 26 extern (C) nothrow @nogc: 27 28 alias GthreadDestroyFn = extern (C) void function(void*); 29 alias GthreadOnceFn = extern (C) void function(); 30 31 static if (GNU_Thread_Model == ThreadModel.Posix) 32 { 33 import core.sys.posix.pthread; 34 35 alias __gthread_key_create = pthread_key_create; 36 alias __gthread_key_delete = pthread_key_delete; 37 alias __gthread_getspecific = pthread_getspecific; 38 alias __gthread_setspecific = pthread_setspecific; 39 alias __gthread_once = pthread_once; 40 alias __gthread_key_t = pthread_key_t; 41 alias __gthread_once_t = pthread_once_t; 42 enum GTHREAD_ONCE_INIT = PTHREAD_ONCE_INIT; 43 44 // TODO: FreeBSD and Solaris exposes a dummy POSIX threads 45 // interface that will need to be handled here. __gthread_active_p()46 extern (D) int __gthread_active_p() 47 { 48 return 1; 49 } 50 } 51 else static if (GNU_Thread_Model == ThreadModel.Single) 52 { 53 alias __gthread_key_t = int; 54 alias __gthread_once_t = int; 55 enum GTHREAD_ONCE_INIT = 0; 56 __gthread_key_create(__gthread_key_t *,GthreadDestroyFn)57 extern (D) int __gthread_key_create(__gthread_key_t*, GthreadDestroyFn) 58 { 59 return 0; 60 } 61 __gthread_key_delete(__gthread_key_t)62 extern (D) int __gthread_key_delete(__gthread_key_t) 63 { 64 return 0; 65 } 66 __gthread_getspecific(__gthread_key_t)67 extern (D) void* __gthread_getspecific(__gthread_key_t) 68 { 69 return null; 70 } 71 __gthread_setspecific(__gthread_key_t,void *)72 extern (D) int __gthread_setspecific(__gthread_key_t, void*) 73 { 74 return 0; 75 } 76 __gthread_once(__gthread_once_t *,GthreadOnceFn)77 extern (D) int __gthread_once(__gthread_once_t*, GthreadOnceFn) 78 { 79 return 0; 80 } 81 __gthread_active_p()82 extern (D) int __gthread_active_p() 83 { 84 return 0; 85 } 86 } 87 else static if (GNU_Thread_Model == ThreadModel.Win32) 88 { 89 struct __gthread_once_t 90 { 91 INT done; 92 LONG started; 93 } 94 95 int __gthr_win32_key_create(__gthread_key_t* keyp, GthreadDestroyFn dtor); 96 int __gthr_win32_key_delete(__gthread_key_t key); 97 void* __gthr_win32_getspecific(__gthread_key_t key); 98 int __gthr_win32_setspecific(__gthread_key_t key, const void* ptr); 99 int __gthr_win32_once(__gthread_once_t* once, GthreadOnceFn); 100 101 alias __gthread_key_create = __gthr_win32_key_create; 102 alias __gthread_key_delete = __gthr_win32_key_delete; 103 alias __gthread_getspecific = __gthr_win32_getspecific; 104 alias __gthread_setspecific = __gthr_win32_setspecific; 105 alias __gthread_once = __gthr_win32_once; 106 enum GTHREAD_ONCE_INIT = __gthread_once_t(0, -1); 107 alias __gthread_key_t = c_ulong; 108 version(MinGW)109 version (MinGW) 110 { 111 // Mingw runtime >= v0.3 provides a magic variable that is set to nonzero 112 // if -mthreads option was specified, or 0 otherwise. 113 extern __gshared int _CRT_MT; 114 } 115 __gthread_active_p()116 extern (D) int __gthread_active_p() 117 { 118 version (MinGW) 119 return _CRT_MT; 120 else 121 return 1; 122 } 123 } 124 else 125 { 126 static assert(false, "Not implemented"); 127 } 128