Changeset 57
- Timestamp:
- 12/07/08 06:33:12 (16 years ago)
- Files:
-
- trunk/src/common/core/thread.d (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/common/core/thread.d
r43 r57 85 85 private 86 86 { 87 87 import core.stdc.stdint : uintptr_t; // for _beginthreadex decl below 88 88 import core.sys.windows.windows; 89 89 90 90 const DWORD TLS_OUT_OF_INDEXES = 0xFFFFFFFF; 91 91 92 92 extern (Windows) alias uint function(void*) btex_fptr; 93 93 extern (C) uintptr_t _beginthreadex(void*, uint, btex_fptr, void*, uint, uint*); 94 94 95 /* The memory between the addresses of _tlsstart and _tlsend 96 * lies all the implicit thread local storage variables for this 97 * thread for this module. 98 * Both are declared in \dm\src\win32\tlsseg.asm 99 */ 100 extern (C) 101 { 102 extern __thread int _tlsstart; 103 extern __thread int _tlsend; 104 } 95 105 96 106 // 97 107 // entry point for Windows threads 98 108 // 99 109 extern (Windows) uint thread_entryPoint( void* arg ) 100 110 { 101 111 Thread obj = cast(Thread) arg; 102 112 assert( obj ); 103 113 scope( exit ) Thread.remove( obj ); 104 114 105 115 assert( obj.m_curr is &obj.m_main ); 106 116 obj.m_main.bstack = getStackBottom(); 107 117 obj.m_main.tstack = obj.m_main.bstack; 108 118 Thread.add( &obj.m_main ); 109 119 Thread.setThis( obj ); 110 120 121 /* Save the bounds of the TLS data block 122 */ 123 void* pstart = cast(void*)&_tlsstart; 124 void* pend = cast(void*)&_tlsend; 125 obj.m_tls = pstart[0 .. pend - pstart]; 126 111 127 // NOTE: No GC allocations may occur until the stack pointers have 112 128 // been set and Thread.getThis returns a valid reference to 113 129 // this thread object (this latter condition is not strictly 114 130 // necessary on Windows but it should be followed for the 115 131 // sake of consistency). 116 132 117 133 // TODO: Consider putting an auto exception object here (using 118 134 // alloca) forOutOfMemoryError plus something to track 119 135 // whether an exception is in-flight? 120 136 … … 156 172 import core.sys.posix.signal; 157 173 import core.sys.posix.time; 158 174 import core.stdc.errno; 159 175 160 176 extern (C) int getErrno(); 161 177 162 178 version( GNU ) 163 179 { 164 180 import gcc.builtins; 165 181 } 182 183 /* The memory between the addresses of _tlsstart and _tlsend 184 * lies all the implicit thread local storage variables for this 185 * thread for this module. 186 * These two are magically allocated by the compiler so that 187 * they will bracket the .tdata and .tbss segments. 188 * See elfobj.c in the dmd compiler source for details. 189 */ 190 extern (C) 191 { 192 __thread int _tlsstart; 193 __thread int _tlsend; 194 } 166 195 167 196 168 197 // 169 198 // entry point for POSIX threads 170 199 // 171 200 extern (C) void* thread_entryPoint( void* arg ) 172 201 { 173 202 Thread obj = cast(Thread) arg; 174 203 assert( obj ); 175 204 scope( exit ) … … 232 261 obj.m_main.bstack = getBasePtr(); 233 262 } 234 263 else version( StackGrowsDown ) 235 264 obj.m_main.bstack = &obj + 1; 236 265 else 237 266 obj.m_main.bstack = &obj; 238 267 obj.m_main.tstack = obj.m_main.bstack; 239 268 assert( obj.m_curr == &obj.m_main ); 240 269 Thread.add( &obj.m_main ); 241 270 Thread.setThis( obj ); 271 272 /* Save the bounds of the TLS data block 273 */ 274 void* pstart = cast(void*)&_tlsstart; 275 void* pend = cast(void*)&_tlsend; 276 obj.m_tls = pstart[0 .. pend - pstart]; 277 242 278 243 279 // NOTE: No GC allocations may occur until the stack pointers have 244 280 // been set and Thread.getThis returns a valid reference to 245 281 // this thread object (this latter condition is not strictly 246 282 // necessary on Windows but it should be followed for the 247 283 // sake of consistency). 248 284 249 285 // TODO: Consider putting an auto exception object here (using 250 286 // alloca) forOutOfMemoryError plus something to track 251 287 // whether an exception is in-flight? … … 1113 1149 1114 1150 private: 1115 1151 // 1116 1152 // Initializes a thread object which has no associated executable function. 1117 1153 // This is used for the main thread initialized in thread_init(). 1118 1154 // 1119 1155 this() 1120 1156 { 1121 1157 m_call = Call.NO; 1122 1158 m_curr = &m_main; 1159 1160 void* pstart = cast(void*)&_tlsstart; 1161 void* pend = cast(void*)&_tlsend; 1162 m_tls = pstart[0 .. pend - pstart]; 1123 1163 } 1124 1164 1125 1165 1126 1166 // 1127 1167 // Thread entry point. Invokes the function or delegate passed on 1128 1168 // construction (if any). 1129 1169 // 1130 1170 final void run() 1131 1171 { 1132 1172 switch( m_call ) … … 1273 1313 tstack; 1274 1314 Context* within; 1275 1315 Context* next, 1276 1316 prev; 1277 1317 } 1278 1318 1279 1319 1280 1320 Context m_main; 1281 1321 Context* m_curr; 1282 1322 bool m_lock; 1323 void[] m_tls; // spans implicit thread local storage 1283 1324 1284 1325 version( Windows ) 1285 1326 { 1286 1327 uint[8] m_reg; // edi,esi,ebp,esp,ebx,edx,ecx,eax 1287 1328 } 1288 1329 1289 1330 1290 1331 private: 1291 1332 /////////////////////////////////////////////////////////////////////////// 1292 1333 // GC Scanning Support … … 1960 2001 // so don't do the "+1" for StackGrowsDown. 1961 2002 if( c.tstack && c.tstack < c.bstack ) 1962 2003 scan( c.tstack, c.bstack ); 1963 2004 } 1964 2005 else 1965 2006 { 1966 2007 if( c.bstack && c.bstack < c.tstack ) 1967 2008 scan( c.bstack, c.tstack + 1 ); 1968 2009 } 1969 2010 } 1970 version( Windows ) 1971 { 1972 for( Thread t = Thread.sm_tbeg; t; t = t.next ) 1973 { 2011 2012 for( Thread t = Thread.sm_tbeg; t; t = t.next ) 2013 { 2014 /* Scan thread local storage. 2015 * The BUG here is that the tls for other modules 2016 * is not scanned. 2017 */ 2018 scan( t.m_tls.ptr, t.m_tls.ptr + t.m_tls.length ); 2019 2020 version (Windows) 1974 2021 scan( &t.m_reg[0], &t.m_reg[0] + t.m_reg.length ); 1975 }1976 2022 } 1977 2023 } 1978 2024 1979 2025 1980 2026 /////////////////////////////////////////////////////////////////////////////// 1981 2027 // Thread Local 1982 2028 /////////////////////////////////////////////////////////////////////////////// 1983 2029 1984 2030 1985 2031 /**
