Overview
Comment: | Add threads for AmigaOS |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
da383f4f038cde23942d035580cf6149 |
User & Date: | js on 2019-08-03 18:13:50 |
Other Links: | manifest | tags |
Context
2019-08-04
| ||
19:33 | Amiga: Add the new __bss_size to data segment size check-in: a15919c6d8 user: js tags: trunk | |
2019-08-03
| ||
18:13 | Add threads for AmigaOS check-in: da383f4f03 user: js tags: trunk | |
2019-08-02
| ||
12:24 | Minor improvements for threads on Windows check-in: 3c865f9e41 user: js tags: trunk | |
Changes
Modified src/OFThread.m from [83f93c8053] to [0f6e6aa5d7].
︙ | ︙ | |||
144 145 146 147 148 149 150 | else # endif thread->_returnValue = [[thread main] retain]; } [thread handleTermination]; | < < > > | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | else # endif thread->_returnValue = [[thread main] retain]; } [thread handleTermination]; objc_autoreleasePoolPop(thread->_pool); [OFAutoreleasePool of_handleThreadTermination]; thread->_running = OF_THREAD_WAITING_FOR_JOIN; [thread release]; } #elif defined(OF_HAVE_SOCKETS) static OFDNSResolver *DNSResolver; #endif |
︙ | ︙ | |||
329 330 331 332 333 334 335 336 337 338 339 340 341 342 | { OFThread *thread = of_tlskey_get(threadSelfKey); OF_ENSURE(thread != nil); thread->_returnValue = [object retain]; longjmp(thread->_exitEnv, 1); } + (void)setName: (OFString *)name { [OFThread currentThread].name = name; if (name != nil) | > > | 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | { OFThread *thread = of_tlskey_get(threadSelfKey); OF_ENSURE(thread != nil); thread->_returnValue = [object retain]; longjmp(thread->_exitEnv, 1); OF_UNREACHABLE } + (void)setName: (OFString *)name { [OFThread currentThread].name = name; if (name != nil) |
︙ | ︙ |
Modified src/mutex_amiga.m from [07f9094daa] to [7de22b2897].
︙ | ︙ | |||
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #include <proto/exec.h> bool of_mutex_new(of_mutex_t *mutex) { InitSemaphore(mutex); return true; | > > > > > > > > > | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #ifdef OF_AMIGAOS4 # define __USE_INLINE__ # define __NOLIBBASE__ # define __NOGLOBALIFACE__ #endif #include <proto/exec.h> #ifdef OF_AMIGAOS4 extern struct ExecIFace *IExec; #endif bool of_mutex_new(of_mutex_t *mutex) { InitSemaphore(mutex); return true; |
︙ | ︙ |
Modified src/thread.h from [a6bfb58593] to [a4fe604036].
︙ | ︙ | |||
16 17 18 19 20 21 22 | */ #include "objfw-defs.h" #include "platform.h" #if !defined(OF_HAVE_THREADS) || \ | | > > > > > > > > > > > > | | > > > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | */ #include "objfw-defs.h" #include "platform.h" #if !defined(OF_HAVE_THREADS) || \ (!defined(OF_HAVE_PTHREADS) && !defined(OF_WINDOWS) && !defined(OF_AMIGAOS)) # error No threads available! #endif #import "macros.h" #if defined(OF_HAVE_PTHREADS) # include <pthread.h> typedef pthread_t of_thread_t; #elif defined(OF_WINDOWS) # include <windows.h> typedef HANDLE of_thread_t; #elif defined(OF_AMIGAOS) # include <exec/tasks.h> # include <exec/semaphores.h> typedef struct { struct Task *task; void (*function)(id); id object; struct SignalSemaphore semaphore; struct Task *joinTask; uint8_t joinSigBit; bool detached, done; } *of_thread_t; #endif typedef struct of_thread_attr_t { float priority; size_t stackSize; } of_thread_attr_t; #if defined(OF_HAVE_PTHREADS) # define of_thread_is_current(t) pthread_equal(t, pthread_self()) # define of_thread_current() pthread_self() #elif defined(OF_WINDOWS) # define of_thread_is_current(t) (t == GetCurrentThread()) # define of_thread_current() GetCurrentThread() #elif defined(OF_AMIGAOS) # define of_thread_is_current(t) (t->thread == FindTask(NULL)) extern of_thread_t of_thread_current(void); #endif #ifdef __cplusplus extern "C" { #endif extern bool of_thread_attr_init(of_thread_attr_t *attr); extern bool of_thread_new(of_thread_t *thread, void (*function)(id), id object, |
︙ | ︙ |
Modified src/thread.m from [97cad1fce3] to [4db82960e0].
︙ | ︙ | |||
19 20 21 22 23 24 25 26 | #import "thread.h" #if defined(OF_HAVE_PTHREADS) # include "thread_pthread.m" #elif defined(OF_WINDOWS) # include "thread_winapi.m" #endif | > > | 19 20 21 22 23 24 25 26 27 28 | #import "thread.h" #if defined(OF_HAVE_PTHREADS) # include "thread_pthread.m" #elif defined(OF_WINDOWS) # include "thread_winapi.m" #elif defined(OF_AMIGAOS) # include "thread_amiga.m" #endif |
Added src/thread_amiga.m version [a7fd919f6d].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018, 2019 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #ifdef OF_AMIGAOS4 # define __USE_INLINE__ # define __NOLIBBASE__ # define __NOGLOBALIFACE__ #endif #include <dos/dostags.h> #include <proto/dos.h> #include <proto/exec.h> #import "OFData.h" #import "tlskey.h" extern void of_tlskey_thread_exited(void); static of_tlskey_t threadKey; #ifdef OF_AMIGAOS4 extern struct ExecIFace *IExec; static struct Library *DOSBase = NULL; static struct DOSIFace *IDOS = NULL; OF_CONSTRUCTOR() { DOSBase = OpenLibrary("dos.library", 36); OF_ENSURE(DOSBase != NULL); IDOS = (struct DOSIFace *)GetInterface(DOSBase, "main", 1, NULL); OF_ENSURE(IDOS != NULL); } OF_DESTRUCTOR() { if (IDOS != NULL) DropInterface((struct Interface *)IDOS); if (DOSBase != NULL) CloseLibrary(DOSBase); } #endif OF_CONSTRUCTOR() { OF_ENSURE(of_tlskey_new(&threadKey)); } static void functionWrapper(void) { bool detached = false; of_thread_t thread = (of_thread_t)((struct Process *)FindTask(NULL))->pr_ExitData; OF_ENSURE(of_tlskey_set(threadKey, thread)); thread->function(thread->object); ObtainSemaphore(&thread->semaphore); @try { thread->done = true; of_tlskey_thread_exited(); if (thread->detached) detached = true; else if (thread->joinTask != NULL) Signal(thread->joinTask, 1 << thread->joinSigBit); } @finally { ReleaseSemaphore(&thread->semaphore); } if (detached) free(thread); } bool of_thread_attr_init(of_thread_attr_t *attr) { attr->priority = 0; attr->stackSize = 0; return true; } bool of_thread_new(of_thread_t *thread, void (*function)(id), id object, const of_thread_attr_t *attr) { OFMutableData *tags = nil; if ((*thread = calloc(1, sizeof(**thread))) == NULL) return false; @try { (*thread)->function = function; (*thread)->object = object; InitSemaphore(&(*thread)->semaphore); tags = [[OFMutableData alloc] initWithItemSize: sizeof(struct TagItem) capacity: 12]; #define ADD_TAG(tag, data) \ { \ struct TagItem t = { \ .ti_Tag = tag, \ .ti_Data = data \ }; \ [tags addItem: &t]; \ } ADD_TAG(NP_Entry, (ULONG)functionWrapper) ADD_TAG(NP_ExitData, (ULONG)*thread) #ifdef OF_AMIGAOS4 ADD_TAG(NP_Child, TRUE) #endif #ifdef OF_MORPHOS ADD_TAG(NP_CodeType, CODETYPE_PPC); #endif ADD_TAG(NP_Input, ((struct Process *)FindTask(NULL))->pr_CIS) ADD_TAG(NP_Output, ((struct Process *)FindTask(NULL))->pr_COS) ADD_TAG(NP_Error, ((struct Process *)FindTask(NULL))->pr_CES) ADD_TAG(NP_CloseInput, FALSE) ADD_TAG(NP_CloseOutput, FALSE) ADD_TAG(NP_CloseError, FALSE) if (attr != NULL && attr->priority != 0) { if (attr->priority < 1 || attr->priority > 1) return false; /* * -1 should be -128 (lowest possible priority) while * +1 should be +127 (highest possible priority). */ ADD_TAG(NP_Priority, (attr->priority > 0 ? attr->priority * 127 : attr->priority * 128)) } ADD_TAG(NP_StackSize, (attr != NULL && attr->stackSize != 0 ? (LONG)attr->stackSize : ((struct Process *)FindTask(NULL))->pr_StackSize)) ADD_TAG(TAG_DONE, 0) #undef ADD_TAG (*thread)->task = (struct Task *)CreateNewProc(tags.items); if ((*thread)->task == NULL) { free(*thread); return false; } } @catch (id e) { free(*thread); @throw e; } @finally { [tags release]; } return true; } of_thread_t of_thread_current(void) { return of_tlskey_get(threadKey); } bool of_thread_join(of_thread_t thread) { bool ret; ObtainSemaphore(&thread->semaphore); @try { if (thread->done) { free(thread); return true; } if (thread->detached || thread->joinTask != NULL) return false; if ((thread->joinSigBit = AllocSignal(-1)) == -1) return false; thread->joinTask = FindTask(NULL); } @finally { ReleaseSemaphore(&thread->semaphore); } Wait(1 << thread->joinSigBit); FreeSignal(thread->joinSigBit); ret = thread->done; free(thread); return ret; } bool of_thread_detach(of_thread_t thread) { ObtainSemaphore(&thread->semaphore); if (thread->done) free(thread); else thread->detached = true; ReleaseSemaphore(&thread->semaphore); return true; } void of_thread_set_name(const char *name) { } |
Modified src/thread_winapi.m from [e19ec23cc7] to [773437e43e].
︙ | ︙ | |||
11 12 13 14 15 16 17 | * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ | < < | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "macros.h" bool of_thread_attr_init(of_thread_attr_t *attr) { attr->priority = 0; attr->stackSize = 0; |
︙ | ︙ |
Modified src/tlskey.h from [a0b1148f7c] to [7c0440c23c].
︙ | ︙ | |||
29 30 31 32 33 34 35 | #if defined(OF_HAVE_PTHREADS) # include <pthread.h> typedef pthread_key_t of_tlskey_t; #elif defined(OF_WINDOWS) # include <windows.h> typedef DWORD of_tlskey_t; #elif defined(OF_AMIGAOS) | | > | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | #if defined(OF_HAVE_PTHREADS) # include <pthread.h> typedef pthread_key_t of_tlskey_t; #elif defined(OF_WINDOWS) # include <windows.h> typedef DWORD of_tlskey_t; #elif defined(OF_AMIGAOS) # import "OFList.h" @class OFMapTable; typedef struct { OFMapTable *mapTable; of_list_object_t *listObject; } *of_tlskey_t; #endif #ifdef __cplusplus extern "C" { #endif extern bool of_tlskey_new(of_tlskey_t *key); |
︙ | ︙ |
Modified src/tlskey.m from [b1dffe2b41] to [22af5740b4].
︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | */ #include "config.h" #import "tlskey.h" #ifdef OF_AMIGAOS # import "OFMapTable.h" static const of_map_table_functions_t functions = { NULL }; #endif bool of_tlskey_new(of_tlskey_t *key) { #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) | > > > > > > > > > > > > > > > > > > > | > > > | | > > > > > > > > > > > > > > > | | < < | | | < < | > > > > > > > > > > > > > > > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | */ #include "config.h" #import "tlskey.h" #ifdef OF_AMIGAOS # ifdef OF_AMIGAOS4 # define __USE_INLINE__ # define __NOLIBBASE__ # define __NOGLOBALIFACE__ # endif # include <exec/semaphores.h> # include <proto/exec.h> # import "OFMapTable.h" # import "OFList.h" # ifdef OF_AMIGAOS4 extern struct ExecIFace *IExec; # endif static const of_map_table_functions_t functions = { NULL }; static OFList *allKeys = nil; static struct SignalSemaphore semaphore; OF_CONSTRUCTOR() { InitSemaphore(&semaphore); } #endif bool of_tlskey_new(of_tlskey_t *key) { #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) return false; /* * We create the map table lazily, as some TLS are created in * constructors, at which time OFMapTable is not available yet. */ return true; #endif } bool of_tlskey_free(of_tlskey_t key) { #if defined(OF_HAVE_PTHREADS) return (pthread_key_delete(key) == 0); #elif defined(OF_WINDOWS) return TlsFree(key); #elif defined(OF_AMIGAOS) ObtainSemaphore(&semaphore); @try { [allKeys removeListObject: key->listObject]; [key->mapTable release]; free(key); } @finally { ReleaseSemaphore(&semaphore); } 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); ret = [key->mapTable objectForKey: FindTask(NULL)]; } @finally { ReleaseSemaphore(&semaphore); } return ret; } bool of_tlskey_set(of_tlskey_t key, void *ptr) { ObtainSemaphore(&semaphore); @try { struct Task *task = FindTask(NULL); if (key->mapTable == NULL) unsafeCreateMapTable(key); if (ptr == NULL) [key->mapTable removeObjectForKey: task]; else [key->mapTable setObject: ptr forKey: task]; } @catch (id e) { return false; } @finally { ReleaseSemaphore(&semaphore); } return true; } void of_tlskey_thread_exited(void) { 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]; } @finally { ReleaseSemaphore(&semaphore); } } #endif |