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 }