enable compilation with multi-threading.
This commit is contained in:
parent
f2e8f2ac2e
commit
3f6b92de4b
@ -282,8 +282,8 @@ FILE *STD_PROTO(Yap_FileDescriptorFromStream,(Term));
|
||||
Int STD_PROTO(Yap_FirstLineInParse,(void));
|
||||
int STD_PROTO(Yap_CheckIOStream,(Term, char *));
|
||||
#if defined(YAPOR) || defined(THREADS)
|
||||
void STD_PROTO(Yap_LockStream,(int));
|
||||
void STD_PROTO(Yap_UnLockStream,(int));
|
||||
void STD_PROTO(Yap_LockStream,(struct io_stream *));
|
||||
void STD_PROTO(Yap_UnLockStream,(struct io_stream *));
|
||||
#else
|
||||
#define Yap_LockStream(X)
|
||||
#define Yap_UnLockStream(X)
|
||||
|
@ -94,11 +94,106 @@ typedef int64_t (*Sseek64_function)(void *handle, int64_t pos, int whence);
|
||||
typedef int (*Sclose_function)(void *handle);
|
||||
typedef int (*Scontrol_function)(void *handle, int action, void *arg);
|
||||
|
||||
#if defined(THREADS) && !defined(O_PLMT)
|
||||
#define O_PLMT 1
|
||||
#endif
|
||||
|
||||
#if defined(O_PLMT) && defined(PL_KERNEL)
|
||||
#include "pl-mutex.h"
|
||||
#define IOLOCK recursiveMutex
|
||||
/* 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)
|
||||
|
||||
#define IF_MT(id, g) if ( id == L_THREAD || GD->thread.enabled ) g
|
||||
|
||||
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_PLFLAG 12
|
||||
#define L_OP 13
|
||||
#define L_INIT 14
|
||||
#define L_TERM 15
|
||||
#define L_GC 16
|
||||
#define L_AGC 17
|
||||
#define L_FOREIGN 18
|
||||
#define L_OS 19
|
||||
|
||||
#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
|
||||
typedef void * IOLOCK; /* Definition for external use */
|
||||
#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 PL_LOCK(id) IF_MT(id, countingMutexLock(&_PL_mutexes[id]))
|
||||
#define PL_UNLOCK(id) IF_MT(id, countingMutexUnlock(&_PL_mutexes[id]))
|
||||
|
||||
#define IOLOCK recursiveMutex
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
#define PL_LOCK(X)
|
||||
#define PL_UNLOCK(X)
|
||||
|
||||
typedef void * IOLOCK;
|
||||
#endif
|
||||
|
||||
typedef struct io_functions
|
||||
|
@ -2855,6 +2855,18 @@ FILE *Yap_FileDescriptorFromStream(Term t)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if THREADS
|
||||
void Yap_LockStream(IOSTREAM *s)
|
||||
{
|
||||
if ( s->mutex ) recursiveMutexLock(s->mutex);
|
||||
}
|
||||
|
||||
void Yap_UnLockStream(IOSTREAM *s)
|
||||
{
|
||||
if ( s->mutex ) recursiveMutexUnlock(s->mutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
extern term_t Yap_CvtTerm(term_t ts);
|
||||
|
||||
term_t Yap_CvtTerm(term_t ts)
|
||||
|
@ -267,25 +267,23 @@ typedef struct
|
||||
#define GF_PROCEDURE 2 /* check for max arity */
|
||||
|
||||
|
||||
#ifdef O_PLMT
|
||||
|
||||
typedef struct free_chunk *FreeChunk; /* left-over chunk */
|
||||
|
||||
struct free_chunk
|
||||
{ FreeChunk next; /* next of chain */
|
||||
size_t size; /* size of free bit */
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*******************************
|
||||
* LIST BUILDING *
|
||||
*******************************/
|
||||
|
||||
#include "pl-privitf.h"
|
||||
|
||||
typedef int simpleMutex;
|
||||
|
||||
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;
|
||||
|
||||
typedef enum
|
||||
{ CLN_NORMAL = 0, /* Normal mode */
|
||||
CLN_ACTIVE, /* Started cleanup */
|
||||
@ -360,12 +358,6 @@ typedef struct {
|
||||
{ Table table; /* global (read-only) features */
|
||||
} prolog_flag;
|
||||
|
||||
#if THREADS
|
||||
struct
|
||||
{ int enabled; /* threads are enabled */
|
||||
} thread;
|
||||
#endif
|
||||
|
||||
struct
|
||||
{ Table tmp_files; /* Known temporary files */
|
||||
CanonicalDir _canonical_dirlist;
|
||||
@ -693,73 +685,6 @@ extern PL_local_data_t lds;
|
||||
#define source_line_pos (LD->read_source.linepos)
|
||||
#define source_char_no (LD->read_source.character)
|
||||
|
||||
/* Support PL_LOCK in the interface */
|
||||
#if THREADS
|
||||
|
||||
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)
|
||||
|
||||
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_PLFLAG 12
|
||||
#define L_OP 13
|
||||
#define L_INIT 14
|
||||
#define L_TERM 15
|
||||
#define L_GC 16
|
||||
#define L_AGC 17
|
||||
#define L_FOREIGN 18
|
||||
#define L_OS 19
|
||||
|
||||
#define IF_MT(id, g) if ( id == L_THREAD || GD->thread.enabled ) 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 PL_LOCK(id) IF_MT(id, countingMutexLock(&_PL_mutexes[id]))
|
||||
#define PL_UNLOCK(id) IF_MT(id, countingMutexUnlock(&_PL_mutexes[id]))
|
||||
|
||||
#else
|
||||
#define PL_LOCK(X)
|
||||
#define PL_UNLOCK(X)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
@ -926,6 +926,63 @@ Yap_fetch_module_for_format(term_t args, YAP_Term *modp) {
|
||||
}
|
||||
|
||||
#if THREADS
|
||||
|
||||
static int
|
||||
recursive_attr(pthread_mutexattr_t **ap)
|
||||
{ static int done;
|
||||
static pthread_mutexattr_t attr;
|
||||
int rc;
|
||||
|
||||
if ( done )
|
||||
{ *ap = &attr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PL_LOCK(L_THREAD);
|
||||
if ( done )
|
||||
{ PL_UNLOCK(L_THREAD);
|
||||
|
||||
*ap = &attr;
|
||||
return 0;
|
||||
}
|
||||
if ( (rc=pthread_mutexattr_init(&attr)) )
|
||||
goto error;
|
||||
#ifdef HAVE_PTHREAD_MUTEXATTR_SETTYPE
|
||||
if ( (rc=pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) )
|
||||
goto error;
|
||||
#else
|
||||
#ifdef HAVE_PTHREAD_MUTEXATTR_SETKIND_NP
|
||||
if ( (rc=pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_RECURSIVE_NP)) )
|
||||
goto error;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
done = TRUE;
|
||||
PL_UNLOCK(L_THREAD);
|
||||
*ap = &attr;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
PL_UNLOCK(L_THREAD);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
recursiveMutexInit(recursiveMutex *m)
|
||||
{
|
||||
int rc;
|
||||
pthread_mutexattr_t *attr;
|
||||
|
||||
if ( (rc=recursive_attr(&attr)) )
|
||||
return rc;
|
||||
|
||||
return pthread_mutex_init(m, attr);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
counting_mutex _PL_mutexes[] =
|
||||
{ COUNT_MUTEX_INITIALIZER("L_MISC"),
|
||||
COUNT_MUTEX_INITIALIZER("L_ALLOC"),
|
||||
|
Reference in New Issue
Block a user