@@ -21,16 +21,30 @@ #ifdef OF_AMIGAOS # include # include -# import "OFMapTable.h" -# import "OFList.h" +/* + * As we use this file in both the runtime and ObjFW, and since AmigaOS always + * has the runtime, use the hashtable from the runtime. + */ +# import "runtime/private.h" -static const of_map_table_functions_t functions = { NULL }; -static OFList *allKeys = nil; +static of_tlskey_t firstKey = NULL, lastKey = NULL; static struct SignalSemaphore semaphore; + +static uint32_t +hashFunc(const void *ptr) +{ + return (uint32_t)(uintptr_t)ptr; +} + +static bool +equalFunc(const void *ptr1, const void *ptr2) +{ + return (ptr1 == ptr2); +} OF_CONSTRUCTOR() { InitSemaphore(&semaphore); } @@ -42,18 +56,32 @@ #if defined(OF_HAVE_PTHREADS) return (pthread_key_create(key, NULL) == 0); #elif defined(OF_WINDOWS) return ((*key = TlsAlloc()) != TLS_OUT_OF_INDEXES); #elif defined(OF_AMIGAOS) - if ((*key = calloc(1, sizeof(**key))) == NULL) + if ((*key = malloc(sizeof(**key))) == NULL) return false; - /* - * We create the map table lazily, as some TLS are created in - * constructors, at which time OFMapTable is not available yet. - */ + (*key)->table = NULL; + + ObtainSemaphore(&semaphore); + @try { + (*key)->next = NULL; + (*key)->previous = lastKey; + + if (lastKey != NULL) + lastKey->next = *key; + + lastKey = *key; + + if (firstKey == NULL) + firstKey = *key; + } @finally { + ReleaseSemaphore(&semaphore); + } + /* We create the hash table lazily. */ return true; #endif } bool @@ -64,12 +92,21 @@ #elif defined(OF_WINDOWS) return TlsFree(key); #elif defined(OF_AMIGAOS) ObtainSemaphore(&semaphore); @try { - [allKeys removeListObject: key->listObject]; - [key->mapTable release]; + if (key->previous != NULL) + key->previous->next = key->next; + if (key->next != NULL) + key->next->previous = key->previous; + + if (firstKey == key) + firstKey = key->next; + if (lastKey == key) + lastKey = key->previous; + + objc_hashtable_free(key->table); free(key); } @finally { ReleaseSemaphore(&semaphore); } @@ -76,33 +113,21 @@ return true; #endif } #ifdef OF_AMIGAOS -static void -unsafeCreateMapTable(of_tlskey_t key) -{ - key->mapTable = [[OFMapTable alloc] initWithKeyFunctions: functions - objectFunctions: functions]; - - if (allKeys == nil) - allKeys = [[OFList alloc] init]; - - key->listObject = [allKeys appendObject: key->mapTable]; -} - void * of_tlskey_get(of_tlskey_t key) { void *ret; ObtainSemaphore(&semaphore); @try { - if (key->mapTable == NULL) - unsafeCreateMapTable(key); + if (key->table == NULL) + return NULL; - ret = [key->mapTable objectForKey: FindTask(NULL)]; + ret = objc_hashtable_get(key->table, FindTask(NULL)); } @finally { ReleaseSemaphore(&semaphore); } return ret; @@ -113,18 +138,17 @@ { ObtainSemaphore(&semaphore); @try { struct Task *task = FindTask(NULL); - if (key->mapTable == NULL) - unsafeCreateMapTable(key); + if (key->table == NULL) + key->table = objc_hashtable_new(hashFunc, equalFunc, 2); if (ptr == NULL) - [key->mapTable removeObjectForKey: task]; + objc_hashtable_delete(key->table, task); else - [key->mapTable setObject: ptr - forKey: task]; + objc_hashtable_set(key->table, task, ptr); } @catch (id e) { return false; } @finally { ReleaseSemaphore(&semaphore); } @@ -137,13 +161,14 @@ { ObtainSemaphore(&semaphore); @try { struct Task *task = FindTask(NULL); - for (of_list_object_t *iter = allKeys.firstListObject; - iter != NULL; iter = iter->next) - [iter->object removeObjectForKey: task]; + for (of_tlskey_t iter = firstKey; iter != NULL; + iter = iter->next) + if (iter->table != NULL) + objc_hashtable_delete(iter->table, task); } @finally { ReleaseSemaphore(&semaphore); } } #endif