1
#define PDL_CORE /* For certain ifdefs */
10
/* Singly linked list */
11
/* Note that this zeroes ->next!) */
13
void pdl__magic_add(pdl *it,pdl_magic *mag)
15
pdl_magic **foo = &(it->magic);
17
foo = &((*foo)->next);
23
void pdl__magic_rm(pdl *it,pdl_magic *mag)
25
pdl_magic **foo = &(it->magic);
30
foo = &((*foo)->next);
32
die("PDL:Magic not found: Internal error\n");
35
/* Test for undestroyability */
37
int pdl__magic_isundestroyable(pdl *it)
39
pdl_magic **foo = &(it->magic);
41
if((*foo)->what & PDL_MAGIC_UNDESTROYABLE) {return 1;}
42
foo = &((*foo)->next);
49
void *pdl__call_magic(pdl *it,int which)
52
pdl_magic **foo = &(it->magic);
54
if((*foo)->what & which) {
55
if((*foo)->what & PDL_MAGIC_DELAYED)
56
pdl_add_delayed_magic(*foo);
58
ret = (void *)((*foo)->vtable->cast(*foo));
61
foo = &((*foo)->next);
66
/* XXX FINDS ONLY FIRST */
67
pdl_magic *pdl__find_magic(pdl *it, int which)
69
pdl_magic **foo = &(it->magic);
71
if((*foo)->what & which) {
74
foo = &((*foo)->next);
79
pdl_magic *pdl__print_magic(pdl *it)
81
pdl_magic **foo = &(it->magic);
83
printf("Magic %d\ttype: ",*foo);
84
if((*foo)->what & PDL_MAGIC_MARKCHANGED)
85
printf("PDL_MAGIC_MARKCHANGED");
86
else if ((*foo)->what & PDL_MAGIC_MUTATEDPARENT)
87
printf("PDL_MAGIC_MUTATEDPARENT");
88
else if ((*foo)->what & PDL_MAGIC_THREADING)
89
printf("PDL_MAGIC_THREADING");
92
if ((*foo)->what & (PDL_MAGIC_DELAYED|PDL_MAGIC_UNDESTROYABLE))
94
printf(" qualifier(s): ");
95
if ((*foo)->what & PDL_MAGIC_DELAYED)
96
printf(" PDL_MAGIC_DELAYED");
97
if ((*foo)->what & PDL_MAGIC_UNDESTROYABLE)
98
printf(" PDL_MAGIC_UNDESTROYABLE");
101
foo = &((*foo)->next);
107
int pdl__ismagic(pdl *it)
109
return (it->magic != 0);
112
static pdl_magic **delayed=NULL;
113
static int ndelayed = 0;
114
void pdl_add_delayed_magic(pdl_magic *mag) {
115
delayed = realloc(delayed,sizeof(*delayed)*++ndelayed);
116
delayed[ndelayed-1] = mag;
118
void pdl_run_delayed_magic() {
120
pdl_magic **oldd = delayed; /* In case someone makes new delayed stuff */
124
for(i=0; i<nold; i++) {
125
oldd[i]->vtable->cast(oldd[i]);
135
void *svmagic_cast(pdl_magic *mag)
137
pdl_magic_perlfunc *magp = (pdl_magic_perlfunc *)mag;
140
perl_call_sv(magp->sv, G_DISCARD | G_NOARGS);
144
static pdl_magic_vtable svmagic_vtable = {
149
pdl_magic *pdl_add_svmagic(pdl *it,SV *func)
152
pdl_magic_perlfunc *ptr = malloc(sizeof(pdl_magic_perlfunc));
153
ptr->what = PDL_MAGIC_MARKCHANGED | PDL_MAGIC_DELAYED;
154
ptr->vtable = &svmagic_vtable;
155
ptr->sv = newSVsv(func);
158
pdl__magic_add(it,(pdl_magic *)ptr);
159
if(it->state & PDL_ANYCHANGED)
160
pdl_add_delayed_magic((pdl_magic *)ptr);
161
/* In order to have our SV destroyed in time for the interpreter, */
162
/* XXX Work this out not to memleak */
163
av = perl_get_av("PDL::disposable_svmagics",TRUE);
165
return (pdl_magic *)ptr;
174
pdl_trans *pdl_find_mutatedtrans(pdl *it)
176
if(!it->magic) return 0;
177
return pdl__call_magic(it,PDL_MAGIC_MUTATEDPARENT);
180
static void *fammutmagic_cast(pdl_magic *mag)
182
pdl_magic_fammut *magp = (pdl_magic_fammut *)mag;
186
struct pdl_magic_vtable familymutmagic_vtable = {
191
pdl_magic *pdl_add_fammutmagic(pdl *it,pdl_trans *ft)
193
pdl_magic_fammut *ptr = malloc(sizeof(pdl_magic_fammut));
194
ptr->what = PDL_MAGIC_MUTATEDPARENT;
195
ptr->vtable = &familymutmagic_vtable;
199
pdl__magic_add(it,(pdl_magic *)ptr);
200
return (pdl_magic *)ptr;
213
typedef struct ptarg {
214
pdl_magic_pthread *mag;
215
void (*func)(pdl_trans *);
220
int pdl_pthreads_enabled(void) {return 1;}
222
static void *pthread_perform(void *vp) {
223
struct ptarg *p = (ptarg *)vp;
224
if(TVERB) printf("STARTING THREAD %d (%d)\n",p->no, pthread_self());
225
pthread_setspecific(p->mag->key,(void *)&(p->no));
227
if(TVERB) printf("ENDING THREAD %d (%d)\n",p->no, pthread_self());
231
int pdl_magic_thread_nthreads(pdl *it,int *nthdim) {
232
pdl_magic_pthread *ptr = (pdl_magic_pthread *)pdl__find_magic(it,
233
PDL_MAGIC_THREADING);
235
*nthdim = ptr->nthdim;
236
return ptr->nthreads;
239
int pdl_magic_get_thread(pdl *it) { /* XXX -> only one thread can handle pdl at once */
240
pdl_magic_pthread *ptr;
242
ptr = (pdl_magic_pthread *)pdl__find_magic(it,
243
PDL_MAGIC_THREADING);
244
if(!ptr) {die("Invalid pdl_magic_get_thread!");}
245
p = (int*)pthread_getspecific(ptr->key);
247
die("Invalid pdl_magic_get_thread specific!!!!");
252
void pdl_magic_thread_cast(pdl *it,void (*func)(pdl_trans *),pdl_trans *t) {
253
pdl_magic_pthread *ptr; pthread_t *tp; ptarg *tparg;
255
ptr = (pdl_magic_pthread *)pdl__find_magic(it,
256
PDL_MAGIC_THREADING);
257
if(!ptr) {die("Invalid pdl_magic_thread_cast!");}
258
tp = malloc(sizeof(pthread_t) * ptr->nthreads);
259
tparg = malloc(sizeof(*tparg) * ptr->nthreads);
260
pthread_key_create(&(ptr->key),NULL);
261
if(TVERB) printf("CREATING THREADS, ME: %d, key: %d\n",pthread_self(),
263
for(i=0; i<ptr->nthreads; i++) {
265
tparg[i].func = func;
268
pthread_create(tp+i, NULL, pthread_perform, tparg+i);
270
if(TVERB) printf("JOINING THREADS, ME: %d, key: %d\n",pthread_self(),
272
for(i=0; i<ptr->nthreads; i++) {
273
pthread_join(tp[i], NULL);
275
if(TVERB) printf("FINISHED THREADS, ME: %d, key: %d\n",pthread_self(),
277
pthread_key_delete((ptr->key));
280
void pdl_add_threading_magic(pdl *it,int nthdim,int nthreads)
282
pdl_magic_pthread *ptr = malloc(sizeof(pdl_magic_pthread));
283
ptr->what = PDL_MAGIC_THREADING;
286
ptr->nthdim = nthdim;
287
ptr->nthreads = nthreads;
288
pdl__magic_add(it,(pdl_magic *)ptr);
293
void pdl_add_threading_magic(pdl *it,int nthdim,int nthreads) {}
294
int pdl_magic_get_thread(pdl *it) {return 0;}
295
void pdl_magic_thread_cast(pdl *it,void (*func)(pdl_trans *),pdl_trans *t) {}
296
int pdl_magic_thread_nthreads(pdl *it,int *nthdim) {return 0;}
297
int pdl_pthreads_enabled() {return 0;}
300
/***************************
307
void pdl_delete_mmapped_data(pdl *p, int param)
310
if(!p->data) {return;}
312
munmap(p->data, param);
314
croak("internal error: trying to delete mmaped data on unsupported platform");
319
static void *delete_mmapped_cast(pdl_magic *mag)
321
pdl_magic_deletedata *magp = (pdl_magic_deletedata *)mag;
322
magp->func(magp->pdl, magp->param);
326
struct pdl_magic_vtable deletedatamagic_vtable = {
331
void pdl_add_deletedata_magic(pdl *it, void (*func)(pdl *, int param), int param)
333
pdl_magic_deletedata *ptr = malloc(sizeof(pdl_magic_deletedata));
334
ptr->what = PDL_MAGIC_DELETEDATA;
335
ptr->vtable = &deletedatamagic_vtable;
339
pdl__magic_add(it, (pdl_magic *)ptr);