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_FirstLineInParse,(void));
|
||||||
int STD_PROTO(Yap_CheckIOStream,(Term, char *));
|
int STD_PROTO(Yap_CheckIOStream,(Term, char *));
|
||||||
#if defined(YAPOR) || defined(THREADS)
|
#if defined(YAPOR) || defined(THREADS)
|
||||||
void STD_PROTO(Yap_LockStream,(int));
|
void STD_PROTO(Yap_LockStream,(struct io_stream *));
|
||||||
void STD_PROTO(Yap_UnLockStream,(int));
|
void STD_PROTO(Yap_UnLockStream,(struct io_stream *));
|
||||||
#else
|
#else
|
||||||
#define Yap_LockStream(X)
|
#define Yap_LockStream(X)
|
||||||
#define Yap_UnLockStream(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 (*Sclose_function)(void *handle);
|
||||||
typedef int (*Scontrol_function)(void *handle, int action, void *arg);
|
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)
|
#if defined(O_PLMT) && defined(PL_KERNEL)
|
||||||
#include "pl-mutex.h"
|
/* Support PL_LOCK in the interface */
|
||||||
#define IOLOCK recursiveMutex
|
#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
|
#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
|
#endif
|
||||||
|
|
||||||
typedef struct io_functions
|
typedef struct io_functions
|
||||||
|
@ -2855,6 +2855,18 @@ FILE *Yap_FileDescriptorFromStream(Term t)
|
|||||||
return NULL;
|
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);
|
extern term_t Yap_CvtTerm(term_t ts);
|
||||||
|
|
||||||
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 */
|
#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 *
|
* LIST BUILDING *
|
||||||
*******************************/
|
*******************************/
|
||||||
|
|
||||||
#include "pl-privitf.h"
|
#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
|
typedef enum
|
||||||
{ CLN_NORMAL = 0, /* Normal mode */
|
{ CLN_NORMAL = 0, /* Normal mode */
|
||||||
CLN_ACTIVE, /* Started cleanup */
|
CLN_ACTIVE, /* Started cleanup */
|
||||||
@ -360,12 +358,6 @@ typedef struct {
|
|||||||
{ Table table; /* global (read-only) features */
|
{ Table table; /* global (read-only) features */
|
||||||
} prolog_flag;
|
} prolog_flag;
|
||||||
|
|
||||||
#if THREADS
|
|
||||||
struct
|
|
||||||
{ int enabled; /* threads are enabled */
|
|
||||||
} thread;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{ Table tmp_files; /* Known temporary files */
|
{ Table tmp_files; /* Known temporary files */
|
||||||
CanonicalDir _canonical_dirlist;
|
CanonicalDir _canonical_dirlist;
|
||||||
@ -693,73 +685,6 @@ extern PL_local_data_t lds;
|
|||||||
#define source_line_pos (LD->read_source.linepos)
|
#define source_line_pos (LD->read_source.linepos)
|
||||||
#define source_char_no (LD->read_source.character)
|
#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
|
#ifndef TRUE
|
||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
|
@ -926,6 +926,63 @@ Yap_fetch_module_for_format(term_t args, YAP_Term *modp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if THREADS
|
#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[] =
|
counting_mutex _PL_mutexes[] =
|
||||||
{ COUNT_MUTEX_INITIALIZER("L_MISC"),
|
{ COUNT_MUTEX_INITIALIZER("L_MISC"),
|
||||||
COUNT_MUTEX_INITIALIZER("L_ALLOC"),
|
COUNT_MUTEX_INITIALIZER("L_ALLOC"),
|
||||||
|
Reference in New Issue
Block a user