This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/os/pl-thread.h

141 lines
3.9 KiB
C
Executable File

#ifndef PL_THREAD_H
#define PL_THREAD_H 1
#if defined(THREADS) && !defined(O_PLMT)
#define O_PLMT 1
#endif
#if defined(O_PLMT) // && defined(PL_KERNEL)
/* Support PL_LOCK in the interface */
#if THREADS
#include <pthread.h>
typedef pthread_mutex_t simpleMutex;
#define simpleMutexInit(p) pthread_mutex_init(p, NULL)
#define simpleMutexDelete(p) pthread_mutex_destroy(p)
#define simpleMutexLock(p) pthread_mutex_lock(p)
#define simpleMutexUnlock(p) pthread_mutex_unlock(p)
typedef pthread_mutex_t recursiveMutex;
#define NEED_RECURSIVE_MUTEX_INIT 1
extern int recursiveMutexInit(recursiveMutex *m);
#define recursiveMutexDelete(p) pthread_mutex_destroy(p)
#define recursiveMutexLock(p) pthread_mutex_lock(p)
#define recursiveMutexTryLock(p) pthread_mutex_trylock(p)
#define recursiveMutexUnlock(p) pthread_mutex_unlock(p)
typedef struct counting_mutex
{ simpleMutex mutex; /* mutex itself */
const char *name; /* name of the mutex */
long count; /* # times locked */
long unlocked; /* # times unlocked */
#ifdef O_CONTENTION_STATISTICS
long collisions; /* # contentions */
#endif
struct counting_mutex *next; /* next of allocated chain */
} counting_mutex;
extern counting_mutex *allocSimpleMutex(const char *name);
extern void freeSimpleMutex(counting_mutex *m);
extern counting_mutex _PL_mutexes[]; /* Prolog mutexes */
#define L_MISC 0
#define L_ALLOC 1
#define L_ATOM 2
#define L_FLAG 3
#define L_FUNCTOR 4
#define L_RECORD 5
#define L_THREAD 6
#define L_PREDICATE 7
#define L_MODULE 8
#define L_TABLE 9
#define L_BREAK 10
#define L_FILE 11
#define L_SEETELL 12
#define L_PLFLAG 13
#define L_OP 14
#define L_INIT 15
#define L_TERM 16
#define L_GC 17
#define L_AGC 18
#define L_STOPTHEWORLD 19
#define L_FOREIGN 20
#define L_OS 21
#ifdef __WINDOWS__
#define L_DDE 22
#define L_CSTACK 23
#endif
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The IF_MT(id, g) macro is used to bypass mutexes if threading is
disabled. We cannot do this for the L_THREAD mutex however as we need to
control when threads can be created.
We assume id == L_THREAD is optimized away if id is known at
compile-time
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define IF_MT(id, g) if ( id == L_THREAD ) g
#ifdef O_CONTENTION_STATISTICS
#define countingMutexLock(cm) \
do \
{ if ( pthread_mutex_trylock(&(cm)->mutex) == EBUSY ) \
{ (cm)->collisions++; \
pthread_mutex_lock(&(cm)->mutex); \
} \
(cm)->count++; \
} while(0)
#else
#define countingMutexLock(cm) \
do \
{ simpleMutexLock(&(cm)->mutex); \
(cm)->count++; \
} while(0)
#endif
#define countingMutexUnlock(cm) \
do \
{ (cm)->unlocked++; \
assert((cm)->unlocked <= (cm)->count); \
simpleMutexUnlock(&(cm)->mutex); \
} while(0)
//#define O_DEBUG_MT
#ifdef O_DEBUG_MT
#define PL_LOCK(id) \
do { Sdprintf("[%d] %s:%d: LOCK(%s)\n", \
pthread_self(), \
__BASE_FILE__, __LINE__, #id); \
countingMutexLock(&_PL_mutexes[id]); \
} while(0)
#define PL_UNLOCK(id) \
do { Sdprintf("[%d] %s:%d: UNLOCK(%s)\n", \
pthread_self(), \
__BASE_FILE__, __LINE__, #id); \
countingMutexUnlock(&_PL_mutexes[id]); \
} while(0)
#else
#define PL_LOCK(id) IF_MT(id, countingMutexLock(&_PL_mutexes[id]))
#define PL_UNLOCK(id) IF_MT(id, countingMutexUnlock(&_PL_mutexes[id]))
#endif
#undef O_DEBUG_MT
#define IOLOCK recursiveMutex
#endif
#else
#define PL_LOCK(X)
#define PL_UNLOCK(X)
typedef void * IOLOCK;
#endif
#endif