summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Ing-Simmons <nik@tiuk.ti.com>1997-11-01 00:08:33 +0000
committerNick Ing-Simmons <nik@tiuk.ti.com>1997-11-01 00:08:33 +0000
commitf890e7c81bc0e52bedc3dcefbcd144d0750c257d (patch)
treef44bf2f24301f0252ec706eb11be1e0315784a18
parentbf3d9ec563d250542a3477e399206648d90ace80 (diff)
downloadperl-f890e7c81bc0e52bedc3dcefbcd144d0750c257d.tar.gz
win32thread.* not in MANIFEST which has muddled moving
back and forth between depots. p4raw-id: //depot/ansiperl@198
-rw-r--r--MANIFEST2
-rw-r--r--win32/win32thread.c15
-rw-r--r--win32/win32thread.h81
3 files changed, 65 insertions, 33 deletions
diff --git a/MANIFEST b/MANIFEST
index 171d7512d2..6c6780cd25 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -885,6 +885,8 @@ win32/win32io.c Win32 port
win32/win32io.h Win32 port
win32/win32iop.h Win32 port
win32/win32sck.c Win32 port
+win32/win32thread.h Win32 port mapping to threads
+win32/win32thread.c Win32 functions for threads
writemain.SH Generate perlmain.c from miniperlmain.c+extensions
x2p/EXTERN.h Same as above
x2p/INTERN.h Same as above
diff --git a/win32/win32thread.c b/win32/win32thread.c
index 9f63d178f4..f93d5e3585 100644
--- a/win32/win32thread.c
+++ b/win32/win32thread.c
@@ -1,10 +1,11 @@
#include "EXTERN.h"
#include "perl.h"
-#include "win32/win32thread.h"
void
init_thread_intern(struct thread *thr)
{
+#ifdef USE_THREADS
+ static int key_allocated = 0;
DuplicateHandle(GetCurrentProcess(),
GetCurrentThread(),
GetCurrentProcess(),
@@ -12,14 +13,19 @@ init_thread_intern(struct thread *thr)
0,
FALSE,
DUPLICATE_SAME_ACCESS);
- if ((thr_key = TlsAlloc()) == TLS_OUT_OF_INDEXES)
- croak("panic: TlsAlloc");
+ if (!key_allocated) {
+ if ((thr_key = TlsAlloc()) == TLS_OUT_OF_INDEXES)
+ croak("panic: TlsAlloc");
+ key_allocated = 1;
+ }
if (TlsSetValue(thr_key, (LPVOID) thr) != TRUE)
croak("panic: TlsSetValue");
+#endif
}
+#ifdef USE_THREADS
int
-thread_create(struct thread *thr, THREAD_RET_TYPE (*fn)(void *))
+Perl_thread_create(struct thread *thr, thread_func_t *fn)
{
DWORD junk;
@@ -28,3 +34,4 @@ thread_create(struct thread *thr, THREAD_RET_TYPE (*fn)(void *))
MUTEX_UNLOCK(&thr->mutex);
return thr->self ? 0 : -1;
}
+#endif
diff --git a/win32/win32thread.h b/win32/win32thread.h
index ab0dbc598f..da7c852756 100644
--- a/win32/win32thread.h
+++ b/win32/win32thread.h
@@ -1,6 +1,6 @@
-/*typedef CRITICAL_SECTION perl_mutex;*/
-typedef HANDLE perl_mutex;
-typedef HANDLE perl_cond;
+#ifndef _WIN32THREAD_H
+#define _WIN32THREAD_H
+typedef struct win32_cond { LONG waiters; HANDLE sem; } perl_cond;
typedef DWORD perl_key;
typedef HANDLE perl_thread;
@@ -8,12 +8,15 @@ typedef HANDLE perl_thread;
* but can't be communicated to child processes, and can't get
* HANDLE to it for use elsewhere
*/
-/*
+
+#ifndef DONT_USE_CRITICAL_SECTION
+typedef CRITICAL_SECTION perl_mutex;
#define MUTEX_INIT(m) InitializeCriticalSection(m)
#define MUTEX_LOCK(m) EnterCriticalSection(m)
#define MUTEX_UNLOCK(m) LeaveCriticalSection(m)
#define MUTEX_DESTROY(m) DeleteCriticalSection(m)
-*/
+#else
+typedef HANDLE perl_mutex;
#define MUTEX_INIT(m) \
STMT_START { \
@@ -36,38 +39,51 @@ typedef HANDLE perl_thread;
croak("panic: MUTEX_DESTROY"); \
} STMT_END
+#endif
+
+/* These macros assume that the mutex associated with the condition
+ * will always be held before COND_{SIGNAL,BROADCAST,WAIT,DESTROY},
+ * so there's no separate mutex protecting access to (c)->waiters
+ */
#define COND_INIT(c) \
- STMT_START { \
- if ((*(c) = CreateEvent(NULL,TRUE,FALSE,NULL)) == NULL) \
- croak("panic: COND_INIT"); \
+ STMT_START { \
+ (c)->waiters = 0; \
+ (c)->sem = CreateSemaphore(NULL,0,LONG_MAX,NULL); \
+ if ((c)->sem == NULL) \
+ croak("panic: COND_INIT (%ld)",GetLastError()); \
} STMT_END
+
#define COND_SIGNAL(c) \
- STMT_START { \
- if (PulseEvent(*(c)) == 0) \
- croak("panic: COND_SIGNAL (%ld)",GetLastError()); \
+ STMT_START { \
+ if (ReleaseSemaphore((c)->sem,1,NULL) == 0) \
+ croak("panic: COND_SIGNAL (%ld)",GetLastError()); \
} STMT_END
+
#define COND_BROADCAST(c) \
- STMT_START { \
- if (PulseEvent(*(c)) == 0) \
- croak("panic: COND_BROADCAST"); \
+ STMT_START { \
+ if ((c)->waiters > 0 && \
+ ReleaseSemaphore((c)->sem,(c)->waiters,NULL) == 0) \
+ croak("panic: COND_BROADCAST (%ld)",GetLastError());\
} STMT_END
-/* #define COND_WAIT(c, m) \
- STMT_START { \
- if (WaitForSingleObject(*(c),INFINITE) == WAIT_FAILED) \
- croak("panic: COND_WAIT"); \
- } STMT_END
-*/
+
#define COND_WAIT(c, m) \
- STMT_START { \
- if (SignalObjectAndWait(*(m),*(c),INFINITE,FALSE) == WAIT_FAILED)\
- croak("panic: COND_WAIT"); \
- else \
- MUTEX_LOCK(m); \
+ STMT_START { \
+ (c)->waiters++; \
+ MUTEX_UNLOCK(m); \
+ /* Note that there's no race here, since a \
+ * COND_BROADCAST() on another thread will have seen the\
+ * right number of waiters (i.e. including this one) */ \
+ if (WaitForSingleObject((c)->sem,INFINITE)==WAIT_FAILED)\
+ croak("panic: COND_WAIT (%ld)",GetLastError()); \
+ MUTEX_LOCK(m); \
+ (c)->waiters--; \
} STMT_END
+
#define COND_DESTROY(c) \
- STMT_START { \
- if (CloseHandle(*(c)) == 0) \
- croak("panic: COND_DESTROY"); \
+ STMT_START { \
+ (c)->waiters = 0; \
+ if (CloseHandle((c)->sem) == 0) \
+ croak("panic: COND_DESTROY (%ld)",GetLastError()); \
} STMT_END
#define DETACH(t) \
@@ -81,6 +97,7 @@ typedef HANDLE perl_thread;
#define THR ((struct thread *) TlsGetValue(thr_key))
#define HAVE_THREAD_INTERN
+void init_thread_intern _((struct thread *thr));
#define JOIN(t, avp) \
STMT_START { \
@@ -95,8 +112,14 @@ typedef HANDLE perl_thread;
croak("panic: TlsSetValue"); \
} STMT_END
-#define THREAD_CREATE(t, f) thread_create(t, f)
+#define THREAD_CREATE(t, f) Perl_thread_create(t, f)
#define THREAD_POST_CREATE(t) NOOP
#define THREAD_RET_TYPE DWORD WINAPI
#define THREAD_RET_CAST(p) ((DWORD)(p))
#define YIELD Sleep(0)
+
+typedef THREAD_RET_TYPE thread_func_t(void *);
+
+int Perl_thread_create _((struct thread *thr, thread_func_t *fn));
+
+#endif /* _WIN32THREAD_H */ \ No newline at end of file