disable the unrecognized nls flag
[AROS-Contrib.git] / regina / mt_amigalib.c
blob3c09d9bda549337d87fc682f015fe2ab3da463e4
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>
20 #include <aros/symbolsets.h>
22 #include <assert.h>
24 APTR __regina_semaphorepool;
26 typedef struct _mt_tsd_t {
27 APTR mempool;
28 } mt_tsd_t;
31 /* Lowest level memory allocation function for normal circumstances. */
32 static void *MTMalloc(const tsd_t *TSD,size_t size)
34 mt_tsd_t *mt = (mt_tsd_t *)TSD->mt_tsd;
35 void *mem;
37 size += sizeof(size_t);
38 mem = AllocPooled( mt->mempool, size);
39 if ( mem == NULL )
40 return NULL;
42 *((size_t*)mem)=size;
43 return (void *)(((char *)mem)+sizeof(size_t));
46 /* Lowest level memory deallocation function for normal circumstances. */
47 static void MTFree(const tsd_t *TSD,void *chunk)
49 mt_tsd_t *mt = (mt_tsd_t *)TSD->mt_tsd;
50 APTR mem = (APTR)(((char *)chunk)-sizeof(size_t));
52 FreePooled( mt->mempool, (APTR)mem, *(size_t *)mem );
55 /* Lowest level exit handler. Use this indirection to prevent errors. */
56 static void MTExit(int code)
58 D(bug("[mt_amigalib::MTExit] exiting with code=%d\n", code));
60 exit(code);
63 void exit_amigaf( APTR ); /* In amifuncs.c */
65 static void cleanup(int dummy, void *ptr)
67 tsd_node_t *node = (tsd_node_t *)ptr;
68 mt_tsd_t *mt = (mt_tsd_t *)node->TSD->mt_tsd;
70 D(bug("[mt_amigalib::cleanup] node=%p\n"));
72 exit_amigaf( node->TSD->ami_tsd );
74 DeletePool( mt->mempool );
76 node->TSD = NULL; /* Node is cleared */
79 int IfcReginaCleanup( VOID )
81 /* Do nothing, currently cleanup is done through on_exit function */
82 return 1;
85 tsd_t *ReginaInitializeThread(void)
87 int OK;
89 tsd_t *__regina_tsd = malloc(sizeof(tsd_t));
90 mt_tsd_t *mt;
92 D(bug("[mt_amigalib::ReginaInitializeThread] TSD=%p\n", __regina_tsd));
94 /* Default all values to zero */
95 memset(__regina_tsd,0,sizeof(tsd_t));
96 __regina_tsd->MTMalloc = MTMalloc;
97 __regina_tsd->MTFree = MTFree;
98 __regina_tsd->MTExit = MTExit;
100 OK = ( __regina_tsd->mt_tsd = malloc(sizeof(mt_tsd_t))) != NULL;
101 mt = (mt_tsd_t *)__regina_tsd->mt_tsd;
102 OK &= ( mt->mempool = CreatePool(MEMF_PUBLIC, 8192, 1024) ) != NULL;
104 OK &= init_memory(__regina_tsd); /* Initialize the memory module FIRST*/
106 D(bug("[mt_amigalib::ReginaInitializeThread] TSD->mem_tsd=%p\n", __regina_tsd->mem_tsd));
108 /* Without the initial memory we don't have ANY chance! */
109 if (!OK)
110 return(NULL);
113 extern OS_Dep_funcs __regina_OS_Amiga;
114 __regina_tsd->OS = &__regina_OS_Amiga;
117 OK &= init_vars(__regina_tsd); /* Initialize the variable module */
118 OK &= init_stacks(__regina_tsd); /* Initialize the stack module */
119 OK &= init_filetable(__regina_tsd); /* Initialize the files module */
120 OK &= init_math(__regina_tsd); /* Initialize the math module */
121 OK &= init_spec_vars(__regina_tsd); /* Initialize the interprt module */
122 OK &= init_tracing(__regina_tsd); /* Initialize the tracing module */
123 OK &= init_builtin(__regina_tsd); /* Initialize the builtin module */
124 OK &= init_client(__regina_tsd); /* Initialize the client module */
125 OK &= init_library(__regina_tsd); /* Initialize the library module */
126 OK &= init_rexxsaa(__regina_tsd); /* Initialize the rexxsaa module */
127 OK &= init_shell(__regina_tsd); /* Initialize the shell module */
128 OK &= init_envir(__regina_tsd); /* Initialize the envir module */
129 OK &= init_expr(__regina_tsd); /* Initialize the expr module */
130 OK &= init_error(__regina_tsd); /* Initialize the error module */
131 #ifdef VMS
132 OK &= init_vms(__regina_tsd); /* Initialize the vmscmd module */
133 OK &= init_vmf(__regina_tsd); /* Initialize the vmsfuncs module */
134 #endif
135 OK &= init_arexxf(__regina_tsd); /* Initialize the arexxfuncs module */
136 OK &= init_amigaf(__regina_tsd); /* Initialize the amigafuncs module */
137 __regina_tsd->loopcnt = 1; /* stupid r2perl-module */
138 __regina_tsd->traceparse = -1;
139 __regina_tsd->thread_id = 1;
141 /* Initiliaze thread specific data */
142 if (!OK)
143 exiterror( ERR_STORAGE_EXHAUSTED, 0 ) ;
145 return(__regina_tsd);
148 void AmigaLockSemaphore(struct SignalSemaphore **semaphoreptr)
150 if (*semaphoreptr == NULL)
152 Forbid();
154 if (*semaphoreptr == NULL)
156 *semaphoreptr = AllocPooled (__regina_semaphorepool, sizeof(struct SignalSemaphore));
157 InitSemaphore(*semaphoreptr);
160 Permit();
163 ObtainSemaphore(*semaphoreptr);
166 void AmigaUnlockSemaphore(struct SignalSemaphore *semaphore)
168 assert(semaphore!=NULL);
169 ReleaseSemaphore(semaphore);
173 tsd_t *__regina_get_tsd(void)
175 struct Task *thistask = FindTask(NULL);
176 tsd_node_t *node;
178 D(bug("[mt_amigalib::__regina_get_tsd] thistask=%p\n", thistask));
180 node = (tsd_node_t *)GetHead(__regina_tsdlist);
181 while (node!=NULL && node->task!=thistask)
182 node = (tsd_node_t *)GetSucc(node);
184 D(bug("[mt_amigalib::__regina_get_tsd] node=%p\n", node));
186 if (node==NULL)
188 /* taskdata not found */
189 node = (tsd_node_t *)AllocPooled(__regina_semaphorepool, sizeof(tsd_node_t));
190 node->task = thistask;
191 node->TSD = ReginaInitializeThread();
192 AddTail((struct List *)__regina_tsdlist, (struct Node *)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 D(bug("[mt_amigalib::__regina_get_tsd] new TSD=%p\n", node->TSD));
201 return node->TSD;
204 /* Run cleanup on closing of per-task library base */
205 void CloseLib(APTR base)
207 struct Task *thistask = FindTask(NULL);
208 tsd_node_t *node;
210 node = (tsd_node_t *)GetHead(__regina_tsdlist);
211 while (node!=NULL && node->task!=thistask)
212 node = (tsd_node_t *)GetSucc(node);
214 if (node!=NULL)
215 cleanup(0, node);
218 ADD2CLOSELIB(CloseLib, 0);