/**************************************************************************** ** *F InitLibrary( <module> ) . . . . . . . initialise library data structures */ static Int InitLibrary ( StructInitInfo * module ) { /* make the list of names of record names */ CountRNam = 0; NamesRNam = NEW_PLIST( T_PLIST, 0 ); MakeBagPublic(NamesRNam); SET_LEN_PLIST( NamesRNam, 0 ); /* make the hash list of record names */ SizeRNam = 997; HashRNam = NEW_PLIST( T_PLIST, SizeRNam ); MakeBagPublic(HashRNam); SET_LEN_PLIST( HashRNam, SizeRNam ); /* init filters and functions */ InitGVarFiltsFromTable( GVarFilts ); InitGVarOpersFromTable( GVarOpers ); InitGVarFuncsFromTable( GVarFuncs ); /* return success */ return 0; }
/**************************************************************************** ** *F InitLibrary( <module> ) . . . . . . . initialise library data structures */ static Int InitLibrary ( StructInitInfo * module ) { /* make the list of names of record names */ NamesRNam = NEW_PLIST( T_PLIST, 0 ); #ifdef HPCGAP MakeBagPublic(NamesRNam); #endif /* make the hash list of record names */ HashRNam = NEW_PLIST( T_PLIST, 14033 ); SET_LEN_PLIST( HashRNam, 14033 ); #ifdef HPCGAP MakeBagPublic(HashRNam); #endif /* init filters and functions */ InitGVarFiltsFromTable( GVarFilts ); InitGVarOpersFromTable( GVarOpers ); InitGVarFuncsFromTable( GVarFuncs ); /* return success */ return 0; }
Region * NewRegion(void) { Region * result; pthread_rwlock_t * lock; Obj region_obj; #ifndef DISABLE_GC result = GC_malloc(sizeof(Region) + (MAX_THREADS + 1)); lock = GC_malloc_atomic(sizeof(*lock)); GC_register_finalizer(lock, LockFinalizer, NULL, NULL, NULL); #else result = calloc(1, sizeof(Region) + (MAX_THREADS + 1)); lock = malloc(sizeof(*lock)); #endif pthread_rwlock_init(lock, NULL); region_obj = NewBag(T_REGION, sizeof(Region *)); MakeBagPublic(region_obj); *(Region **)(ADDR_OBJ(region_obj)) = result; result->obj = region_obj; result->lock = lock; return result; }
UInt RNamNameWithLen(const Char * name, UInt len) { Obj rnam; /* record name (as imm intobj) */ UInt pos; /* hash position */ Char namx [1024]; /* temporary copy of <name> */ Obj string; /* temporary string object <name> */ Obj table; /* temporary copy of <HashRNam> */ Obj rnam2; /* one element of <table> */ UInt i; /* loop variable */ UInt sizeRNam; if (len > 1023) { // Note: We can't pass 'name' here, as it might get moved by garbage collection ErrorQuit("Record names must consist of at most 1023 characters", 0, 0); } /* start looking in the table at the following hash position */ const UInt hash = HashString( name, len ); #ifdef HPCGAP HPC_LockNames(0); /* try a read lock first */ #endif /* look through the table until we find a free slot or the global */ sizeRNam = LEN_PLIST(HashRNam); pos = (hash % sizeRNam) + 1; while ( (rnam = ELM_PLIST( HashRNam, pos )) != 0 && !EqString( NAME_RNAM( INT_INTOBJ(rnam) ), name, len ) ) { pos = (pos % sizeRNam) + 1; } if (rnam != 0) { #ifdef HPCGAP HPC_UnlockNames(); #endif return INT_INTOBJ(rnam); } #ifdef HPCGAP if (!PreThreadCreation) { HPC_UnlockNames(); /* switch to a write lock */ HPC_LockNames(1); /* look through the table until we find a free slot or the global */ sizeRNam = LEN_PLIST(HashRNam); pos = (hash % sizeRNam) + 1; while ( (rnam = ELM_PLIST( HashRNam, pos )) != 0 && !EqString( NAME_RNAM( INT_INTOBJ(rnam) ), name, len ) ) { pos = (pos % sizeRNam) + 1; } } if (rnam != 0) { HPC_UnlockNames(); return INT_INTOBJ(rnam); } #endif /* if we did not find the global variable, make a new one and enter it */ /* (copy the name first, to avoid a stale pointer in case of a GC) */ memcpy( namx, name, len ); namx[len] = 0; string = MakeImmString(namx); const UInt countRNam = PushPlist(NamesRNam, string); rnam = INTOBJ_INT(countRNam); SET_ELM_PLIST( HashRNam, pos, rnam ); /* if the table is too crowded, make a larger one, rehash the names */ if ( sizeRNam < 3 * countRNam / 2 ) { table = HashRNam; sizeRNam = 2 * sizeRNam + 1; HashRNam = NEW_PLIST( T_PLIST, sizeRNam ); SET_LEN_PLIST( HashRNam, sizeRNam ); #ifdef HPCGAP /* The list is briefly non-public, but this is safe, because * the mutex protects it from being accessed by other threads. */ MakeBagPublic(HashRNam); #endif for ( i = 1; i <= (sizeRNam-1)/2; i++ ) { rnam2 = ELM_PLIST( table, i ); if ( rnam2 == 0 ) continue; string = NAME_RNAM( INT_INTOBJ(rnam2) ); pos = HashString( CONST_CSTR_STRING( string ), GET_LEN_STRING( string) ); pos = (pos % sizeRNam) + 1; while ( ELM_PLIST( HashRNam, pos ) != 0 ) { pos = (pos % sizeRNam) + 1; } SET_ELM_PLIST( HashRNam, pos, rnam2 ); } } #ifdef HPCGAP HPC_UnlockNames(); #endif /* return the record name */ return INT_INTOBJ(rnam); }