GCC + Threads on Win32 - best gcc results yet
[p5sagit/p5-mst-13.2.git] / win32 / win32thread.c
1 #include "EXTERN.h"
2 #include "perl.h"
3
4 #ifdef USE_DECLSPEC_THREAD
5 __declspec(thread) struct perl_thread *Perl_current_thread = NULL;
6 #endif
7
8 void
9 Perl_setTHR(struct perl_thread *t)
10 {
11 #ifdef USE_DECLSPEC_THREAD
12  Perl_current_thread = t;
13 #else
14  TlsSetValue(thr_key,t);
15 #endif
16 }
17
18 struct perl_thread *
19 Perl_getTHR(void)
20 {
21 #ifdef USE_DECLSPEC_THREAD
22  return Perl_current_thread;
23 #else
24  return (struct perl_thread *) TlsGetValue(thr_key);
25 #endif
26 }
27
28 void
29 Perl_alloc_thread_key(void)
30 {
31 #ifdef USE_THREADS
32     static int key_allocated = 0;
33     if (!key_allocated) {
34         if ((thr_key = TlsAlloc()) == TLS_OUT_OF_INDEXES)
35             croak("panic: TlsAlloc");
36         key_allocated = 1;
37     }
38 #endif
39 }
40
41 void
42 Perl_set_thread_self(struct perl_thread *thr)
43 {
44 #ifdef USE_THREADS
45     /* Set thr->self.  GetCurrentThread() retrurns a pseudo handle, need
46        this to convert it into a handle another thread can use.
47      */
48     DuplicateHandle(GetCurrentProcess(),
49                     GetCurrentThread(),
50                     GetCurrentProcess(),
51                     &thr->self,
52                     0,
53                     FALSE,
54                     DUPLICATE_SAME_ACCESS);
55 #endif
56 }
57
58 #ifdef USE_THREADS
59 int
60 Perl_thread_create(struct perl_thread *thr, thread_func_t *fn)
61 {
62     DWORD junk;
63
64     MUTEX_LOCK(&thr->mutex);
65     DEBUG_L(PerlIO_printf(PerlIO_stderr(),
66                           "%p: create OS thread\n", thr));
67     thr->self = CreateThread(NULL, 0, fn, (void*)thr, 0, &junk);
68     DEBUG_L(PerlIO_printf(PerlIO_stderr(),
69                           "%p: OS thread = %p, id=%ld\n", thr, thr->self, junk));
70     MUTEX_UNLOCK(&thr->mutex);
71     return thr->self ? 0 : -1;
72 }
73 #endif