begin of support for named mutexes.
This commit is contained in:
parent
ff6184863f
commit
50659967ed
30
C/adtdefs.c
30
C/adtdefs.c
@ -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
|
||||||
|
457
C/threads.c
457
C/threads.c
@ -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)
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@}
|
@}
|
||||||
*/
|
*/
|
||||||
|
90
H/Yatom.h
90
H/Yatom.h
@ -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,
|
||||||
|
Reference in New Issue
Block a user