RetroArch
implement.h
Go to the documentation of this file.
1 /*
2  * implement.h
3  *
4  * Definitions that don't need to be public.
5  *
6  * Keeps all the internals out of pthread.h
7  *
8  * --------------------------------------------------------------------------
9  *
10  * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
11  * Copyright(C) 2008 Jason Schmidlapp
12  *
13  * Contact Email: [email protected]
14  *
15  *
16  * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
17  * Copyright(C) 2008 Jason Schmidlapp
18  *
19  * Contact Email: [email protected]
20  *
21  *
22  * Based upon Pthreads-win32 - POSIX Threads Library for Win32
23  * Copyright(C) 1998 John E. Bossom
24  * Copyright(C) 1999,2005 Pthreads-win32 contributors
25  *
26  * Contact Email: [email protected]
27  *
28  * The original list of contributors to the Pthreads-win32 project
29  * is contained in the file CONTRIBUTORS.ptw32 included with the
30  * source code distribution. The list can also be seen at the
31  * following World Wide Web location:
32  * http://sources.redhat.com/pthreads-win32/contributors.html
33  *
34  * This library is free software; you can redistribute it and/or
35  * modify it under the terms of the GNU Lesser General Public
36  * License as published by the Free Software Foundation; either
37  * version 2 of the License, or (at your option) any later version.
38  *
39  * This library is distributed in the hope that it will be useful,
40  * but WITHOUT ANY WARRANTY; without even the implied warranty of
41  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
42  * Lesser General Public License for more details.
43  *
44  * You should have received a copy of the GNU Lesser General Public
45  * License along with this library in the file COPYING.LIB;
46  * if not, write to the Free Software Foundation, Inc.,
47  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
48  */
49 
50 
51 #ifndef _IMPLEMENT_H
52 #define _IMPLEMENT_H
53 
54 #include "pte_osal.h"
55 
56 /* use local include files during development */
57 #include "semaphore.h"
58 #include "sched.h"
59 
60 
61 typedef enum
62 {
63  /*
64  * This enumeration represents the state of the thread;
65  * The thread is still "alive" if the numeric value of the
66  * state is greater or equal "PThreadStateRunning".
67  */
68  PThreadStateInitial = 0, /* Thread not running */
69  PThreadStateRunning, /* Thread alive & kicking */
70  PThreadStateSuspended, /* Thread alive but suspended */
71  PThreadStateCancelPending, /* Thread alive but is */
72  /* has cancelation pending. */
73  PThreadStateCanceling, /* Thread alive but is */
74  /* in the process of terminating */
75  /* due to a cancellation request */
76  PThreadStateException, /* Thread alive but exiting */
77  /* due to an exception */
79 }
81 
82 
83 typedef struct pte_thread_t_ pte_thread_t;
84 
86  {
87  pte_osThreadHandle threadId; /* OS specific thread handle */
88  // pthread_t ptHandle; /* This thread's permanent pthread_t handle */
89  pte_thread_t * prevReuse; /* Links threads on reuse stack */
90  volatile PThreadState state;
91  void *exitStatus;
92  void *parms;
93  int ptErrno;
95  pthread_mutex_t threadLock; /* Used for serialised access to public thread state */
96  int sched_priority; /* As set, not as currently is */
97  pthread_mutex_t cancelLock; /* Used for async-cancel safety */
101  jmp_buf start_mark;
102  int implicit:
103  1;
104  void *keys;
105  void *nextAssoc;
106 
107  unsigned int x; /* Extra information - reuse count etc */
108  };
109 
110 
111 /*
112  * Special value to mark attribute objects as valid.
113  */
114 #define PTE_ATTR_VALID ((unsigned long) 0xC4C0FFEE)
115 
117  {
118  unsigned long valid;
119  void *stackaddr;
120  size_t stacksize;
125  };
126 
127 
128 /*
129  * ====================
130  * ====================
131  * Semaphores, Mutexes and Condition Variables
132  * ====================
133  * ====================
134  */
135 
136 struct sem_t_
137  {
138  int value;
141  };
142 
143 #define PTE_OBJECT_AUTO_INIT ((void *) -1)
144 #define PTE_OBJECT_INVALID 0
145 
147  {
149  int lock_idx;
150  /* Provides exclusive access to mutex state
151  via the Interlocked* mechanism.
152  0: unlocked/free.
153  1: locked - no other waiters.
154  -1: locked - with possible other waiters.
155  */
156  int recursive_count; /* Number of unlocks a thread needs to perform
157  before the lock is released (recursive
158  mutexes only). */
159  int kind; /* Mutex type. */
161  };
162 
164  {
165  int pshared;
166  int kind;
167  };
168 
169 /*
170  * Possible values, other than PTE_OBJECT_INVALID,
171  * for the "interlock" element in a spinlock.
172  *
173  * In this implementation, when a spinlock is initialised,
174  * the number of cpus available to the process is checked.
175  * If there is only one cpu then "interlock" is set equal to
176  * PTE_SPIN_USE_MUTEX and u.mutex is a initialised mutex.
177  * If the number of cpus is greater than 1 then "interlock"
178  * is set equal to PTE_SPIN_UNLOCKED and the number is
179  * stored in u.cpus. This arrangement allows the spinlock
180  * routines to attempt an InterlockedCompareExchange on "interlock"
181  * immediately and, if that fails, to try the inferior mutex.
182  *
183  * "u.cpus" isn't used for anything yet, but could be used at
184  * some point to optimise spinlock behaviour.
185  */
186 #define PTE_SPIN_UNLOCKED (1)
187 #define PTE_SPIN_LOCKED (2)
188 #define PTE_SPIN_USE_MUTEX (3)
189 
191  {
192  int interlock; /* Locking element for multi-cpus. */
193  union
194  {
195  int cpus; /* No. of cpus if multi cpus, or */
196  pthread_mutex_t mutex; /* mutex if single cpu. */
197  } u;
198  };
199 
201  {
202  unsigned int nCurrentBarrierHeight;
203  unsigned int nInitialBarrierHeight;
204  int iStep;
205  int pshared;
207  };
208 
210  {
211  int pshared;
212  };
213 
215  {
216  unsigned key;
217  void (*destructor) (void *);
219  void *threads;
220  };
221 
222 
223 typedef struct ThreadParms ThreadParms;
225 
227  {
229  void *(*start) (void *);
230  void *arg;
231  };
232 
234  {
235  long nWaitersBlocked; /* Number of threads blocked */
236  long nWaitersGone; /* Number of threads timed out */
237  long nWaitersToUnblock; /* Number of threads to unblock */
238  sem_t semBlockQueue; /* Queue up threads waiting for the */
239  /* condition to become signalled */
240  sem_t semBlockLock; /* Semaphore that guards access to */
241  /* | waiters blocked count/block queue */
242  /* +-> Mandatory Sync.LEVEL-1 */
243  pthread_mutex_t mtxUnblockLock; /* Mutex that guards access to */
244  /* | waiters (to)unblock(ed) counts */
245  /* +-> Optional* Sync.LEVEL-2 */
246  pthread_cond_t next; /* Doubly linked list */
248  };
249 
250 
252  {
253  int pshared;
254  };
255 
256 #define PTE_RWLOCK_MAGIC 0xfacade2
257 
259  {
266  int nMagic;
267  };
268 
270  {
271  int pshared;
272  };
273 
274 /*
275  * MCS lock queue node - see pte_MCS_lock.c
276  */
278  {
279  struct pte_mcs_node_t_ **lock; /* ptr to tail of queue */
280  struct pte_mcs_node_t_ *next; /* ptr to successor in queue */
281  unsigned int readyFlag; /* set after lock is released by
282  predecessor */
283  unsigned int nextFlag; /* set after 'next' ptr is set by
284  successor */
285  };
286 
289 
290 
292  {
293  /*
294  * Purpose:
295  * This structure creates an association between a thread and a key.
296  * It is used to implement the implicit invocation of a user defined
297  * destroy routine for thread specific data registered by a user upon
298  * exiting a thread.
299  *
300  * Graphically, the arrangement is as follows, where:
301  *
302  * K - Key with destructor
303  * (head of chain is key->threads)
304  * T - Thread that has called pthread_setspecific(Kn)
305  * (head of chain is thread->keys)
306  * A - Association. Each association is a node at the
307  * intersection of two doubly-linked lists.
308  *
309  * T1 T2 T3
310  * | | |
311  * | | |
312  * K1 -----+-----A-----A----->
313  * | | |
314  * | | |
315  * K2 -----A-----A-----+----->
316  * | | |
317  * | | |
318  * K3 -----A-----+-----A----->
319  * | | |
320  * | | |
321  * V V V
322  *
323  * Access to the association is guarded by two locks: the key's
324  * general lock (guarding the row) and the thread's general
325  * lock (guarding the column). This avoids the need for a
326  * dedicated lock for each association, which not only consumes
327  * more handles but requires that: before the lock handle can
328  * be released - both the key must be deleted and the thread
329  * must have called the destructor. The two-lock arrangement
330  * allows the resources to be freed as soon as either thread or
331  * key is concluded.
332  *
333  * To avoid deadlock: whenever both locks are required, the key
334  * and thread locks are always acquired in the order: key lock
335  * then thread lock. An exception to this exists when a thread
336  * calls the destructors, however this is done carefully to
337  * avoid deadlock.
338  *
339  * An association is created when a thread first calls
340  * pthread_setspecific() on a key that has a specified
341  * destructor.
342  *
343  * An association is destroyed either immediately after the
344  * thread calls the key destructor function on thread exit, or
345  * when the key is deleted.
346  *
347  * Attributes:
348  * thread
349  * reference to the thread that owns the
350  * association. This is actually the pointer to the
351  * thread struct itself. Since the association is
352  * destroyed before the thread exits, this can never
353  * point to a different logical thread to the one that
354  * created the assoc, i.e. after thread struct reuse.
355  *
356  * key
357  * reference to the key that owns the association.
358  *
359  * nextKey
360  * The pthread_t->keys attribute is the head of a
361  * chain of associations that runs through the nextKey
362  * link. This chain provides the 1 to many relationship
363  * between a pthread_t and all pthread_key_t on which
364  * it called pthread_setspecific.
365  *
366  * prevKey
367  * Similarly.
368  *
369  * nextThread
370  * The pthread_key_t->threads attribute is the head of
371  * a chain of assoctiations that runs through the
372  * nextThreads link. This chain provides the 1 to many
373  * relationship between a pthread_key_t and all the
374  * PThreads that have called pthread_setspecific for
375  * this pthread_key_t.
376  *
377  * prevThread
378  * Similarly.
379  *
380  * Notes:
381  * 1) As soon as either the key or the thread is no longer
382  * referencing the association, it can be destroyed. The
383  * association will be removed from both chains.
384  *
385  * 2) An association is only created by
386  * pthread_setspecific if the user provided a
387  * destroyRoutine when they created the key.
388  *
389  *
390  */
397  };
398 
399 /*
400  * Services available through EXCEPTION_PTE_SERVICES
401  * and also used [as parameters to pte_throw()] as
402  * generic exception selectors.
403  */
404 
405 #define PTE_EPS_EXIT (1)
406 #define PTE_EPS_CANCEL (2)
407 
408 
409 /* Useful macros */
410 #define PTE_MAX(a,b) ((a)<(b)?(b):(a))
411 #define PTE_MIN(a,b) ((a)>(b)?(b):(a))
412 
413 
414 /* Thread Reuse stack bottom marker. Must not be NULL or any valid pointer to memory. */
415 #define PTE_THREAD_REUSE_EMPTY ((pte_thread_t *) 1)
416 
417 extern int pte_processInitialized;
424 
425 extern int pte_mutex_default_kind;
426 
427 extern int pte_concurrency;
428 
429 extern int pte_features;
430 
437 
438 
439 #ifdef __cplusplus
440 extern "C"
441  {
442 #endif /* __cplusplus */
443 
444  /*
445  * =====================
446  * =====================
447  * Forward Declarations
448  * =====================
449  * =====================
450  */
451 
452  int pte_is_attr (const pthread_attr_t * attr);
453 
458 
459  int pte_processInitialize (void);
460 
461  void pte_processTerminate (void);
462 
463  void pte_threadDestroy (pthread_t tid);
465 
466  void pte_pop_cleanup_all (int execute);
467 
468  pthread_t pte_new (void);
469 
471 
472  void pte_threadReusePush (pthread_t thread);
473 
474  int pte_getprocessors (int *count);
475 
476  int pte_setthreadpriority (pthread_t thread, int policy, int priority);
477 
478  void pte_rwlock_cancelwrwait (void *arg);
479 
480  int pte_threadStart (void *vthreadParms);
481 
483 
484  int pte_tkAssocCreate (pte_thread_t * thread, pthread_key_t key);
485 
486  void pte_tkAssocDestroy (ThreadKeyAssoc * assoc);
487 
488  int sem_wait_nocancel (sem_t * sem);
489 
490  unsigned int pte_relmillisecs (const struct timespec * abstime);
491 
493 
495 
496  /* Declared in private.c */
497  void pte_throw (unsigned int exception);
498 
499  int pte_cancellable_wait (pte_osSemaphoreHandle semHandle, unsigned int* timeout);
500 
501 #define PTE_ATOMIC_EXCHANGE pte_osAtomicExchange
502 #define PTE_ATOMIC_EXCHANGE_ADD pte_osAtomicExchangeAdd
503 #define PTE_ATOMIC_COMPARE_EXCHANGE pte_osAtomicCompareExchange
504 #define PTE_ATOMIC_DECREMENT pte_osAtomicDecrement
505 #define PTE_ATOMIC_INCREMENT pte_osAtomicIncrement
506 
507  int pte_thread_detach_np();
509 
510 
511 #ifdef __cplusplus
512 }
513 #endif /* __cplusplus */
514 
515 
516 #endif /* _IMPLEMENT_H */
unsigned int readyFlag
Definition: implement.h:281
int nSharedAccessCount
Definition: implement.h:263
pthread_mutex_t keyLock
Definition: implement.h:218
int cancelState
Definition: implement.h:98
Definition: implement.h:269
SceUID pte_osThreadHandle
Definition: psp_osal.h:31
int recursive_count
Definition: implement.h:156
void pte_mcs_lock_acquire(pte_mcs_lock_t *lock, pte_mcs_local_node_t *node)
GLbitfield GLuint64 timeout
Definition: glext.h:7831
Definition: implement.h:233
int pshared
Definition: implement.h:165
int pte_features
Definition: pte_main.c:64
int interlock
Definition: implement.h:192
Definition: implement.h:85
void * exitStatus
Definition: implement.h:91
volatile PThreadState state
Definition: implement.h:90
pthread_t ownerThread
Definition: implement.h:160
Definition: sched.h:97
unsigned int pte_relmillisecs(const struct timespec *abstime)
Definition: pte.c:537
int pte_thread_detach_np()
Definition: pte.c:405
struct pte_mcs_node_t_ * next
Definition: implement.h:280
pte_osMutexHandle pte_mutex_test_init_lock
Definition: pte_main.c:76
Definition: implement.h:291
Definition: implement.h:69
ThreadKeyAssoc * nextThread
Definition: implement.h:394
int detachstate
Definition: implement.h:121
pthread_t pte_new(void)
Definition: pte.c:499
pte_osMutexHandle pte_thread_reuse_lock
Definition: pte_main.c:71
pthread_mutex_t lock
Definition: implement.h:139
int pshared
Definition: implement.h:271
int pte_tkAssocCreate(pte_thread_t *thread, pthread_key_t key)
Definition: pte.c:931
pthread_key_t pte_cleanupKey
Definition: pte_main.c:57
static int cond(LexState *ls)
Definition: lparser.c:1177
sem_t semBarrierBreeched[2]
Definition: implement.h:206
void pte_callUserDestroyRoutines(pthread_t thread)
Definition: pte.c:144
pte_thread_t * thread
Definition: implement.h:391
int pte_setthreadpriority(pthread_t thread, int policy, int priority)
Definition: pthread_set.c:248
typedef void(__stdcall *PFN_DESTRUCTION_CALLBACK)(void *pData)
Definition: implement.h:71
ThreadKeyAssoc * nextKey
Definition: implement.h:393
int sched_priority
Definition: implement.h:96
static sys_sem mutex
Definition: memp.c:120
int implicit
Definition: implement.h:103
int pte_getprocessors(int *count)
Definition: pte.c:423
pte_osSemaphoreHandle handle
Definition: implement.h:148
pthread_t pte_threadReusePop(void)
Definition: pte.c:614
int nCompletedSharedAccessCount
Definition: implement.h:265
GLuint GLuint GLsizei count
Definition: glext.h:6292
ThreadKeyAssoc * prevKey
Definition: implement.h:395
int pshared
Definition: implement.h:253
int pte_thread_detach_and_exit_np()
Definition: pte.c:400
pte_osMutexHandle pte_rwlock_test_init_lock
Definition: pte_main.c:88
pthread_key_t key
Definition: implement.h:392
pthread_t tid
Definition: implement.h:228
GLfloat param
Definition: glext.h:6480
void * stackaddr
Definition: implement.h:119
int nMagic
Definition: implement.h:266
int pte_spinlock_check_need_init(pthread_spinlock_t *lock)
Definition: pte.c:743
void pte_mcs_lock_release(pte_mcs_local_node_t *node)
int cancelEvent
Definition: implement.h:100
jmp_buf start_mark
Definition: implement.h:101
Definition: implement.h:76
struct pte_mcs_node_t_ * pte_mcs_lock_t
Definition: implement.h:288
Definition: implement.h:146
void * parms
Definition: implement.h:92
pthread_mutex_t mtxExclusiveAccess
Definition: implement.h:260
int value
Definition: implement.h:138
pthread_cond_t prev
Definition: implement.h:247
void(* destructor)(void *)
Definition: implement.h:217
int pte_concurrency
Definition: pte_main.c:61
int pte_processInitialized
Definition: pte_main.c:53
Definition: psp_pthread.h:45
long nWaitersGone
Definition: implement.h:236
long nWaitersBlocked
Definition: implement.h:235
SceUID pte_osSemaphoreHandle
Definition: psp_osal.h:33
int iStep
Definition: implement.h:204
int lock_idx
Definition: implement.h:149
int inheritsched
Definition: implement.h:123
int pte_cond_check_need_init(pthread_cond_t *cond)
Definition: pte.c:348
pte_osMutexHandle pte_spinlock_test_init_lock
Definition: pte_main.c:94
PThreadState
Definition: implement.h:61
Definition: implement.h:209
int pte_is_attr(const pthread_attr_t *attr)
Definition: pte.c:432
int pte_cancellable_wait(pte_osSemaphoreHandle semHandle, unsigned int *timeout)
Definition: pte.c:288
int pte_rwlock_check_need_init(pthread_rwlock_t *rwlock)
Definition: pte.c:691
SceUID pte_osMutexHandle
Definition: psp_osal.h:35
sem_t semBlockLock
Definition: implement.h:240
void * pthread_t
Definition: pthread.h:398
unsigned long valid
Definition: implement.h:118
pte_thread_t * pte_threadReuseTop
Definition: pte_main.c:54
int sem_wait_nocancel(sem_t *sem)
Definition: sem.c:822
void pte_threadDestroy(pthread_t tid)
Definition: pte.c:782
long nWaitersToUnblock
Definition: implement.h:237
pte_osThreadHandle threadId
Definition: implement.h:87
static const struct @104 priority[]
Definition: implement.h:78
unsigned int nInitialBarrierHeight
Definition: implement.h:203
Definition: implement.h:73
void * arg
Definition: implement.h:230
int cpus
Definition: implement.h:195
Definition: implement.h:258
struct pte_mcs_node_t_ ** lock
Definition: implement.h:279
int kind
Definition: implement.h:159
unsigned int x
Definition: implement.h:107
unsigned int nextFlag
Definition: implement.h:283
void * keys
Definition: implement.h:104
pte_thread_t * prevReuse
Definition: implement.h:89
void pte_tkAssocDestroy(ThreadKeyAssoc *assoc)
Definition: pte.c:1001
void pte_pop_cleanup_all(int execute)
Definition: pte.c:921
int pte_processInitialize(void)
void pte_threadExitAndDestroy(pthread_t tid)
Definition: pte.c:787
int nExclusiveAccessCount
Definition: implement.h:264
Definition: implement.h:190
void * nextAssoc
Definition: implement.h:105
void * threads
Definition: implement.h:219
void pte_threadReusePush(pthread_t thread)
Definition: pte.c:648
size_t stacksize
Definition: implement.h:120
Definition: implement.h:136
pthread_mutex_t mutex
Definition: implement.h:196
pte_osMutexHandle pte_cond_test_init_lock
Definition: pte_main.c:82
int pte_threadStart(void *vthreadParms)
Definition: pte.c:794
pthread_mutex_t mtxSharedAccessCompleted
Definition: implement.h:261
Definition: implement.h:226
int contentionscope
Definition: implement.h:124
int ptErrno
Definition: implement.h:93
unsigned int nCurrentBarrierHeight
Definition: implement.h:202
int detachState
Definition: implement.h:94
Definition: implement.h:200
pthread_cond_t pte_cond_list_head
Definition: pte_main.c:58
Definition: implement.h:163
pte_osMutexHandle pte_cond_list_lock
Definition: pte_main.c:101
pthread_mutex_t threadLock
Definition: implement.h:95
void pte_processTerminate(void)
int kind
Definition: implement.h:166
Definition: implement.h:116
void pte_rwlock_cancelwrwait(void *arg)
Definition: pte.c:680
ThreadKeyAssoc * prevThread
Definition: implement.h:396
pthread_cond_t pte_cond_list_tail
Definition: pte_main.c:59
Definition: implement.h:277
int pshared
Definition: implement.h:211
void pte_throw(unsigned int exception)
Definition: pte.c:875
pte_thread_t * pte_threadReuseBottom
Definition: pte_main.c:55
int pshared
Definition: implement.h:205
pthread_mutex_t cancelLock
Definition: implement.h:97
pthread_cond_t next
Definition: implement.h:246
Definition: implement.h:251
int cancelType
Definition: implement.h:99
pthread_cond_t cndSharedAccessCompleted
Definition: implement.h:262
Definition: implement.h:214
int pte_mutex_check_need_init(pthread_mutex_t *mutex)
Definition: pte.c:440
int pte_mutex_default_kind
pte_osSemaphoreHandle sem
Definition: implement.h:140
sem_t semBlockQueue
Definition: implement.h:238
union pthread_spinlock_t_::@117 u
pthread_key_t pte_selfThreadKey
Definition: pte_main.c:56
unsigned key
Definition: implement.h:216
pthread_mutex_t mtxUnblockLock
Definition: implement.h:243
Definition: implement.h:68
Definition: implement.h:70