forgotten commit. disabled until egl is adapted.
[AROS-Contrib.git] / regina / mt_win32.h
blobd679a3dc7f40e0bdbb2083ca71bf6be31fdebe3f
1 /* This is the supporting header file for WIN32 threads.
2 * Checked with MSVC 6.0.
3 * We need the following globals:
5 * 1) THREAD_PROTECT(varname)
6 * = a pseudo code NOT TERMINATED BY A SEMICOLON. After this point all
7 * code until a THREAD_UNPROTECT is executed by one thread at once.
8 * This may be done by a call to a semaphore action or something else.
9 * THREAD_PROTECT and THREAD_UNPROTECT define a C block logically.
10 * varname ist a variable created by PROTECTION_VAR()
11 * 2) THREAD_UNPROTECT(varname)
12 * = see above
13 * 3) PROTECTION_VAR(varname)
14 * = a pseudo code NOT TERMINATED BY A SEMICOLON. This define will
15 * create and initialize a local variable which may be used by
16 * THREAD_PROTECT and THREAD_UNPROTECT.
17 * Typical examples are the protection of static local variables.
18 * 4) GLOBAL_PROTECTION_VAR(varname)
19 * = a pseudo code NOT TERMINATED BY A SEMICOLON. This define will
20 * create and initialize a global variable which may be used by
21 * THREAD_PROTECT and THREAD_UNPROTECT.
22 * Typical examples are the usage of the parser or global variables
23 * like macro_serialno.
24 * 5) EXPORT_GLOBAL_PROTECTION_VAR(varname)
25 * = a pseudo code NOT TERMINATED BY A SEMICOLON. This define will
26 * export the varname in header files. There must exist one declaration
27 * of the variable done by GLOBAL_PROTECTION_VAR.
28 * 6) GLOBAL_ENTRY_POINT()
29 * = initializes the process specific data and the thread specific data.
30 * This pseudo function is only called by those functions which are
31 * external (rexxsaa.h).
32 * It should return (tsd_t *) of the current thread.
33 * 7) __regina_get_tsd()
34 * = pointer to a variable of type tsd_t.
35 * This may only exist after a GLOBAL_ENTRY_POINT()-call and must then
36 * exist.
40 #ifndef MT_H_INCLUDED
41 # error This file should included by mt.h, only.
42 #endif
44 /* We hide the mutex management to fasten up the compilation step. I
45 * don't want to include every special stuff here.
47 void ReginaSetMutex(void **mutex);
48 void ReginaUnsetMutex(void **mutex);
50 #ifdef __MINGW32__
51 # include <excpt.h>
52 static EXCEPTION_DISPOSITION myHandler( struct _EXCEPTION_RECORD *p1, void *p2, struct _CONTEXT *p3, void *p4 ) {
53 fprintf( stderr, "\nMinGW Exception handler\n" );
54 return ExceptionCollidedUnwind;
56 typedef struct _EXCEPTION_REGISTRATION_TAG {
57 void *prev;
58 void *handler;
59 } _EXCEPTION_REGISTRATION;
60 static _EXCEPTION_REGISTRATION er_EXCEPTION_REGISTRATION;
61 # define __tryVK(pHandler) \
62 er_EXCEPTION_REGISTRATION.handler = pHandler; \
63 __asm__ ( "movl %%fs:0,%%eax;movl %%eax,%0" : : "g" (er_EXCEPTION_REGISTRATION.prev) ); \
64 __asm__ ( "leal %0,%%eax;movl %%eax,%%fs:0" : : "g" (er_EXCEPTION_REGISTRATION) );
65 # define __exceptVK \
66 __asm__ ( "movl %0,%%eax;movl %%eax,%%fs:0;" : : "g" (er_EXCEPTION_REGISTRATION.prev) );
67 # define THREAD_PROTECT(varname) __tryVK( myHandler ) ReginaSetMutex(&varname);
68 # define THREAD_UNPROTECT(varname) __exceptVK ReginaUnsetMutex(&varname);
69 #else
70 # define THREAD_PROTECT(varname) __try { ReginaSetMutex(&varname);
71 # define THREAD_UNPROTECT(varname) } __finally { ReginaUnsetMutex(&varname); }
72 #endif
74 #define PROTECTION_VAR(varname) static void * varname = NULL;
76 #define EXPORT_GLOBAL_PROTECTION_VAR(varname) extern void *varname;
77 #define GLOBAL_PROTECTION_VAR(varname) void *varname;
79 tsd_t *ReginaInitializeThread(void);
80 #define GLOBAL_ENTRY_POINT() ReginaInitializeThread()
82 /* we need a pointer to tsd_t sometimes: */
83 tsd_t *__regina_get_tsd(void);
85 /* NEVER USE __regina_get_tsd() IF YOU CAN GET THE VALUE FROM SOMEWHERE ELSE.
86 * IT REDUCES THE EXECUTION SPEED SIGNIFICANTLY. TAKE THE VALUE FROM THE CALLER
87 * WHERE IT IS POSSIBLE.