void Yap_LookupAtomWithAddress(const char *atom, AtomEntry *ae) { /* lookup atom in atom table */ register CELL hash; register const unsigned char *p; Atom a; /* compute hash */ p = (const unsigned char *)atom; hash = HashFunction(p) % AtomHashTableSize; /* ask for a WRITE lock because it is highly unlikely we shall find anything */ WRITE_LOCK(HashChain[hash].AERWLock); a = HashChain[hash].Entry; /* search atom in chain */ if (SearchAtom(p, a) != NIL) { Yap_Error(SYSTEM_ERROR_INTERNAL, TermNil, "repeated initialization for atom %s", ae); WRITE_UNLOCK(HashChain[hash].AERWLock); return; } /* add new atom to start of chain */ NOfAtoms++; ae->NextOfAE = a; HashChain[hash].Entry = AbsAtom(ae); ae->PropsOfAE = NIL; strcpy((char *)ae->StrOfAE, (char *)atom); INIT_RWLOCK(ae->ARWLock); WRITE_UNLOCK(HashChain[hash].AERWLock); }
static void InitAtoms(void) { int i; AtomHashTableSize = MaxHash; HashChain = (AtomHashEntry *)Yap_AllocAtomSpace(sizeof(AtomHashEntry) * MaxHash); if (HashChain == NULL) { Yap_Error(SYSTEM_ERROR_FATAL, MkIntTerm(0), "allocating initial atom table"); } for (i = 0; i < MaxHash; ++i) { INIT_RWLOCK(HashChain[i].AERWLock); HashChain[i].Entry = NIL; } NOfAtoms = 0; #if OLD_STYLE_INITIAL_ATOMS Yap_LookupAtomWithAddress("**", (AtomEntry *)&(SF_STORE->AtFoundVar)); Yap_ReleaseAtom(AtomFoundVar); Yap_LookupAtomWithAddress("?", (AtomEntry *)&(SF_STORE->AtFreeTerm)); Yap_ReleaseAtom(AtomFreeTerm); Yap_LookupAtomWithAddress("[]", (AtomEntry *)&(SF_STORE->AtNil)); Yap_LookupAtomWithAddress(".", (AtomEntry *)&(SF_STORE->AtDot)); #else SF_STORE->AtFoundVar = Yap_LookupAtom("**"); Yap_ReleaseAtom(AtomFoundVar); SF_STORE->AtFreeTerm = Yap_LookupAtom("?"); Yap_ReleaseAtom(AtomFreeTerm); SF_STORE->AtNil = Yap_LookupAtom("[]"); SF_STORE->AtDot = Yap_LookupAtom("."); #endif }
static BBProp PutBBProp(AtomEntry *ae, Term mod USES_REGS) /* get BBentry for at; */ { Prop p0; BBProp p; WRITE_LOCK(ae->ARWLock); p = RepBBProp(p0 = ae->PropsOfAE); while (p0 != NIL && (!IsBBProperty(p->KindOfPE) || (p->ModuleOfBB != mod))) { p = RepBBProp(p0 = p->NextOfPE); } if (p0 == NIL) { p = (BBProp)Yap_AllocAtomSpace(sizeof(*p)); if (p == NULL) { WRITE_UNLOCK(ae->ARWLock); Yap_Error(OUT_OF_HEAP_ERROR,ARG1,"could not allocate space in bb_put/2"); return(NULL); } AddPropToAtom(ae, (PropEntry *)p); p->ModuleOfBB = mod; p->Element = 0L; p->KeyOfBB = AbsAtom(ae); p->KindOfPE = BBProperty; INIT_RWLOCK(p->BBRWLock); } WRITE_UNLOCK(ae->ARWLock); return (p); }
static Atom LookupAtom(const unsigned char *atom) { /* lookup atom in atom table */ uint64_t hash; const unsigned char *p; Atom a, na; AtomEntry *ae; size_t sz = AtomHashTableSize; /* compute hash */ p = atom; hash = HashFunction(p); hash = hash % sz ; /* we'll start by holding a read lock in order to avoid contention */ READ_LOCK(HashChain[hash].AERWLock); a = HashChain[hash].Entry; /* search atom in chain */ na = SearchAtom(atom, a); if (na != NIL) { READ_UNLOCK(HashChain[hash].AERWLock); return (na); } READ_UNLOCK(HashChain[hash].AERWLock); /* we need a write lock */ WRITE_LOCK(HashChain[hash].AERWLock); /* concurrent version of Yap, need to take care */ #if defined(YAPOR) || defined(THREADS) if (a != HashChain[hash].Entry) { a = HashChain[hash].Entry; na = SearchAtom(atom, a); if (na != NIL) { WRITE_UNLOCK(HashChain[hash].AERWLock); return (na); } } #endif /* add new atom to start of chain */ ae = (AtomEntry *)Yap_AllocAtomSpace((sizeof *ae) + strlen((const char *)atom) + 1); if (ae == NULL) { WRITE_UNLOCK(HashChain[hash].AERWLock); return NIL; } NOfAtoms++; na = AbsAtom(ae); ae->PropsOfAE = NIL; if (ae->UStrOfAE != atom) strcpy((char *)ae->StrOfAE, (const char *)atom); ae->NextOfAE = a; HashChain[hash].Entry = na; INIT_RWLOCK(ae->ARWLock); WRITE_UNLOCK(HashChain[hash].AERWLock); if (NOfAtoms > 2 * AtomHashTableSize) { Yap_signal(YAP_CDOVF_SIGNAL); } return na; }
static int OpDec(int p, const char *type, Atom a, Term m) { int i; AtomEntry *ae = RepAtom(a); OpEntry *info; if (m == TermProlog) m = PROLOG_MODULE; else if (m == USER_MODULE) m = PROLOG_MODULE; for (i = 1; i <= 7; ++i) if (strcmp(type, optypes[i]) == 0) break; if (i > 7) { Yap_Error(DOMAIN_ERROR_OPERATOR_SPECIFIER,MkAtomTerm(Yap_LookupAtom(type)),"op/3"); return(FALSE); } if (p) { if (i == 1 || i == 2 || i == 4) p |= DcrlpFlag; if (i == 1 || i == 3 || i == 6) p |= DcrrpFlag; } WRITE_LOCK(ae->ARWLock); info = Yap_GetOpPropForAModuleHavingALock(ae, m); if (EndOfPAEntr(info)) { info = (OpEntry *) Yap_AllocAtomSpace(sizeof(OpEntry)); info->KindOfPE = Ord(OpProperty); info->OpModule = m; info->OpName = a; //LOCK(OpListLock); info->OpNext = OpList; OpList = info; //UNLOCK(OpListLock); AddPropToAtom(ae, (PropEntry *)info); INIT_RWLOCK(info->OpRWLock); WRITE_LOCK(info->OpRWLock); WRITE_UNLOCK(ae->ARWLock); info->Prefix = info->Infix = info->Posfix = 0; } else { WRITE_LOCK(info->OpRWLock); WRITE_UNLOCK(ae->ARWLock); } if (i <= 3) { GET_LD if (truePrologFlag(PLFLAG_ISO) && info->Posfix != 0) /* there is a posfix operator */ { /* ISO dictates */ WRITE_UNLOCK(info->OpRWLock); Yap_Error(PERMISSION_ERROR_CREATE_OPERATOR,MkAtomTerm(a),"op/3"); return FALSE; } info->Infix = p; } else if (i <= 5) {
bool Yap_dup_op(OpEntry *op, ModEntry *she) { AtomEntry *ae = RepAtom(op->OpName); OpEntry *info = (OpEntry *)Yap_AllocAtomSpace(sizeof(OpEntry)); if (!info) return false; memcpy(info, op, sizeof(OpEntry)); info->NextForME =she->OpForME; she->OpForME = info; info->OpModule = MkAtomTerm(she->AtomOfME); AddPropToAtom(ae, AbsOpProp(info)); INIT_RWLOCK(info->OpRWLock); return true; }
static void InitPredHash(void) { UInt i; PredHash = (PredEntry **)Yap_AllocAtomSpace(sizeof(PredEntry **) * PredHashInitialSize); PredHashTableSize = PredHashInitialSize; if (PredHash == NULL) { Yap_Error(SYSTEM_ERROR_FATAL, MkIntTerm(0), "allocating initial predicate hash table"); } for (i = 0; i < PredHashTableSize; ++i) { PredHash[i] = NULL; } INIT_RWLOCK(PredHashRWLock); }
static void InitWideAtoms(void) { int i; WideAtomHashTableSize = MaxWideHash; WideHashChain = (AtomHashEntry *)Yap_AllocAtomSpace(sizeof(AtomHashEntry) * MaxWideHash); if (WideHashChain == NULL) { Yap_Error(SYSTEM_ERROR_FATAL, MkIntTerm(0), "allocating wide atom table"); } for (i = 0; i < MaxWideHash; ++i) { INIT_RWLOCK(WideHashChain[i].AERWLock); WideHashChain[i].Entry = NIL; } NOfWideAtoms = 0; }
static __attribute__((noinline)) int rwl_ref(pthread_rwlock_t *rwl, int f ) { int r = 0; INIT_RWLOCK(rwl); _spin_lite_lock(&rwl_global); if (!rwl || !*rwl || ((rwlock_t *)*rwl)->valid != LIFE_RWLOCK) r = EINVAL; else { ((rwlock_t *)*rwl)->busy ++; } _spin_lite_unlock(&rwl_global); return r; }
static AtomEntry * lookupBlob(void *blob, size_t len, PL_blob_t *type) { BlobPropEntry *b; AtomEntry *ae; LOCK(SWI_Blobs_Lock); if (type->flags & PL_BLOB_UNIQUE) { /* just keep a linked chain for now */ ae = SWI_Blobs; while (ae) { if (ae->PropsOfAE && RepBlobProp(ae->PropsOfAE)->blob_t == type && ae->rep.blob->length == len && !memcmp(ae->rep.blob->data, blob, len)) { UNLOCK(SWI_Blobs_Lock); return ae; } ae = RepAtom(ae->NextOfAE); } } b = (BlobPropEntry *)Yap_AllocCodeSpace(sizeof(BlobPropEntry)); if (!b) { UNLOCK(SWI_Blobs_Lock); return NULL; } b->NextOfPE = NIL; b->KindOfPE = BlobProperty; b->blob_t = type; ae = (AtomEntry *)Yap_AllocCodeSpace(sizeof(AtomEntry)+len+sizeof(size_t)); if (!ae) { UNLOCK(SWI_Blobs_Lock); return NULL; } NOfBlobs++; INIT_RWLOCK(ae->ARWLock); ae->PropsOfAE = AbsBlobProp(b); ae->NextOfAE = AbsAtom(SWI_Blobs); ae->rep.blob->length = len; memcpy(ae->rep.blob->data, blob, len); SWI_Blobs = ae; UNLOCK(SWI_Blobs_Lock); if (NOfBlobs > NOfBlobsMax) { Yap_signal(YAP_CDOVF_SIGNAL); } return ae; }
/** * initialize module data-structure * * @param to parent module (CurrentModule) * @param ae module name. * * @return a new module structure */ /** */ static ModEntry *initMod(AtomEntry *toname, AtomEntry *ae) { CACHE_REGS ModEntry *n, *parent; if (toname == NULL) parent = NULL; else { parent = FetchModuleEntry(toname); } n = (ModEntry *)Yap_AllocAtomSpace(sizeof(*n)); INIT_RWLOCK(n->ModRWLock); n->KindOfPE = ModProperty; n->PredForME = NULL; n->NextME = CurrentModules; CurrentModules = n; n->AtomOfME = ae; n->OwnerFile = Yap_ConsultingFile(PASS_REGS1); AddPropToAtom(ae, (PropEntry *)n); Yap_setModuleFlags(n, parent); return n; }
/* vsc: We must guarantee that IsVarTerm(functor) returns true! */ static inline Functor InlinedUnlockedMkFunctor(AtomEntry *ae, unsigned int arity) { FunctorEntry *p; Prop p0; p0 = GetFunctorProp(ae, arity); if (p0 != NIL) { return ((Functor)RepProp(p0)); } p = (FunctorEntry *)Yap_AllocAtomSpace(sizeof(*p)); if (!p) return NULL; p->KindOfPE = FunctorProperty; p->NameOfFE = AbsAtom(ae); p->ArityOfFE = arity; p->PropsOfFE = NIL; INIT_RWLOCK(p->FRWLock); /* respect the first property, in case this is a wide atom */ AddPropToAtom(ae, (PropEntry *)p); return ((Functor)p); }
OpEntry * Yap_OpPropForModule(Atom a, Term mod) { /* look property list of atom a for kind */ AtomEntry *ae = RepAtom(a); PropEntry *pp; OpEntry *info = NULL; if (mod == TermProlog) mod = PROLOG_MODULE; WRITE_LOCK(ae->ARWLock); pp = RepProp(ae->PropsOfAE); while (!EndOfPAEntr(pp)) { if (pp->KindOfPE == OpProperty) { info = (OpEntry *)pp; if (info->OpModule == mod) { WRITE_LOCK(info->OpRWLock); WRITE_UNLOCK(ae->ARWLock); return info; } } pp = pp->NextOfPE; } info = (OpEntry *)Yap_AllocAtomSpace(sizeof(OpEntry)); info->KindOfPE = Ord(OpProperty); info->OpModule = mod; info->OpName = a; LOCK(OpListLock); info->OpNext = OpList; OpList = info; UNLOCK(OpListLock); AddPropToAtom(ae, (PropEntry *)info); INIT_RWLOCK(info->OpRWLock); WRITE_LOCK(info->OpRWLock); WRITE_UNLOCK(ae->ARWLock); info->Prefix = info->Infix = info->Posfix = 0; return info; }
static Atom LookupWideAtom(const wchar_t *atom) { /* lookup atom in atom table */ CELL hash; wchar_t *p; Atom a, na; AtomEntry *ae; UInt sz; WideAtomEntry *wae; /* compute hash */ p = (wchar_t *)atom; hash = WideHashFunction(p) % WideAtomHashTableSize; /* we'll start by holding a read lock in order to avoid contention */ READ_LOCK(WideHashChain[hash].AERWLock); a = WideHashChain[hash].Entry; /* search atom in chain */ na = SearchWideAtom(atom, a); if (na != NIL) { READ_UNLOCK(WideHashChain[hash].AERWLock); return (na); } READ_UNLOCK(WideHashChain[hash].AERWLock); /* we need a write lock */ WRITE_LOCK(WideHashChain[hash].AERWLock); /* concurrent version of Yap, need to take care */ #if defined(YAPOR) || defined(THREADS) if (a != WideHashChain[hash].Entry) { a = WideHashChain[hash].Entry; na = SearchWideAtom(atom, a); if (na != NIL) { WRITE_UNLOCK(WideHashChain[hash].AERWLock); return na; } } #endif /* add new atom to start of chain */ sz = wcslen(atom); ae = (AtomEntry *)Yap_AllocAtomSpace((size_t)(((AtomEntry *)NULL) + 1) + sizeof(wchar_t) * (sz + 1)); if (ae == NULL) { WRITE_UNLOCK(WideHashChain[hash].AERWLock); return NIL; } wae = (WideAtomEntry *)Yap_AllocAtomSpace(sizeof(WideAtomEntry)); if (wae == NULL) { WRITE_UNLOCK(WideHashChain[hash].AERWLock); return NIL; } na = AbsAtom(ae); ae->PropsOfAE = AbsWideAtomProp(wae); wae->NextOfPE = NIL; wae->KindOfPE = WideAtomProperty; wae->SizeOfAtom = sz; if (ae->WStrOfAE != atom) wcscpy(ae->WStrOfAE, atom); NOfAtoms++; ae->NextOfAE = a; WideHashChain[hash].Entry = na; INIT_RWLOCK(ae->ARWLock); WRITE_UNLOCK(WideHashChain[hash].AERWLock); if (NOfWideAtoms > 2 * WideAtomHashTableSize) { Yap_signal(YAP_CDOVF_SIGNAL); } return na; }
static void InitInvisibleAtoms(void) { /* initialize invisible chain */ INVISIBLECHAIN.Entry = NIL; INIT_RWLOCK(INVISIBLECHAIN.AERWLock); }