enable compilation with multi-threading.

This commit is contained in:
ubu32 2011-02-27 15:06:10 -08:00
parent f2e8f2ac2e
commit 3f6b92de4b
5 changed files with 180 additions and 91 deletions

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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"),