PL_unify_blob(term_t t, void *blob, size_t len, PL_blob_t *type) { CACHE_REGS AtomEntry *ae; if (!blob) return FALSE; ae = lookupBlob(blob, len, type); if (!ae) { return FALSE; } if (type->acquire) { type->acquire(AtomToSWIAtom(AbsAtom(ae))); } return Yap_unify(Yap_GetFromSlot(t PASS_REGS), MkAtomTerm(AbsAtom(ae))); }
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 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; }
inline static Atom SearchInInvisible(const unsigned char *atom) { AtomEntry *chain; READ_LOCK(INVISIBLECHAIN.AERWLock); chain = RepAtom(INVISIBLECHAIN.Entry); while (!EndOfPAEntr(chain) && strcmp((char *)chain->StrOfAE, (char *)atom)) { chain = RepAtom(chain->NextOfAE); } READ_UNLOCK(INVISIBLECHAIN.AERWLock); if (EndOfPAEntr(chain)) return (NIL); else return (AbsAtom(chain)); }
static int hidden (Atom at) { AtomEntry *chain; READ_LOCK(INVISIBLECHAIN.AERWLock); chain = RepAtom(INVISIBLECHAIN.Entry); while (!EndOfPAEntr (chain) && AbsAtom (chain) != at) chain = RepAtom(chain->NextOfAE); READ_UNLOCK(INVISIBLECHAIN.AERWLock); if (EndOfPAEntr (chain)) return (FALSE); return (TRUE); }
static char *predicate_enumerate(const char *prefix, int state) { CACHE_REGS PredEntry *p; ModEntry m0, *mod; AtomEntry *ap; if (!state) { p = NULL; mod = &m0; m0.NextME = CurrentModules; if (mod->AtomOfME == AtomIDB) mod = mod->NextME; } else { Term cmod; p = LOCAL_SearchPreds; cmod = (p->ModuleOfPred != PROLOG_MODULE ? p->ModuleOfPred : TermProlog); mod = Yap_GetModuleEntry(cmod); } while (mod) { // move to next o; if (p) p = p->NextPredOfModule; while (p == NULL) { mod = mod->NextME; if (!mod) { // done LOCAL_SearchPreds = NULL; return NULL; } if (mod->AtomOfME == AtomIDB) mod = mod->NextME; p = mod->PredForME; } char *c = RepAtom(ap = NameOfPred(p))->StrOfAE; if (strlen(c) > strlen(prefix) && strstr(c, prefix) == c && !(p->PredFlags & HiddenPredFlag)) { LOCAL_SearchPreds = p; arity_t ar = p->ArityOfPE; int l, r; if (Yap_IsPrefixOp(AbsAtom(ap), &l, &r) && ar == 1) { return c; } strncpy(LOCAL_FileNameBuf, c, YAP_FILENAME_MAX); strncat(LOCAL_FileNameBuf, "(", YAP_FILENAME_MAX); return LOCAL_FileNameBuf; } } LOCAL_SearchPreds = NULL; return NULL; }
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; }
int Yap_write_blob(AtomEntry *ref, FILE *stream) { blob_type_t *type = RepBlobProp(ref->PropsOfAE)->blob_type; if (type->write) { Atom at = AbsAtom(ref); return type->write(stream, at, 0); } else { #if defined(__linux__) || defined(__APPLE__) return fprintf(stream, "\'%s\'(%p)", RepAtom(AtomSWIStream)->StrOfAE, ref); #else return fprintf(stream, "\'%s\'(0x%p)", RepAtom(AtomSWIStream)->StrOfAE, ref); #endif } return 0; }
char *Yap_blob_to_string(AtomEntry *ref, const char *s0, size_t sz) { // int rc; char *s = (char *)s0; #if HAVE_FMEMOPEN blob_type_t *type = RepBlobProp(ref->PropsOfAE)->blob_type; if (type->write) { FILE *f = fmemopen(s, sz, "w"); if (f == NULL) { // could not find stream; return NULL; } Atom at = AbsAtom(ref); int rc = type->write(f, at, 0); if (rc < 0) { Yap_Error(EVALUATION_ERROR_UNDEFINED, MkAtomTerm(at), "failure in user-defined blob to string code"); } fclose(f); // return the final result. return s; } else { #endif #if __APPLE__ size_t sz0 = strlcpy(s, (char *)RepAtom(AtomSWIStream)->StrOfAE, sz); #else size_t sz0; char *f = (char *)memcpy(s, (char *)RepAtom(AtomSWIStream)->StrOfAE, sz); f[0] = '\0'; sz0 = f - s; #endif s = s + sz0; sz -= sz0; #if defined(__linux__) || defined(__APPLE__) snprintf(s + strlen(s), sz0, "(%p)", ref); #else snprintf(s + strlen(s), sz0, "(0x%p)", ref); #endif return s; #if HAVE_FMEMOPEN } return NULL; #endif }
/* 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); }
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; }