1 /* This is the supporting header file for WIN32 threads.
2  * Checked with MSVC 6.0.
3  * We need the following globals:
4  *
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 (RxPackageGlobalDataDef *) of the current thread.
33  * 7) __rxpack_get_tsd()
34  *    = pointer to a variable of type RxPackageGlobalDataDef.
35  *      This may only exist after a GLOBAL_ENTRY_POINT()-call and must then
36  *      exist.
37  *
38  */
39 
40 #ifndef RXMT_H_INCLUDED
41 #  error This file should included by rxmt.h, only.
42 #endif
43 
44 /* We hide the mutex management to fasten up the compilation step. I
45  * don't want to include every special stuff here.
46  */
47 void RxPackSetMutex(void **mutex);
48 void RxPackUnsetMutex(void **mutex);
49 
50 #ifdef __MINGW32__
51 # include <excpt.h>
myHandler(struct _EXCEPTION_RECORD * p1,void * p2,struct _CONTEXT * p3,void * p4)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;
55 }
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 ) RxPackSetMutex(&varname);
68 # define THREAD_UNPROTECT(varname) __exceptVK           RxPackUnsetMutex(&varname);
69 #else
70 # define THREAD_PROTECT(varname) __try { RxPackSetMutex(&varname);
71 # define THREAD_UNPROTECT(varname) } __finally { RxPackUnsetMutex(&varname); }
72 #endif
73 
74 #define PROTECTION_VAR(varname) static void * varname = NULL;
75 
76 #define EXPORT_GLOBAL_PROTECTION_VAR(varname) extern void *varname;
77 #define GLOBAL_PROTECTION_VAR(varname) void *varname;
78 
79 RxPackageGlobalDataDef *RxPackInitializeThread(void);
80 #define GLOBAL_ENTRY_POINT() RxPackInitializeThread()
81 
82 unsigned long RxPackGetThreadID(void);
83 
84 /* we need a pointer to RxPackageGlobalDataDef sometimes: */
85 RxPackageGlobalDataDef *__rxpack_get_tsd(void);
86 
87 /* NEVER USE __rxpack_get_tsd() IF YOU CAN GET THE VALUE FROM SOMEWHERE ELSE.
88  * IT REDUCES THE EXECUTION SPEED SIGNIFICANTLY. TAKE THE VALUE FROM THE CALLER
89  * WHERE IT IS POSSIBLE.
90  */
91