We can't link with bz2 anymore because it's now a shared
[AROS-Contrib.git] / regina / mt_amigalib.c
blob481f8a9346eb00d00ffe67df9cb9c4d5f1438812
1 /* This is the file to support single-threading.
2 * We initialize the global data structure and the global access variable.
3 */
5 #if !defined(__AROS__) && !defined(_AMIGA)
6 # error mt_amiga.c only works on Amiga or AROS
7 #endif
9 #if !defined(RXLIB)
10 # error compiling mt_amiga.c without being a library does not make sense
11 #endif
13 #include "rexx.h"
15 #include <proto/alib.h>
16 #include <exec/memory.h>
18 #define DEBUG 0
19 #include <aros/debug.h>
21 #include <assert.h>
23 APTR __regina_semaphorepool;
25 typedef struct _mt_tsd_t {
26 APTR mempool;
27 } mt_tsd_t;
30 /* Lowest level memory allocation function for normal circumstances. */
31 static void *MTMalloc(const tsd_t *TSD,size_t size)
33 mt_tsd_t *mt = (mt_tsd_t *)TSD->mt_tsd;
34 void *mem;
36 size += sizeof(size_t);
37 mem = AllocPooled( mt->mempool, size);
38 if ( mem == NULL )
39 return NULL;
41 *((size_t*)mem)=size;
42 return (void *)(((char *)mem)+sizeof(size_t));
45 /* Lowest level memory deallocation function for normal circumstances. */
46 static void MTFree(const tsd_t *TSD,void *chunk)
48 mt_tsd_t *mt = (mt_tsd_t *)TSD->mt_tsd;
49 APTR mem = (APTR)(((char *)chunk)-sizeof(size_t));
51 FreePooled( mt->mempool, (APTR)mem, *(size_t *)mem );
54 /* Lowest level exit handler. Use this indirection to prevent errors. */
55 static void MTExit(int code)
57 D(bug("[mt_amigalib::MTExit] exiting with code=%d\n", code));
59 exit(code);
62 void exit_amigaf( APTR ); /* In amifuncs.c */
64 static void cleanup(int dummy, void *ptr)
66 tsd_node_t *node = (tsd_node_t *)ptr;
67 mt_tsd_t *mt = (mt_tsd_t *)node->TSD->mt_tsd;
69 D(bug("[mt_amigalib::cleanup] node=%p\n"));
71 exit_amigaf( node->TSD->ami_tsd );
73 DeletePool( mt->mempool );
75 node->TSD = NULL; /* Node is cleared */
78 int IfcReginaCleanup( VOID )
80 /* Do nothing, currently cleanup is done through on_exit function */
81 return 1;
84 tsd_t *ReginaInitializeThread(void)
86 int OK;
88 tsd_t *__regina_tsd = malloc(sizeof(tsd_t));
89 mt_tsd_t *mt;
91 D(bug("[mt_amigalib::ReginaInitializeThread] TSD=%p\n", __regina_tsd));
93 /* Default all values to zero */
94 memset(__regina_tsd,0,sizeof(tsd_t));
95 __regina_tsd->MTMalloc = MTMalloc;
96 __regina_tsd->MTFree = MTFree;
97 __regina_tsd->MTExit = MTExit;
99 OK = ( __regina_tsd->mt_tsd = malloc(sizeof(mt_tsd_t))) != NULL;
100 mt = (mt_tsd_t *)__regina_tsd->mt_tsd;
101 OK &= ( mt->mempool = CreatePool(MEMF_PUBLIC, 8192, 1024) ) != NULL;
103 OK &= init_memory(__regina_tsd); /* Initialize the memory module FIRST*/
105 D(bug("[mt_amigalib::ReginaInitializeThread] TSD->mem_tsd=%p\n", __regina_tsd->mem_tsd));
107 /* Without the initial memory we don't have ANY chance! */
108 if (!OK)
109 return(NULL);
112 extern OS_Dep_funcs __regina_OS_Amiga;
113 __regina_tsd->OS = &__regina_OS_Amiga;
116 OK &= init_vars(__regina_tsd); /* Initialize the variable module */
117 OK &= init_stacks(__regina_tsd); /* Initialize the stack module */
118 OK &= init_filetable(__regina_tsd); /* Initialize the files module */
119 OK &= init_math(__regina_tsd); /* Initialize the math module */
120 OK &= init_spec_vars(__regina_tsd); /* Initialize the interprt module */
121 OK &= init_tracing(__regina_tsd); /* Initialize the tracing module */
122 OK &= init_builtin(__regina_tsd); /* Initialize the builtin module */
123 OK &= init_client(__regina_tsd); /* Initialize the client module */
124 OK &= init_library(__regina_tsd); /* Initialize the library module */
125 OK &= init_rexxsaa(__regina_tsd); /* Initialize the rexxsaa module */
126 OK &= init_shell(__regina_tsd); /* Initialize the shell module */
127 OK &= init_envir(__regina_tsd); /* Initialize the envir module */
128 OK &= init_expr(__regina_tsd); /* Initialize the expr module */
129 OK &= init_error(__regina_tsd); /* Initialize the error module */
130 #ifdef VMS
131 OK &= init_vms(__regina_tsd); /* Initialize the vmscmd module */
132 OK &= init_vmf(__regina_tsd); /* Initialize the vmsfuncs module */
133 #endif
134 OK &= init_arexxf(__regina_tsd); /* Initialize the arexxfuncs module */
135 OK &= init_amigaf(__regina_tsd); /* Initialize the amigafuncs module */
136 __regina_tsd->loopcnt = 1; /* stupid r2perl-module */
137 __regina_tsd->traceparse = -1;
138 __regina_tsd->thread_id = 1;
140 /* Initiliaze thread specific data */
141 if (!OK)
142 exiterror( ERR_STORAGE_EXHAUSTED, 0 ) ;
144 return(__regina_tsd);
147 void AmigaLockSemaphore(struct SignalSemaphore **semaphoreptr)
149 if (*semaphoreptr == NULL)
151 Forbid();
153 if (*semaphoreptr == NULL)
155 *semaphoreptr = AllocPooled (__regina_semaphorepool, sizeof(struct SignalSemaphore));
156 InitSemaphore(*semaphoreptr);
159 Permit();
162 ObtainSemaphore(*semaphoreptr);
165 void AmigaUnlockSemaphore(struct SignalSemaphore *semaphore)
167 assert(semaphore!=NULL);
168 ReleaseSemaphore(semaphore);
172 tsd_t *__regina_get_tsd(void)
174 struct Task *thistask = FindTask(NULL);
175 tsd_node_t *node;
177 D(bug("[mt_amigalib::__regina_get_tsd] thistask=%p\n", thistask));
179 node = (tsd_node_t *)GetHead(__regina_tsdlist);
180 while (node!=NULL && node->task!=thistask)
181 node = (tsd_node_t *)GetSucc(node);
183 D(bug("[mt_amigalib::__regina_get_tsd] node=%p\n", node));
185 if (node==NULL)
187 /* taskdata not found */
188 node = (tsd_node_t *)AllocPooled(__regina_semaphorepool, sizeof(tsd_node_t));
189 node->task = thistask;
190 node->TSD = ReginaInitializeThread();
191 AddTail((struct List *)__regina_tsdlist, (struct Node *)node);
192 on_exit(cleanup, node);
193 D(bug("[mt_amigalib::__regina_get_tsd] new node=%p, TSD=%p\n", node, node->TSD));
195 else if (node->TSD==NULL) /* Was MTExit called on this task ? */
197 node->TSD = ReginaInitializeThread();
198 on_exit(cleanup, node);
199 D(bug("[mt_amigalib::__regina_get_tsd] new TSD=%p\n", node->TSD));
202 return node->TSD;