Mercurial > projects > ldc
comparison tango/tango/core/Thread.di @ 132:1700239cab2e trunk
[svn r136] MAJOR UNSTABLE UPDATE!!!
Initial commit after moving to Tango instead of Phobos.
Lots of bugfixes...
This build is not suitable for most things.
author | lindquist |
---|---|
date | Fri, 11 Jan 2008 17:57:40 +0100 |
parents | |
children | f5ca6bbbf1d7 |
comparison
equal
deleted
inserted
replaced
131:5825d48b27d1 | 132:1700239cab2e |
---|---|
1 // D import file generated from 'core/Thread.d' | |
2 module tango.core.Thread; | |
3 version = StackGrowsDown; | |
4 public | |
5 { | |
6 } | |
7 private | |
8 { | |
9 import tango.core.Exception; | |
10 extern (C) | |
11 { | |
12 void* rt_stackBottom(); | |
13 } | |
14 extern (C) | |
15 { | |
16 void* rt_stackTop(); | |
17 } | |
18 void* getStackBottom() | |
19 { | |
20 return rt_stackBottom(); | |
21 } | |
22 void* getStackTop(); | |
23 } | |
24 version (Win32) | |
25 { | |
26 private | |
27 { | |
28 import tango.stdc.stdint; | |
29 import tango.sys.win32.UserGdi; | |
30 const | |
31 { | |
32 DWORD TLS_OUT_OF_INDEXES = -1u; | |
33 } | |
34 extern (Windows) | |
35 { | |
36 alias uint(* btex_fptr)(void*); | |
37 } | |
38 extern (C) | |
39 { | |
40 uintptr_t _beginthreadex(void*, uint, btex_fptr, void*, uint, uint*); | |
41 } | |
42 extern (Windows) | |
43 { | |
44 uint thread_entryPoint(void* arg); | |
45 } | |
46 HANDLE GetCurrentThreadHandle() | |
47 { | |
48 const uint DUPLICATE_SAME_ACCESS = 2; | |
49 HANDLE curr = GetCurrentThread(); | |
50 HANDLE proc = GetCurrentProcess(); | |
51 HANDLE hndl; | |
52 DuplicateHandle(proc,curr,proc,&hndl,0,TRUE,DUPLICATE_SAME_ACCESS); | |
53 return hndl; | |
54 } | |
55 } | |
56 } | |
57 else | |
58 { | |
59 version (Posix) | |
60 { | |
61 private | |
62 { | |
63 import tango.stdc.posix.semaphore; | |
64 import tango.stdc.posix.pthread; | |
65 import tango.stdc.posix.signal; | |
66 import tango.stdc.posix.time; | |
67 import tango.stdc.errno; | |
68 extern (C) | |
69 { | |
70 int getErrno(); | |
71 } | |
72 version (GNU) | |
73 { | |
74 import gcc.builtins; | |
75 } | |
76 extern (C) | |
77 { | |
78 void* thread_entryPoint(void* arg); | |
79 } | |
80 sem_t suspendCount; | |
81 extern (C) | |
82 { | |
83 void thread_suspendHandler(int sig); | |
84 } | |
85 extern (C) | |
86 { | |
87 void thread_resumeHandler(int sig) | |
88 in | |
89 { | |
90 assert(sig == SIGUSR2); | |
91 } | |
92 body | |
93 { | |
94 } | |
95 } | |
96 } | |
97 } | |
98 else | |
99 { | |
100 static assert(false,"Unknown threading implementation."); | |
101 } | |
102 } | |
103 class Thread | |
104 { | |
105 this(void(* fn)(), size_t sz = 0) | |
106 in | |
107 { | |
108 assert(fn); | |
109 } | |
110 body | |
111 { | |
112 m_fn = fn; | |
113 m_sz = sz; | |
114 m_call = Call.FN; | |
115 m_curr = &m_main; | |
116 } | |
117 this(void delegate() dg, size_t sz = 0) | |
118 in | |
119 { | |
120 assert(dg); | |
121 } | |
122 body | |
123 { | |
124 m_dg = dg; | |
125 m_sz = sz; | |
126 m_call = Call.DG; | |
127 m_curr = &m_main; | |
128 } | |
129 final | |
130 { | |
131 void start(); | |
132 } | |
133 final | |
134 { | |
135 void join(bool rethrow = true); | |
136 } | |
137 final | |
138 { | |
139 char[] name(); | |
140 } | |
141 final | |
142 { | |
143 void name(char[] val); | |
144 } | |
145 final | |
146 { | |
147 bool isDaemon(); | |
148 } | |
149 final | |
150 { | |
151 void isDaemon(bool val); | |
152 } | |
153 final | |
154 { | |
155 bool isRunning(); | |
156 } | |
157 static const | |
158 { | |
159 int PRIORITY_MIN; | |
160 } | |
161 static const | |
162 { | |
163 int PRIORITY_MAX; | |
164 } | |
165 final | |
166 { | |
167 int priority(); | |
168 } | |
169 final | |
170 { | |
171 void priority(int val); | |
172 } | |
173 static | |
174 { | |
175 void sleep(double period); | |
176 } | |
177 static | |
178 { | |
179 void yield(); | |
180 } | |
181 static | |
182 { | |
183 Thread getThis(); | |
184 } | |
185 static | |
186 { | |
187 Thread[] getAll(); | |
188 } | |
189 static | |
190 { | |
191 int opApply(int delegate(ref Thread) dg); | |
192 } | |
193 static const | |
194 { | |
195 uint LOCAL_MAX = 64; | |
196 } | |
197 static | |
198 { | |
199 uint createLocal(); | |
200 } | |
201 static | |
202 { | |
203 void deleteLocal(uint key); | |
204 } | |
205 static | |
206 { | |
207 void* getLocal(uint key) | |
208 { | |
209 return getThis().m_local[key]; | |
210 } | |
211 } | |
212 static | |
213 { | |
214 void* setLocal(uint key, void* val) | |
215 { | |
216 return getThis().m_local[key] = val; | |
217 } | |
218 } | |
219 static this(); | |
220 private | |
221 { | |
222 this() | |
223 { | |
224 m_call = Call.NO; | |
225 m_curr = &m_main; | |
226 } | |
227 final | |
228 { | |
229 void run(); | |
230 } | |
231 private | |
232 { | |
233 enum Call | |
234 { | |
235 NO, | |
236 FN, | |
237 DG, | |
238 } | |
239 version (Win32) | |
240 { | |
241 alias uint TLSKey; | |
242 alias uint ThreadAddr; | |
243 } | |
244 else | |
245 { | |
246 version (Posix) | |
247 { | |
248 alias pthread_key_t TLSKey; | |
249 alias pthread_t ThreadAddr; | |
250 } | |
251 } | |
252 static | |
253 { | |
254 bool[LOCAL_MAX] sm_local; | |
255 } | |
256 static | |
257 { | |
258 TLSKey sm_this; | |
259 } | |
260 void*[LOCAL_MAX] m_local; | |
261 version (Win32) | |
262 { | |
263 HANDLE m_hndl; | |
264 } | |
265 ThreadAddr m_addr; | |
266 Call m_call; | |
267 char[] m_name; | |
268 union | |
269 { | |
270 void(* m_fn)(); | |
271 void delegate() m_dg; | |
272 } | |
273 size_t m_sz; | |
274 version (Posix) | |
275 { | |
276 bool m_isRunning; | |
277 } | |
278 bool m_isDaemon; | |
279 Object m_unhandled; | |
280 private | |
281 { | |
282 static | |
283 { | |
284 void setThis(Thread t); | |
285 } | |
286 private | |
287 { | |
288 final | |
289 { | |
290 void pushContext(Context* c) | |
291 in | |
292 { | |
293 assert(!c.within); | |
294 } | |
295 body | |
296 { | |
297 c.within = m_curr; | |
298 m_curr = c; | |
299 } | |
300 } | |
301 final | |
302 { | |
303 void popContext() | |
304 in | |
305 { | |
306 assert(m_curr && m_curr.within); | |
307 } | |
308 body | |
309 { | |
310 Context* c = m_curr; | |
311 m_curr = c.within; | |
312 c.within = null; | |
313 } | |
314 } | |
315 final | |
316 { | |
317 Context* topContext() | |
318 in | |
319 { | |
320 assert(m_curr); | |
321 } | |
322 body | |
323 { | |
324 return m_curr; | |
325 } | |
326 } | |
327 static | |
328 { | |
329 struct Context | |
330 { | |
331 void* bstack; | |
332 void* tstack; | |
333 Context* within; | |
334 Context* next; | |
335 Context* prev; | |
336 } | |
337 } | |
338 Context m_main; | |
339 Context* m_curr; | |
340 bool m_lock; | |
341 version (Win32) | |
342 { | |
343 uint[8] m_reg; | |
344 } | |
345 private | |
346 { | |
347 static | |
348 { | |
349 Object slock() | |
350 { | |
351 return Thread.classinfo; | |
352 } | |
353 } | |
354 static | |
355 { | |
356 Context* sm_cbeg; | |
357 } | |
358 static | |
359 { | |
360 size_t sm_clen; | |
361 } | |
362 static | |
363 { | |
364 Thread sm_tbeg; | |
365 } | |
366 static | |
367 { | |
368 size_t sm_tlen; | |
369 } | |
370 Thread prev; | |
371 Thread next; | |
372 static | |
373 { | |
374 void add(Context* c); | |
375 } | |
376 static | |
377 { | |
378 void remove(Context* c); | |
379 } | |
380 static | |
381 { | |
382 void add(Thread t); | |
383 } | |
384 static | |
385 { | |
386 void remove(Thread t); | |
387 } | |
388 } | |
389 } | |
390 } | |
391 } | |
392 } | |
393 } | |
394 extern (C) | |
395 { | |
396 void thread_init(); | |
397 } | |
398 extern (C) | |
399 { | |
400 void thread_attachThis(); | |
401 } | |
402 extern (C) | |
403 { | |
404 void thread_detachThis() | |
405 { | |
406 Thread.remove(Thread.getThis()); | |
407 } | |
408 } | |
409 extern (C) | |
410 { | |
411 void thread_joinAll(); | |
412 } | |
413 private | |
414 { | |
415 bool multiThreadedFlag = false; | |
416 } | |
417 extern (C) | |
418 { | |
419 bool thread_needLock() | |
420 { | |
421 return multiThreadedFlag; | |
422 } | |
423 } | |
424 private | |
425 { | |
426 uint suspendDepth = 0; | |
427 } | |
428 extern (C) | |
429 { | |
430 void thread_suspendAll(); | |
431 } | |
432 extern (C) | |
433 { | |
434 void thread_resumeAll(); | |
435 } | |
436 private | |
437 { | |
438 alias void delegate(void*, void*) scanAllThreadsFn; | |
439 } | |
440 extern (C) | |
441 { | |
442 void thread_scanAll(scanAllThreadsFn scan, void* curStackTop = null); | |
443 } | |
444 template ThreadLocal(T) | |
445 { | |
446 class ThreadLocal | |
447 { | |
448 this(T def = T.init) | |
449 { | |
450 m_def = def; | |
451 m_key = Thread.createLocal(); | |
452 } | |
453 T val() | |
454 { | |
455 Wrap* wrap = cast(Wrap*)Thread.getLocal(m_key); | |
456 return wrap ? wrap.val : m_def; | |
457 } | |
458 T val(T newval) | |
459 { | |
460 Wrap* wrap = cast(Wrap*)Thread.getLocal(m_key); | |
461 if (wrap is null) | |
462 { | |
463 wrap = new Wrap; | |
464 Thread.setLocal(m_key,wrap); | |
465 } | |
466 wrap.val = newval; | |
467 return newval; | |
468 } | |
469 private | |
470 { | |
471 struct Wrap | |
472 { | |
473 T val; | |
474 } | |
475 T m_def; | |
476 uint m_key; | |
477 } | |
478 } | |
479 } | |
480 class ThreadGroup | |
481 { | |
482 final | |
483 { | |
484 Thread create(void(* fn)()); | |
485 } | |
486 final | |
487 { | |
488 Thread create(void delegate() dg); | |
489 } | |
490 final | |
491 { | |
492 void add(Thread t); | |
493 } | |
494 final | |
495 { | |
496 void remove(Thread t); | |
497 } | |
498 final | |
499 { | |
500 int opApply(int delegate(ref Thread) dg); | |
501 } | |
502 final | |
503 { | |
504 void joinAll(bool rethrow = true); | |
505 } | |
506 private | |
507 { | |
508 Thread[Thread] m_all; | |
509 } | |
510 } | |
511 private | |
512 { | |
513 version (D_InlineAsm_X86) | |
514 { | |
515 version (X86_64) | |
516 { | |
517 } | |
518 else | |
519 { | |
520 version (Win32) | |
521 { | |
522 version = AsmX86_Win32; | |
523 } | |
524 else | |
525 { | |
526 version (Posix) | |
527 { | |
528 version = AsmX86_Posix; | |
529 } | |
530 } | |
531 } | |
532 } | |
533 else | |
534 { | |
535 version (PPC) | |
536 { | |
537 version (Posix) | |
538 { | |
539 version = AsmPPC_Posix; | |
540 } | |
541 } | |
542 } | |
543 version (Posix) | |
544 { | |
545 import tango.stdc.posix.unistd; | |
546 import tango.stdc.posix.sys.mman; | |
547 import tango.stdc.posix.stdlib; | |
548 version (AsmX86_Win32) | |
549 { | |
550 } | |
551 else | |
552 { | |
553 version (AsmX86_Posix) | |
554 { | |
555 } | |
556 else | |
557 { | |
558 version (AsmPPC_Posix) | |
559 { | |
560 } | |
561 else | |
562 { | |
563 import tango.stdc.posix.ucontext; | |
564 } | |
565 } | |
566 } | |
567 } | |
568 const | |
569 { | |
570 size_t PAGESIZE; | |
571 } | |
572 } | |
573 static this(); | |
574 private | |
575 { | |
576 extern (C) | |
577 { | |
578 void fiber_entryPoint(); | |
579 } | |
580 version (AsmPPC_Posix) | |
581 { | |
582 extern (C) | |
583 { | |
584 void fiber_switchContext(void** oldp, void* newp); | |
585 } | |
586 } | |
587 else | |
588 { | |
589 extern (C) | |
590 { | |
591 void fiber_switchContext(void** oldp, void* newp); | |
592 } | |
593 } | |
594 } | |
595 class Fiber | |
596 { | |
597 this(void(* fn)(), size_t sz = PAGESIZE) | |
598 in | |
599 { | |
600 assert(fn); | |
601 } | |
602 body | |
603 { | |
604 m_fn = fn; | |
605 m_call = Call.FN; | |
606 m_state = State.HOLD; | |
607 allocStack(sz); | |
608 initStack(); | |
609 } | |
610 this(void delegate() dg, size_t sz = PAGESIZE) | |
611 in | |
612 { | |
613 assert(dg); | |
614 } | |
615 body | |
616 { | |
617 m_dg = dg; | |
618 m_call = Call.DG; | |
619 m_state = State.HOLD; | |
620 allocStack(sz); | |
621 initStack(); | |
622 } | |
623 final | |
624 { | |
625 void call(bool rethrow = true); | |
626 } | |
627 final | |
628 { | |
629 void reset() | |
630 in | |
631 { | |
632 assert(m_state == State.TERM); | |
633 assert(m_ctxt.tstack == m_ctxt.bstack); | |
634 } | |
635 body | |
636 { | |
637 m_state = State.HOLD; | |
638 initStack(); | |
639 m_unhandled = null; | |
640 } | |
641 } | |
642 enum State | |
643 { | |
644 HOLD, | |
645 EXEC, | |
646 TERM, | |
647 } | |
648 final | |
649 { | |
650 State state() | |
651 { | |
652 return m_state; | |
653 } | |
654 } | |
655 static | |
656 { | |
657 void yield(); | |
658 } | |
659 static | |
660 { | |
661 void yieldAndThrow(Object obj); | |
662 } | |
663 static | |
664 { | |
665 Fiber getThis(); | |
666 } | |
667 static this(); | |
668 private | |
669 { | |
670 this() | |
671 { | |
672 m_call = Call.NO; | |
673 } | |
674 final | |
675 { | |
676 void run(); | |
677 } | |
678 private | |
679 { | |
680 enum Call | |
681 { | |
682 NO, | |
683 FN, | |
684 DG, | |
685 } | |
686 Call m_call; | |
687 union | |
688 { | |
689 void(* m_fn)(); | |
690 void delegate() m_dg; | |
691 } | |
692 bool m_isRunning; | |
693 Object m_unhandled; | |
694 State m_state; | |
695 private | |
696 { | |
697 final | |
698 { | |
699 void allocStack(size_t sz); | |
700 } | |
701 final | |
702 { | |
703 void freeStack(); | |
704 } | |
705 final | |
706 { | |
707 void initStack(); | |
708 } | |
709 Thread.Context* m_ctxt; | |
710 size_t m_size; | |
711 void* m_pmem; | |
712 static if(is(typeof(ucontext_t))) | |
713 { | |
714 static | |
715 { | |
716 ucontext_t sm_utxt = void; | |
717 } | |
718 ucontext_t m_utxt = void; | |
719 ucontext_t* m_ucur = null; | |
720 } | |
721 private | |
722 { | |
723 static | |
724 { | |
725 void setThis(Fiber f); | |
726 } | |
727 static | |
728 { | |
729 Thread.TLSKey sm_this; | |
730 } | |
731 private | |
732 { | |
733 final | |
734 { | |
735 void switchIn(); | |
736 } | |
737 final | |
738 { | |
739 void switchOut(); | |
740 } | |
741 } | |
742 } | |
743 } | |
744 } | |
745 } | |
746 } |