summaryrefslogtreecommitdiff
path: root/src/tet3/inc/dtthr.h
blob: d414a787cfc14108cefda59b50bffe9aadbe0921 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
/*
 *	SCCS: @(#)dtthr.h	1.16 (98/08/28)
 *
 *	UniSoft Ltd., London, England
 *
 * (C) Copyright 1996 X/Open Company Limited
 *
 * All rights reserved.  No part of this source code may be reproduced,
 * stored in a retrieval system, or transmitted, in any form or by any
 * means, electronic, mechanical, photocopying, recording or otherwise,
 * except as stated in the end-user licence agreement, without the prior
 * permission of the copyright owners.
 * A copy of the end-user licence agreement is contained in the file
 * Licence which accompanies this distribution.
 * 
 * X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
 * the UK and other countries.
 */

/************************************************************************

SCCS:   	@(#)dtthr.h	1.16 98/08/28 TETware release 3.3
NAME:		dtthr.h
PRODUCT:	TETware
AUTHOR:		Geoff Clare, UniSoft Ltd.
DATE CREATED:	July 1996

DESCRIPTION:
	macros used for thread safety

MODIFICATIONS:
	
	Geoff Clare, UniSoft Ltd., Sept 1996
	Moved alarm stuff to alarm.h.
	Changes for POSIX threads.
	
	Geoff Clare, UniSoft Ltd., Oct 1996
	Added tet_thr_equal definitions.
	
	Geoff Clare, UniSoft Ltd., June 1997
	Changes to support NT threads.

	Andrew Dingwall, UniSoft Ltd., January 1998
	Changes to enable this file to be used on UNIX systems which
	support both UI threads and POSIX threads.

	Andrew Dingwall, UniSoft Ltd., July 1998
	Added support for shared API libraries.

	Aaron Plattner, April 2010
	Fixed warnings when compiled with GCC's -Wall option.

************************************************************************/

#ifdef TET_THREADS

/*
**	macros to access threads functions
**
**	a set of macros and typedefs appears here for each threads
**	implementation that is supported by TETware;
**	each set of compatibility macros also defines TET_THR_COMPAT_MACROS
**	which is used to ensure that exactly one set of compatibility
**	macros is defined
**
**	note that the macros which appear should only be used internally
**	by TETware and (in some cases) only provide sufficient functionality
**	for use by TETware routines
*/

/* first some include files */

#  ifndef TET_SHLIB_BUILD_SCRIPT
#      include <signal.h>
#      ifdef TET_POSIX_THREADS
#        include <sys/types.h>
#        include <pthread.h>
#      else
#        include <thread.h>
#        include <synch.h>
#      endif /* TET_POSIX_THREADS */
#  endif /* TET_SHLIB_BUILD_SCRIPT */


/*
** The following data types are defined:
**
**	tet_cond_t		condition variable
**	tet_mutex_t		mutex variable
**	tet_thread_key_t	thread key - used to access TLS
**	tet_thread_t		thread identifier
**	tet_timestruc_t		time structure (seconds and microseconds)
**
** The following macros are defined which look like functions.
** (Note that arguments with side effects won't always work as expected.)
** It's only meaningful to use values returned by macros not marked as "void".
** A "void" macro does not return a meaningful value and might not return a
** value at all!
**
**	int TET_COND_DESTROY(cvp)
**	int TET_COND_INIT(cvp)
**	int TET_COND_SIGNAL(cvp)
**	int TET_COND_TIMEDWAIT(cvp, mp, tvp)
**	void TET_MUTEX_INIT(mp)
**	void TET_MUTEX_DESTROY(mp)
**	void TET_MUTEX_LOCK(mp)
**	void TET_MUTEX_UNLOCK(mp)
**	int TET_THR_CREATE(func, arg, tp)
**	int TET_THR_EQUAL(a, b)
**	void TET_THR_EXIT(sp)
**	void TET_THR_GETSPECIFIC(key, vp)
**	int TET_THR_JOIN(tid, sp)
**	int TET_THR_KEYCREATE(kp)
**	int TET_THR_KILL(tid, sig)
**	tet_thread_t TET_THR_SELF()
**	void TET_THR_SETSPECIFIC(key, value)
**	int TET_THR_SIGSETMASK(how, sp, osp)
*/

/*
** the WIN32 API on Windows NT and Windows 95
*/



/*
** POSIX threads on UNIX-like systems
*/

#  ifdef TET_POSIX_THREADS

#    ifdef TET_THR_COMPAT_MACROS
#      error more than one threads API-specific macro has been defined
#    else
#      define TET_THR_COMPAT_MACROS
#    endif /* TET_THR_COMPAT_MACROS */

     /* typedefs for data items */
     typedef pthread_cond_t	tet_cond_t;
     typedef pthread_mutex_t	tet_mutex_t;
     typedef pthread_key_t	tet_thread_key_t;
     typedef pthread_t		tet_thread_t;
     typedef struct timespec	tet_timestruc_t;

     /* macros which access functions */
#    define TET_COND_DESTROY(cvp)	pthread_cond_destroy((cvp))
#    define TET_COND_INIT(cvp) \
	pthread_cond_init((cvp), (pthread_condattr_t *) 0)
#    define TET_COND_SIGNAL(cvp)	pthread_cond_signal((cvp))
#    define TET_COND_TIMEDWAIT(cvp, mp, tvp) \
	pthread_cond_timedwait((cvp), (mp), (tvp))
#    define TET_MUTEX_INIT(mp) \
	((void) pthread_mutex_init((mp), (pthread_mutexattr_t *) 0))
#    define TET_MUTEX_DESTROY(mp)	((void) pthread_mutex_destroy((mp)))
#    define TET_MUTEX_LOCK(mp)		((void) pthread_mutex_lock((mp)))
#    define TET_MUTEX_UNLOCK(mp)	((void) pthread_mutex_unlock((mp)))
#    define TET_THR_CREATE(func, arg, tp) \
	pthread_create((tp), (pthread_attr_t *) 0, (func), (arg))
#    define TET_THR_EQUAL(a, b)		pthread_equal((a), (b))
#    define TET_THR_EXIT(sp)		pthread_exit((sp))
#    define TET_THR_GETSPECIFIC(key, vp) \
	(*(vp) = pthread_getspecific((key)))
#    define TET_THR_JOIN(tid, sp)	pthread_join((tid), (sp))
#    define TET_THR_KEYCREATE(kp)	pthread_key_create((kp), TET_NULLFP)
#    define TET_THR_KILL(tid, sig)	pthread_kill((tid), (sig))
#    define TET_THR_SELF()		pthread_self()
#    define TET_THR_SETSPECIFIC(key, value) \
	((void) pthread_setspecific((key), (value)))
#    define TET_THR_SIGSETMASK(how, sp, osp) \
	pthread_sigmask((how), (sp), (osp))


#  endif /* TET_POSIX_THREADS */


/*
** UI threads - the default
**
** (this doesn't imply favouring any particular type of threads;
** it's just that TETware thread-safety was implemented using
** UI threads first - the other implementations came later!)
*/

#  ifndef TET_THR_COMPAT_MACROS

#  define TET_THR_COMPAT_MACROS

     /* typedefs for data items */
     typedef cond_t		tet_cond_t;
     typedef mutex_t		tet_mutex_t;
     typedef thread_key_t	tet_thread_key_t;
     typedef thread_t		tet_thread_t;
     typedef timestruc_t	tet_timestruc_t;

     /* macros which access functions */
#    define TET_COND_DESTROY(cvp)	cond_destroy((cvp))
#    define TET_COND_INIT(cvp) \
	cond_init((cvp), USYNC_THREAD, (void *) 0)
#    define TET_COND_SIGNAL(cvp)	cond_signal((cvp))
#    define TET_COND_TIMEDWAIT(cvp, mp, tvp) \
	cond_timedwait((cvp), (mp), (tvp))
#    define TET_MUTEX_INIT(mp) \
	((void) mutex_init((mp), USYNC_THREAD, (void *) 0))
#    define TET_MUTEX_DESTROY(mp)	((void) mutex_destroy((mp)))
#    define TET_MUTEX_LOCK(mp)		((void) mutex_lock((mp)))
#    define TET_MUTEX_UNLOCK(mp)	((void) mutex_unlock((mp)))
#    define TET_THR_CREATE(func, arg, tp) \
	thr_create((void *) 0, (size_t) 0, (func), (arg), 0L, (tp))
#    define TET_THR_EQUAL(a, b)		((a) == (b))
#    define TET_THR_EXIT(sp)		thr_exit((sp))
#    define TET_THR_GETSPECIFIC(key, vp) \
	(*(vp) = (void *) 0, thr_getspecific((key), (vp)))
#    define TET_THR_JOIN(tid, sp)	thr_join((tid), (thread_t *) 0, (sp))
#    define TET_THR_KEYCREATE(kp)	thr_keycreate((kp), TET_NULLFP)
#    define TET_THR_KILL(tid, sig)	thr_kill((tid), (sig))
#    define TET_THR_SELF()		thr_self()
#    define TET_THR_SETSPECIFIC(key, value) \
	((void) thr_setspecific((key), (value)))
#    define TET_THR_SIGSETMASK(how, sp, osp) \
	thr_sigsetmask((how), (sp), (osp))

#  endif /* !TET_THR_COMPAT_MACROS */

   /* Keys for thread-specific data */
   TET_IMPORT_DATA(tet_thread_key_t, tet_errno_key);
   TET_IMPORT_DATA(tet_thread_key_t, tet_block_key);
   TET_IMPORT_DATA(tet_thread_key_t, tet_sequence_key);
     TET_IMPORT_DATA(tet_thread_key_t, tet_child_key);
     TET_IMPORT_DATA(tet_thread_key_t, tet_alrm_flag_key);

   TET_EXPORT_DATA(tet_thread_t, tet_start_tid);


     /* macros for signal-safe mutex locking */
     /* These must be used in matching pairs as if they were braces */
#    define MTX_LOCK(mp) { sigset_t MTX_LOCK_oss; int MTX_LOCK_maskret = \
	TET_THR_SIGSETMASK(SIG_BLOCK, &tet_blockable_sigs, &MTX_LOCK_oss); \
	TET_MUTEX_LOCK(mp);
#    define MTX_UNLOCK(mp) TET_MUTEX_UNLOCK(mp); if (MTX_LOCK_maskret == 0) \
	TET_THR_SIGSETMASK(SIG_SETMASK, &MTX_LOCK_oss, (sigset_t *)0); }


   /* top-level API mutex with calls that can be nested */
#  define API_LOCK	tet_api_lock(1, __FILE__, __LINE__)
#  define API_UNLOCK	tet_api_lock(0, __FILE__, __LINE__)
   void tet_api_lock(int getlock, const char *file, int line);

#else /* TET_THREADS */

   /* allow use of symbols without putting them in #ifdef TET_THREADS */
#  define MTX_LOCK(mp)		{
#  define MTX_UNLOCK(mp)	}
#  define API_LOCK
#  define API_UNLOCK

   extern long tet_sequence;

#endif /* TET_THREADS */