begin of support for named mutexes.

This commit is contained in:
Vitor Santos Costa 2014-11-25 16:41:53 +00:00
parent ff6184863f
commit 50659967ed
3 changed files with 888 additions and 781 deletions

View File

@ -1242,7 +1242,7 @@ Yap_PutValue(Atom a, Term v)
WRITE_UNLOCK(p->VRWLock); WRITE_UNLOCK(p->VRWLock);
} }
void bool
Yap_PutAtomTranslation(Atom a, Int i) Yap_PutAtomTranslation(Atom a, Int i)
{ {
AtomEntry *ae = RepAtom(a); AtomEntry *ae = RepAtom(a);
@ -1255,7 +1255,7 @@ Yap_PutAtomTranslation(Atom a, Int i)
p = (TranslationEntry *) Yap_AllocAtomSpace(sizeof(TranslationEntry)); p = (TranslationEntry *) Yap_AllocAtomSpace(sizeof(TranslationEntry));
if (p == NULL) { if (p == NULL) {
WRITE_UNLOCK(ae->ARWLock); WRITE_UNLOCK(ae->ARWLock);
return; return false;
} }
p->KindOfPE = TranslationProperty; p->KindOfPE = TranslationProperty;
p->Translation = i; p->Translation = i;
@ -1264,6 +1264,32 @@ Yap_PutAtomTranslation(Atom a, Int i)
/* take care that the lock for the property will be inited even /* take care that the lock for the property will be inited even
if someone else searches for the property */ if someone else searches for the property */
WRITE_UNLOCK(ae->ARWLock); WRITE_UNLOCK(ae->ARWLock);
return true;
}
bool
Yap_PutAtomMutex(Atom a, void * i)
{
AtomEntry *ae = RepAtom(a);
Prop p0;
MutexEntry *p;
WRITE_LOCK(ae->ARWLock);
p0 = GetAPropHavingLock(ae, MutexProperty);
if (p0 == NIL) {
p = (MutexEntry *) Yap_AllocAtomSpace(sizeof(MutexEntry));
if (p == NULL) {
WRITE_UNLOCK(ae->ARWLock);
return false;
}
p->KindOfPE = MutexProperty;
p->Mutex = i;
AddPropToAtom(RepAtom(a), (PropEntry *)p);
}
/* take care that the lock for the property will be inited even
if someone else searches for the property */
WRITE_UNLOCK(ae->ARWLock);
return true;
} }
Term Term

View File

@ -1,26 +1,26 @@
/************************************************************************* /*************************************************************************
* * * *
* YAP Prolog * * YAP Prolog *
* * * *
* Yap Prolog was developed at NCCUP - Universidade do Porto * * Yap Prolog was developed at NCCUP - Universidade do Porto *
* * * *
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 * * Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
* * * *
************************************************************************** **************************************************************************
* * * *
* File: stdpreds.c * * File: stdpreds.c *
* Last rev: * * Last rev: *
* mods: * * mods: *
* comments: threads * * comments: threads *
* * * *
*************************************************************************/ *************************************************************************/
#ifdef SCCS #ifdef SCCS
static char SccsId[] = "%W% %G%"; static char SccsId[] = "%W% %G%";
#endif #endif
/** /**
@ingroup Threads @ingroup Threads
@{ @{
*/ */
#include "Yap.h" #include "Yap.h"
@ -832,13 +832,10 @@ p_thread_exit( USES_REGS1 )
static Int static Int
p_thread_set_concurrency( USES_REGS1 ) p_thread_set_concurrency( USES_REGS1 )
{ {
Term tnew = Deref(ARG2);
int newc;
#if HAVE_PTHREAD_GETCONCURRENCY #if HAVE_PTHREAD_GETCONCURRENCY
int cur; int newc;
#endif int cur;
Term tnew = Deref(ARG2);
if (IsVarTerm(tnew)) { if (IsVarTerm(tnew)) {
newc = 0; newc = 0;
} else if (IsIntegerTerm(tnew)) { } else if (IsIntegerTerm(tnew)) {
@ -847,7 +844,6 @@ int cur;
Yap_Error(TYPE_ERROR_INTEGER,tnew,"thread_set_concurrency/2"); Yap_Error(TYPE_ERROR_INTEGER,tnew,"thread_set_concurrency/2");
return(FALSE); return(FALSE);
} }
#if HAVE_PTHREAD_GETCONCURRENCY
cur = MkIntegerTerm(pthread_getconcurrency()); cur = MkIntegerTerm(pthread_getconcurrency());
if (pthread_setconcurrency(newc) != 0) { if (pthread_setconcurrency(newc) != 0) {
return FALSE; return FALSE;
@ -906,40 +902,44 @@ p_new_mutex( USES_REGS1 )
pthread_mutex_init(&mutp->m, &mat); pthread_mutex_init(&mutp->m, &mat);
mutp->owners = 0; mutp->owners = 0;
mutp->tid_own = 0; mutp->tid_own = 0;
return Yap_unify(ARG1, MkIntegerTerm((Int)mutp)); if (IsVarTerm((t1 = Deref(ARG1)))) {
return Yap_unify(t1, MkAddressTerm(mutp));
} else if(IsAtomTerm(t1)) {
return Yap_PutAtomMutex( AtomOfTerm(t1), mutp );
}
} }
static Int static Int
p_destroy_mutex( USES_REGS1 ) p_destroy_mutex( USES_REGS1 )
{ {
SWIMutex *mut = (SWIMutex*)IntegerOfTerm(Deref(ARG1)); SWIMutex *mut = (SWIMutex*)IntegerOfTerm(Deref(ARG1));
if (pthread_mutex_destroy(&mut->m) < 0) if (pthread_mutex_destroy(&mut->m) < 0)
return FALSE; return FALSE;
Yap_FreeCodeSpace((void *)mut); Yap_FreeCodeSpace((void *)mut);
return TRUE; return TRUE;
} }
static Int static Int
p_lock_mutex( USES_REGS1 ) p_lock_mutex( USES_REGS1 )
{ {
SWIMutex *mut = (SWIMutex*)IntegerOfTerm(Deref(ARG1)); SWIMutex *mut = (SWIMutex*)IntegerOfTerm(Deref(ARG1));
#if DEBUG_LOCKS #if DEBUG_LOCKS
MUTEX_LOCK(&mut->m); MUTEX_LOCK(&mut->m);
#else #else
if (MUTEX_LOCK(&mut->m) < 0) if (MUTEX_LOCK(&mut->m) < 0)
return FALSE; return FALSE;
#endif #endif
mut->owners++; mut->owners++;
mut->tid_own = worker_id; mut->tid_own = worker_id;
return TRUE; return TRUE;
} }
static Int static Int
p_trylock_mutex( USES_REGS1 ) p_trylock_mutex( USES_REGS1 )
{ {
SWIMutex *mut = (SWIMutex*)IntegerOfTerm(Deref(ARG1)); SWIMutex *mut = (SWIMutex*)IntegerOfTerm(Deref(ARG1));
if (MUTEX_TRYLOCK(&mut->m) == EBUSY) if (MUTEX_TRYLOCK(&mut->m) == EBUSY)
@ -947,26 +947,26 @@ p_new_mutex( USES_REGS1 )
mut->owners++; mut->owners++;
mut->tid_own = worker_id; mut->tid_own = worker_id;
return TRUE; return TRUE;
} }
static Int static Int
p_unlock_mutex( USES_REGS1 ) p_unlock_mutex( USES_REGS1 )
{ {
SWIMutex *mut = (SWIMutex*)IntegerOfTerm(Deref(ARG1)); SWIMutex *mut = (SWIMutex*)IntegerOfTerm(Deref(ARG1));
#if DEBUG_LOCKS #if DEBUG_LOCKS
MUTEX_UNLOCK(&mut->m); MUTEX_UNLOCK(&mut->m);
#else #else
if (MUTEX_UNLOCK(&mut->m) < 0) if (MUTEX_UNLOCK(&mut->m) < 0)
return FALSE; return FALSE;
#endif #endif
mut->owners--; mut->owners--;
return TRUE; return TRUE;
} }
static Int static Int
p_with_mutex( USES_REGS1 ) p_with_mutex( USES_REGS1 )
{ {
SWIMutex *mut; SWIMutex *mut;
Term t1 = Deref(ARG1), excep; Term t1 = Deref(ARG1), excep;
Int rc = FALSE; Int rc = FALSE;
@ -1037,12 +1037,12 @@ p_new_mutex( USES_REGS1 )
return Yap_JumpToEnv(excep); return Yap_JumpToEnv(excep);
} }
return rc; return rc;
} }
static Int static Int
p_with_with_mutex( USES_REGS1 ) p_with_with_mutex( USES_REGS1 )
{ {
if (GLOBAL_WithMutex == NULL) { if (GLOBAL_WithMutex == NULL) {
p_new_mutex( PASS_REGS1 ); p_new_mutex( PASS_REGS1 );
GLOBAL_WithMutex = (SWIMutex*)IntegerOfTerm(Deref(ARG1)); GLOBAL_WithMutex = (SWIMutex*)IntegerOfTerm(Deref(ARG1));
@ -1050,30 +1050,30 @@ p_new_mutex( USES_REGS1 )
ARG1 = MkIntegerTerm((Int)GLOBAL_WithMutex); ARG1 = MkIntegerTerm((Int)GLOBAL_WithMutex);
} }
return p_lock_mutex( PASS_REGS1 ); return p_lock_mutex( PASS_REGS1 );
} }
static Int static Int
p_unlock_with_mutex( USES_REGS1 ) p_unlock_with_mutex( USES_REGS1 )
{ {
ARG1 = MkIntegerTerm((Int)GLOBAL_WithMutex); ARG1 = MkIntegerTerm((Int)GLOBAL_WithMutex);
return p_unlock_mutex( PASS_REGS1 ); return p_unlock_mutex( PASS_REGS1 );
} }
static Int static Int
p_mutex_info( USES_REGS1 ) p_mutex_info( USES_REGS1 )
{ {
SWIMutex *mut = (SWIMutex*)IntegerOfTerm(Deref(ARG1)); SWIMutex *mut = (SWIMutex*)IntegerOfTerm(Deref(ARG1));
return Yap_unify(ARG2, MkIntegerTerm(mut->owners)) && return Yap_unify(ARG2, MkIntegerTerm(mut->owners)) &&
Yap_unify(ARG3, MkIntegerTerm(mut->tid_own)); Yap_unify(ARG3, MkIntegerTerm(mut->tid_own));
return TRUE; return TRUE;
} }
static Int static Int
p_cond_create( USES_REGS1 ) p_cond_create( USES_REGS1 )
{ {
pthread_cond_t* condp; pthread_cond_t* condp;
condp = (pthread_cond_t *)Yap_AllocCodeSpace(sizeof(pthread_cond_t)); condp = (pthread_cond_t *)Yap_AllocCodeSpace(sizeof(pthread_cond_t));
@ -1082,16 +1082,16 @@ p_new_mutex( USES_REGS1 )
} }
pthread_cond_init(condp, NULL); pthread_cond_init(condp, NULL);
return Yap_unify(ARG1, MkIntegerTerm((Int)condp)); return Yap_unify(ARG1, MkIntegerTerm((Int)condp));
} }
typedef struct { typedef struct {
UInt indx; UInt indx;
mbox_t mbox; mbox_t mbox;
} counted_mbox; } counted_mbox;
static Int static Int
p_mbox_create( USES_REGS1 ) p_mbox_create( USES_REGS1 )
{ {
Term namet = Deref(ARG1); Term namet = Deref(ARG1);
mbox_t* mboxp = GLOBAL_named_mboxes; mbox_t* mboxp = GLOBAL_named_mboxes;
@ -1125,11 +1125,11 @@ p_new_mutex( USES_REGS1 )
bool rc = mboxCreate( namet, mboxp PASS_REGS ); bool rc = mboxCreate( namet, mboxp PASS_REGS );
UNLOCK(GLOBAL_mboxq_lock); UNLOCK(GLOBAL_mboxq_lock);
return rc; return rc;
} }
static Int static Int
p_mbox_destroy( USES_REGS1 ) p_mbox_destroy( USES_REGS1 )
{ {
Term namet = Deref(ARG1); Term namet = Deref(ARG1);
mbox_t* mboxp = GLOBAL_named_mboxes, *prevp; mbox_t* mboxp = GLOBAL_named_mboxes, *prevp;
@ -1157,11 +1157,11 @@ p_new_mutex( USES_REGS1 )
mboxDestroy(mboxp PASS_REGS); mboxDestroy(mboxp PASS_REGS);
Yap_FreeCodeSpace( (char *)mboxp ); Yap_FreeCodeSpace( (char *)mboxp );
return TRUE; return TRUE;
} }
static mbox_t* static mbox_t*
getMbox(Term t) getMbox(Term t)
{ {
mbox_t* mboxp; mbox_t* mboxp;
if (IsAtomTerm(t=Deref(t))) { if (IsAtomTerm(t=Deref(t))) {
@ -1199,98 +1199,99 @@ p_new_mutex( USES_REGS1 )
return NULL; return NULL;
} }
return mboxp; return mboxp;
} }
static Int static Int
p_mbox_send( USES_REGS1 ) p_mbox_send( USES_REGS1 )
{ {
Term namet = Deref(ARG1); Term namet = Deref(ARG1);
mbox_t* mboxp = getMbox(namet) ; mbox_t* mboxp = getMbox(namet) ;
if (!mboxp) if (!mboxp)
return FALSE; return FALSE;
return mboxSend(mboxp, Deref(ARG2) PASS_REGS); return mboxSend(mboxp, Deref(ARG2) PASS_REGS);
} }
static Int static Int
p_mbox_size( USES_REGS1 ) p_mbox_size( USES_REGS1 )
{ {
Term namet = Deref(ARG1); Term namet = Deref(ARG1);
mbox_t* mboxp = getMbox(namet) ; mbox_t* mboxp = getMbox(namet) ;
if (!mboxp) if (!mboxp)
return FALSE; return FALSE;
return Yap_unify( ARG2, MkIntTerm(mboxp->nmsgs)); return Yap_unify( ARG2, MkIntTerm(mboxp->nmsgs));
} }
static Int static Int
p_mbox_receive( USES_REGS1 ) p_mbox_receive( USES_REGS1 )
{ {
Term namet = Deref(ARG1); Term namet = Deref(ARG1);
mbox_t* mboxp = getMbox(namet) ; mbox_t* mboxp = getMbox(namet) ;
if (!mboxp) if (!mboxp)
return FALSE; return FALSE;
return mboxReceive(mboxp, Deref(ARG2) PASS_REGS); return mboxReceive(mboxp, Deref(ARG2) PASS_REGS);
} }
static Int static Int
p_mbox_peek( USES_REGS1 ) p_mbox_peek( USES_REGS1 )
{ {
Term namet = Deref(ARG1); Term namet = Deref(ARG1);
mbox_t* mboxp = getMbox(namet) ; mbox_t* mboxp = getMbox(namet) ;
if (!mboxp) if (!mboxp)
return FALSE; return FALSE;
return mboxPeek(mboxp, Deref(ARG2) PASS_REGS); return mboxPeek(mboxp, Deref(ARG2) PASS_REGS);
} }
static Int static Int
p_cond_destroy( USES_REGS1 ) p_cond_destroy( USES_REGS1 )
{ {
pthread_cond_t *condp = (pthread_cond_t *)IntegerOfTerm(Deref(ARG1)); pthread_cond_t *condp = (pthread_cond_t *)IntegerOfTerm(Deref(ARG1));
if (pthread_cond_destroy(condp) < 0) if (pthread_cond_destroy(condp) < 0)
return FALSE; return FALSE;
Yap_FreeCodeSpace((void *)condp); Yap_FreeCodeSpace((void *)condp);
return TRUE; return TRUE;
} }
static Int static Int
p_cond_signal( USES_REGS1 ) p_cond_signal( USES_REGS1 )
{ {
pthread_cond_t *condp = (pthread_cond_t *)IntegerOfTerm(Deref(ARG1)); pthread_cond_t *condp = (pthread_cond_t *)IntegerOfTerm(Deref(ARG1));
if (pthread_cond_signal(condp) < 0) if (pthread_cond_signal(condp) < 0)
return FALSE; return FALSE;
return TRUE; return TRUE;
} }
static Int static Int
p_cond_broadcast( USES_REGS1 ) p_cond_broadcast( USES_REGS1 )
{ {
pthread_cond_t *condp = (pthread_cond_t *)IntegerOfTerm(Deref(ARG1)); pthread_cond_t *condp = (pthread_cond_t *)IntegerOfTerm(Deref(ARG1));
if (pthread_cond_broadcast(condp) < 0) if (pthread_cond_broadcast(condp) < 0)
return FALSE; return FALSE;
v return TRUE; else
} return TRUE;
}
static Int static Int
p_cond_wait( USES_REGS1 ) p_cond_wait( USES_REGS1 )
{ {
pthread_cond_t *condp = (pthread_cond_t *)IntegerOfTerm(Deref(ARG1)); pthread_cond_t *condp = (pthread_cond_t *)IntegerOfTerm(Deref(ARG1));
SWIMutex *mut = (SWIMutex*)IntegerOfTerm(Deref(ARG2)); SWIMutex *mut = (SWIMutex*)IntegerOfTerm(Deref(ARG2));
pthread_cond_wait(condp, &mut->m); pthread_cond_wait(condp, &mut->m);
return TRUE; return TRUE;
} }
static Int static Int
p_thread_stacks( USES_REGS1 ) p_thread_stacks( USES_REGS1 )
{ /* '$thread_signal'(+P) */ { /* '$thread_signal'(+P) */
Int tid = IntegerOfTerm(Deref(ARG1)); Int tid = IntegerOfTerm(Deref(ARG1));
Int status= TRUE; Int status= TRUE;
@ -1305,11 +1306,11 @@ p_new_mutex( USES_REGS1 )
} }
MUTEX_UNLOCK(&(REMOTE_ThreadHandle(tid).tlock)); MUTEX_UNLOCK(&(REMOTE_ThreadHandle(tid).tlock));
return FALSE; return FALSE;
} }
static Int static Int
p_thread_atexit( USES_REGS1 ) p_thread_atexit( USES_REGS1 )
{ /* '$thread_signal'(+P) */ { /* '$thread_signal'(+P) */
Term t; Term t;
if (LOCAL_ThreadHandle.texit == NULL || if (LOCAL_ThreadHandle.texit == NULL ||
@ -1338,13 +1339,13 @@ p_new_mutex( USES_REGS1 )
} while (t == 0); } while (t == 0);
LOCAL_ThreadHandle.texit = NULL; LOCAL_ThreadHandle.texit = NULL;
return Yap_unify(ARG1, t) && Yap_unify(ARG2, LOCAL_ThreadHandle.texit_mod); return Yap_unify(ARG1, t) && Yap_unify(ARG2, LOCAL_ThreadHandle.texit_mod);
} }
static Int static Int
p_thread_signal( USES_REGS1 ) p_thread_signal( USES_REGS1 )
{ /* '$thread_signal'(+P) */ { /* '$thread_signal'(+P) */
Int wid = IntegerOfTerm(Deref(ARG1)); Int wid = IntegerOfTerm(Deref(ARG1));
/* make sure the lock is available */ /* make sure the lock is available */
MUTEX_LOCK(&(REMOTE_ThreadHandle(wid).tlock)); MUTEX_LOCK(&(REMOTE_ThreadHandle(wid).tlock));
@ -1356,17 +1357,17 @@ p_new_mutex( USES_REGS1 )
Yap_external_signal( wid, YAP_ITI_SIGNAL ); Yap_external_signal( wid, YAP_ITI_SIGNAL );
MUTEX_UNLOCK(&(REMOTE_ThreadHandle(wid).tlock)); MUTEX_UNLOCK(&(REMOTE_ThreadHandle(wid).tlock));
return TRUE; return TRUE;
} }
static Int static Int
p_no_threads( USES_REGS1 ) p_no_threads( USES_REGS1 )
{ /* '$thread_signal'(+P) */ { /* '$thread_signal'(+P) */
return FALSE; return FALSE;
} }
static Int static Int
p_nof_threads( USES_REGS1 ) p_nof_threads( USES_REGS1 )
{ /* '$nof_threads'(+P) */ { /* '$nof_threads'(+P) */
int i = 0, wid; int i = 0, wid;
LOCK(GLOBAL_ThreadHandlesLock); LOCK(GLOBAL_ThreadHandlesLock);
for (wid = 0; wid < MAX_THREADS; wid++) { for (wid = 0; wid < MAX_THREADS; wid++) {
@ -1376,70 +1377,70 @@ p_new_mutex( USES_REGS1 )
} }
UNLOCK(GLOBAL_ThreadHandlesLock); UNLOCK(GLOBAL_ThreadHandlesLock);
return Yap_unify(ARG1,MkIntegerTerm(i)); return Yap_unify(ARG1,MkIntegerTerm(i));
} }
static Int static Int
p_max_workers( USES_REGS1 ) p_max_workers( USES_REGS1 )
{ /* '$max_workers'(+P) */ { /* '$max_workers'(+P) */
return Yap_unify(ARG1,MkIntegerTerm(MAX_WORKERS)); return Yap_unify(ARG1,MkIntegerTerm(MAX_WORKERS));
} }
static Int static Int
p_max_threads( USES_REGS1 ) p_max_threads( USES_REGS1 )
{ /* '$max_threads'(+P) */ { /* '$max_threads'(+P) */
return Yap_unify(ARG1,MkIntegerTerm(MAX_THREADS)); return Yap_unify(ARG1,MkIntegerTerm(MAX_THREADS));
} }
static Int static Int
p_nof_threads_created( USES_REGS1 ) p_nof_threads_created( USES_REGS1 )
{ /* '$nof_threads'(+P) */ { /* '$nof_threads'(+P) */
return Yap_unify(ARG1,MkIntTerm(GLOBAL_NOfThreadsCreated)); return Yap_unify(ARG1,MkIntTerm(GLOBAL_NOfThreadsCreated));
} }
static Int static Int
p_thread_runtime( USES_REGS1 ) p_thread_runtime( USES_REGS1 )
{ /* '$thread_runtime'(+P) */ { /* '$thread_runtime'(+P) */
return Yap_unify(ARG1,MkIntegerTerm(GLOBAL_ThreadsTotalTime)); return Yap_unify(ARG1,MkIntegerTerm(GLOBAL_ThreadsTotalTime));
} }
static Int static Int
p_thread_self_lock( USES_REGS1 ) p_thread_self_lock( USES_REGS1 )
{ /* '$thread_unlock' */ { /* '$thread_unlock' */
MUTEX_LOCK(&(LOCAL_ThreadHandle.tlock)); MUTEX_LOCK(&(LOCAL_ThreadHandle.tlock));
return Yap_unify(ARG1,MkIntegerTerm(worker_id)); return Yap_unify(ARG1,MkIntegerTerm(worker_id));
} }
static Int static Int
p_thread_unlock( USES_REGS1 ) p_thread_unlock( USES_REGS1 )
{ /* '$thread_unlock' */ { /* '$thread_unlock' */
Int wid = IntegerOfTerm(Deref(ARG1)); Int wid = IntegerOfTerm(Deref(ARG1));
MUTEX_UNLOCK(&(REMOTE_ThreadHandle(wid).tlock)); MUTEX_UNLOCK(&(REMOTE_ThreadHandle(wid).tlock));
return TRUE; return TRUE;
} }
intptr_t intptr_t
system_thread_id(PL_thread_info_t *info) system_thread_id(PL_thread_info_t *info)
{ if ( !info ) { if ( !info )
{ CACHE_REGS { CACHE_REGS
if ( LOCAL ) if ( LOCAL )
info = SWI_thread_info(worker_id, NULL); info = SWI_thread_info(worker_id, NULL);
else else
return -1; return -1;
} }
#ifdef __linux__ #ifdef __linux__
return info->pid; return info->pid;
#else #else
#ifdef __WINDOWS__ #ifdef __WINDOWS__
return info->w32id; return info->w32id;
#else #else
return (intptr_t)info->tid; return (intptr_t)info->tid;
#endif #endif
#endif #endif
} }
void void
Yap_InitFirstWorkerThreadHandle(void) Yap_InitFirstWorkerThreadHandle(void)
{ {
CACHE_REGS CACHE_REGS
set_system_thread_id(0, NULL); set_system_thread_id(0, NULL);
LOCAL_ThreadHandle.id = 0; LOCAL_ThreadHandle.id = 0;
@ -1455,12 +1456,12 @@ p_new_mutex( USES_REGS1 )
pthread_mutex_init(&REMOTE_ThreadHandle(0).tlock_status, NULL); pthread_mutex_init(&REMOTE_ThreadHandle(0).tlock_status, NULL);
LOCAL_ThreadHandle.tdetach = MkAtomTerm(AtomFalse); LOCAL_ThreadHandle.tdetach = MkAtomTerm(AtomFalse);
LOCAL_ThreadHandle.ref_count = 1; LOCAL_ThreadHandle.ref_count = 1;
} }
FILE *debugf; FILE *debugf;
void Yap_InitThreadPreds(void) void Yap_InitThreadPreds(void)
{ {
Yap_InitCPred("$no_threads", 0, p_no_threads, 0); Yap_InitCPred("$no_threads", 0, p_no_threads, 0);
@ -1530,89 +1531,89 @@ p_new_mutex( USES_REGS1 )
Yap_InitCPred("$thread_self_lock", 1, p_thread_self_lock, SafePredFlag); Yap_InitCPred("$thread_self_lock", 1, p_thread_self_lock, SafePredFlag);
Yap_InitCPred("$thread_run_at_exit", 2, p_thread_atexit, SafePredFlag); Yap_InitCPred("$thread_run_at_exit", 2, p_thread_atexit, SafePredFlag);
Yap_InitCPred("$thread_unlock", 1, p_thread_unlock, SafePredFlag); Yap_InitCPred("$thread_unlock", 1, p_thread_unlock, SafePredFlag);
#if DEBUG_LOCKS||DEBUG_PE_LOCKS #if DEBUG_LOCKS||DEBUG_PE_LOCKS
Yap_InitCPred("debug_locks", 0, p_debug_locks, SafePredFlag); Yap_InitCPred("debug_locks", 0, p_debug_locks, SafePredFlag);
Yap_InitCPred("nodebug_locks", 0, p_nodebug_locks, SafePredFlag); Yap_InitCPred("nodebug_locks", 0, p_nodebug_locks, SafePredFlag);
#endif #endif
} }
#else #else
int int
Yap_NOfThreads(void) { Yap_NOfThreads(void) {
// GLOBAL_ThreadHandlesLock is held // GLOBAL_ThreadHandlesLock is held
#ifdef YAPOR #ifdef YAPOR
return 2; return 2;
#else #else
return 1; return 1;
#endif #endif
} }
static Int static Int
p_no_threads(void) p_no_threads(void)
{ /* '$thread_signal'(+P) */ { /* '$thread_signal'(+P) */
return TRUE; return TRUE;
} }
static Int static Int
p_nof_threads(void) p_nof_threads(void)
{ /* '$nof_threads'(+P) */ { /* '$nof_threads'(+P) */
return Yap_unify(ARG1,MkIntTerm(1)); return Yap_unify(ARG1,MkIntTerm(1));
} }
static Int static Int
p_max_threads(void) p_max_threads(void)
{ /* '$nof_threads'(+P) */ { /* '$nof_threads'(+P) */
return Yap_unify(ARG1,MkIntTerm(1)); return Yap_unify(ARG1,MkIntTerm(1));
} }
static Int static Int
p_nof_threads_created(void) p_nof_threads_created(void)
{ /* '$nof_threads'(+P) */ { /* '$nof_threads'(+P) */
return Yap_unify(ARG1,MkIntTerm(1)); return Yap_unify(ARG1,MkIntTerm(1));
} }
static Int static Int
p_thread_runtime(void) p_thread_runtime(void)
{ /* '$thread_runtime'(+P) */ { /* '$thread_runtime'(+P) */
return Yap_unify(ARG1,MkIntTerm(0)); return Yap_unify(ARG1,MkIntTerm(0));
} }
static Int static Int
p_thread_self(void) p_thread_self(void)
{ /* '$thread_runtime'(+P) */ { /* '$thread_runtime'(+P) */
return Yap_unify(ARG1,MkIntTerm(0)); return Yap_unify(ARG1,MkIntTerm(0));
} }
static Int static Int
p_thread_stacks(void) p_thread_stacks(void)
{ /* '$thread_runtime'(+P) */ { /* '$thread_runtime'(+P) */
return FALSE; return FALSE;
} }
static Int static Int
p_thread_unlock(void) p_thread_unlock(void)
{ /* '$thread_runtime'(+P) */ { /* '$thread_runtime'(+P) */
return TRUE; return TRUE;
} }
static Int static Int
p_max_workers(void) p_max_workers(void)
{ /* '$max_workers'(+P) */ { /* '$max_workers'(+P) */
return Yap_unify(ARG1,MkIntTerm(1)); return Yap_unify(ARG1,MkIntTerm(1));
} }
static Int static Int
p_new_mutex(void) p_new_mutex(void)
{ /* '$max_workers'(+P) */ { /* '$max_workers'(+P) */
static int mutexes = 1; static int mutexes = 1;
return Yap_unify(ARG1, MkIntegerTerm(mutexes++) ); return Yap_unify(ARG1, MkIntegerTerm(mutexes++) );
} }
static Int static Int
p_with_mutex( USES_REGS1 ) p_with_mutex( USES_REGS1 )
{ {
Int mut; Int mut;
Term t1 = Deref(ARG1), excep; Term t1 = Deref(ARG1), excep;
Int rc = FALSE; Int rc = FALSE;
@ -1679,7 +1680,7 @@ p_new_mutex( USES_REGS1 )
return Yap_JumpToEnv(excep); return Yap_JumpToEnv(excep);
} }
return rc; return rc;
} }
void void
Yap_InitFirstWorkerThreadHandle(void) Yap_InitFirstWorkerThreadHandle(void)
@ -1710,5 +1711,5 @@ void Yap_InitThreadPreds(void)
/** /**
@} @}
*/ */

View File

@ -1242,7 +1242,7 @@ RepTranslationProp (Prop p)
INLINE_ONLY inline EXTERN Prop AbsTranslationProp (TranslationEntry * p); INLINE_ONLY inline EXTERN Prop AbsTranslationProp (TranslationEntry * p);
INLINE_ONLY inline EXTERN Prop INLINE_ONLY inline EXTERN Prop
AbsTranslationProp (TranslationEntry * p) AbsTranslationProp (TranslationEntry * p)
{ {
return (Prop) (p); return (Prop) (p);
@ -1252,7 +1252,7 @@ AbsTranslationProp (TranslationEntry * p)
#endif #endif
#define TranslationProperty 0xfff4 #define TranslationProperty 0xfff4
void Yap_PutAtomTranslation(Atom a, Int i); bool Yap_PutAtomTranslation(Atom a, Int i);
/* get translation prop for atom; */ /* get translation prop for atom; */
static inline TranslationEntry * static inline TranslationEntry *
@ -1271,9 +1271,6 @@ Yap_GetTranslationProp(Atom at)
return p; return p;
} }
/* only unary and binary expressions are acceptable */
INLINE_ONLY inline EXTERN PropFlags IsTranslationProperty (int); INLINE_ONLY inline EXTERN PropFlags IsTranslationProperty (int);
INLINE_ONLY inline EXTERN PropFlags INLINE_ONLY inline EXTERN PropFlags
@ -1282,6 +1279,89 @@ IsTranslationProperty (int flags)
return (PropFlags) ((flags == TranslationProperty)); return (PropFlags) ((flags == TranslationProperty));
} }
/*** handle named mutexes */
/* translationnamed mutex property entry structure */
typedef struct mutex_entry
{
Prop NextOfPE; /* used to chain properties */
PropFlags KindOfPE; /* kind of property */
void *Mutex; /* used to hash the atom as an integer; */
} MutexEntry;
#if USE_OFFSETS_IN_PROPS
INLINE_ONLY inline EXTERN MutexEntry *RepMutexProp (Prop p);
INLINE_ONLY inline EXTERN MutexEntry *
RepMutexProp (Prop p)
{
return (MutexEntry *) (AtomBase + Unsigned (p));
}
INLINE_ONLY inline EXTERN Prop AbsMutexProp (MutexEntry * p);
INLINE_ONLY inline EXTERN Prop
AbsMutexProp (MutexEntry * p)
{
return (Prop) (Addr (p) - AtomBase);
}
#else
INLINE_ONLY inline EXTERN MutexEntry *RepMutexProp (Prop p);
INLINE_ONLY inline EXTERN MutexEntry *
RepMutexProp (Prop p)
{
return (MutexEntry *) (p);
}
INLINE_ONLY inline EXTERN Prop AbsMutexProp (MutexEntry * p);
INLINE_ONLY inline EXTERN Prop
AbsMutexProp (MutexEntry * p)
{
return (Prop) (p);
}
#endif
#define MutexProperty 0xfff5
bool Yap_PutAtomMutex(Atom a, void *ptr);
/* get mutex prop for atom; */
static inline MutexEntry *
Yap_GetMutexProp(Atom at)
{
Prop p0;
AtomEntry *ae = RepAtom(at);
MutexEntry *p;
READ_LOCK(ae->ARWLock);
p = RepMutexProp(p0 = ae->PropsOfAE);
while (p0 && p->KindOfPE != MutexProperty)
p = RepMutexProp(p0 = p->NextOfPE);
READ_UNLOCK(ae->ARWLock);
if (p0 == NIL) return NULL;
return p;
}
INLINE_ONLY inline EXTERN PropFlags IsMutexProperty (int);
INLINE_ONLY inline EXTERN PropFlags
IsMutexProperty (int flags)
{
return (PropFlags) ((flags == MutexProperty));
}
/* end of code for named mutexes */
typedef enum { typedef enum {
STATIC_ARRAY = 1, STATIC_ARRAY = 1,