23
23
typedef struct _tsrm_tls_entry tsrm_tls_entry ;
24
24
25
25
struct _tsrm_tls_entry {
26
- void * * storage ;
26
+ void * storage ;
27
27
int count ;
28
28
THREAD_T thread_id ;
29
29
tsrm_tls_entry * next ;
30
30
};
31
31
32
32
33
33
typedef struct {
34
+ ts_rsrc_offset offset ;
34
35
size_t size ;
35
36
ts_allocate_ctor ctor ;
36
37
ts_allocate_dtor dtor ;
@@ -42,7 +43,7 @@ typedef struct {
42
43
static tsrm_tls_entry * * tsrm_tls_table = NULL ;
43
44
static int tsrm_tls_table_size ;
44
45
static ts_rsrc_id id_count ;
45
-
46
+ static size_t rsrcs_size ;
46
47
/* The resource sizes table */
47
48
static tsrm_resource_type * resource_types_table = NULL ;
48
49
static int resource_types_table_size ;
@@ -61,31 +62,62 @@ int tsrm_error(int level, const char *format, ...);
61
62
static int tsrm_error_level ;
62
63
static FILE * tsrm_error_file ;
63
64
65
+ #ifdef USE___THREAD
66
+ TSRM_API TSRM_TLS void * tsrm_ls_cache = 0 ;
67
+ #endif
68
+
69
+ #ifdef PASS_TSRMLS
70
+ # define CALL_TSRMG_CTOR (ctor , globale , storage ) (ctor)((globale), (storage))
71
+ # define CALL_TSRMG_DTOR (ctor , globale , storage ) (ctor)((globale), (storage))
72
+ # define CALL_NEW_THREAD_BEGIN_HANDLER (thread_id , storage ) tsrm_new_thread_begin_handler((thread_id), (storage))
73
+ # define CALL_NEW_THREAD_END_HANDLER (thread_id , storage ) tsrm_new_thread_end_handler((thread_id), (storage))
74
+ #else
75
+ # define CALL_TSRMG_CTOR (ctor , globale , storage ) (ctor)((globale))
76
+ # define CALL_TSRMG_DTOR (ctor , globale , storage ) (ctor)((globale))
77
+ # define CALL_NEW_THREAD_BEGIN_HANDLER (thread_id , storage ) tsrm_new_thread_begin_handler((thread_id))
78
+ # define CALL_NEW_THREAD_END_HANDLER (thread_id , storage ) tsrm_new_thread_end_handler((thread_id))
79
+ #endif
80
+
81
+ #ifndef TSRM_MM_ALIGNMENT
82
+ # define TSRM_MM_ALIGNMENT 8
83
+ #elif TSRM_MM_ALIGNMENT < 4
84
+ # undef TSRM_MM_ALIGNMENT
85
+ # define TSRM_MM_ALIGNMENT 8
86
+ #endif
87
+
88
+ #define TSRMG_PTR (storage , offset ) ((void *)((tsrm_uintptr_t)storage + offset))
89
+
90
+ #ifdef USE___THREAD
91
+ # define TSRM_RETURN_TSRM_LS (array ) array
92
+ #else
93
+ # define TSRM_RETURN_TSRM_LS (array ) &array
94
+ #endif
95
+
64
96
#if TSRM_DEBUG
65
97
#define TSRM_ERROR (args ) tsrm_error args
66
- #define TSRM_SAFE_RETURN_RSRC (array , offset , range ) \
98
+ #define TSRM_SAFE_RETURN_RSRC (array , id , range ) \
67
99
{ \
68
- int unshuffled_offset = TSRM_UNSHUFFLE_RSRC_ID(offset ); \
100
+ int unshuffled_id = TSRM_UNSHUFFLE_RSRC_ID(id ); \
69
101
\
70
- if (offset ==0) { \
71
- return & array; \
72
- } else if ((unshuffled_offset )>=0 && (unshuffled_offset )<(range)) { \
102
+ if (id ==0) { \
103
+ return TSRM_RETURN_TSRM_LS( array); \
104
+ } else if ((unshuffled_id )>=0 && (unshuffled_id )<(range)) { \
73
105
TSRM_ERROR((TSRM_ERROR_LEVEL_INFO, "Successfully fetched resource id %d for thread id %ld - 0x%0.8X", \
74
- unshuffled_offset , (long) thread_resources->thread_id, array[unshuffled_offset])); \
75
- return array[unshuffled_offset]; \
106
+ unshuffled_id , (long) thread_resources->thread_id, TSRMG_PTR( array, resource_types_table[unshuffled_id].offset))); \
107
+ return TSRMG_PTR( array, resource_types_table[unshuffled_id].offset); \
76
108
} else { \
77
109
TSRM_ERROR((TSRM_ERROR_LEVEL_ERROR, "Resource id %d is out of range (%d..%d)", \
78
- unshuffled_offset , TSRM_SHUFFLE_RSRC_ID(0), TSRM_SHUFFLE_RSRC_ID(thread_resources->count-1))); \
110
+ unshuffled_id , TSRM_SHUFFLE_RSRC_ID(0), TSRM_SHUFFLE_RSRC_ID(thread_resources->count-1))); \
79
111
return NULL; \
80
112
} \
81
113
}
82
114
#else
83
115
#define TSRM_ERROR (args )
84
- #define TSRM_SAFE_RETURN_RSRC (array , offset , range ) \
85
- if (offset ==0) { \
86
- return & array; \
87
- } else { \
88
- return array[TSRM_UNSHUFFLE_RSRC_ID(offset)] ; \
116
+ #define TSRM_SAFE_RETURN_RSRC (array , id , range ) \
117
+ if (id ==0) { \
118
+ return TSRM_RETURN_TSRM_LS( array); \
119
+ } else { \
120
+ return TSRMG_PTR( array, resource_types_table [TSRM_UNSHUFFLE_RSRC_ID(id)].offset) ; \
89
121
}
90
122
#endif
91
123
@@ -175,12 +207,9 @@ TSRM_API void tsrm_shutdown(void)
175
207
176
208
next_p = p -> next ;
177
209
for (j = 0 ; j < p -> count ; j ++ ) {
178
- if (p -> storage [j ]) {
179
- if (resource_types_table && !resource_types_table [j ].done && resource_types_table [j ].dtor ) {
180
- resource_types_table [j ].dtor (p -> storage [j ], & p -> storage );
181
- }
182
- free (p -> storage [j ]);
183
- }
210
+ if (resource_types_table && !resource_types_table [j ].done && resource_types_table [j ].dtor ) {
211
+ CALL_TSRMG_CTOR (resource_types_table [j ].dtor , TSRMG_PTR (p -> storage , resource_types_table [j ].offset ), & p -> storage );
212
+ }
184
213
}
185
214
free (p -> storage );
186
215
free (p );
@@ -212,9 +241,10 @@ TSRM_API void tsrm_shutdown(void)
212
241
213
242
214
243
/* allocates a new thread-safe-resource id */
215
- TSRM_API ts_rsrc_id ts_allocate_id (ts_rsrc_id * rsrc_id , size_t size , ts_allocate_ctor ctor , ts_allocate_dtor dtor )
244
+ TSRM_API ts_rsrc_id ts_allocate_id (ts_rsrc_id * rsrc_id , ts_rsrc_offset * rsrc_offset , size_t size , ts_allocate_ctor ctor , ts_allocate_dtor dtor )
216
245
{
217
246
int i ;
247
+ ts_rsrc_offset offset = 0 ;
218
248
219
249
TSRM_ERROR ((TSRM_ERROR_LEVEL_CORE , "Obtaining a new resource id, %d bytes" , size ));
220
250
@@ -235,6 +265,17 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate
235
265
}
236
266
resource_types_table_size = id_count ;
237
267
}
268
+
269
+ if (TSRM_UNSHUFFLE_RSRC_ID (* rsrc_id ) > 0 ) {
270
+ offset = resource_types_table [TSRM_UNSHUFFLE_RSRC_ID (* rsrc_id - 1 )].offset
271
+ + resource_types_table [TSRM_UNSHUFFLE_RSRC_ID (* rsrc_id - 1 )].size ;
272
+ }
273
+ offset = ((TSRM_MM_ALIGNMENT + offset - 1 ) & ~(TSRM_MM_ALIGNMENT - 1 ));
274
+ if (rsrc_offset ) {
275
+ * rsrc_offset = offset ;
276
+ }
277
+
278
+ resource_types_table [TSRM_UNSHUFFLE_RSRC_ID (* rsrc_id )].offset = offset ;
238
279
resource_types_table [TSRM_UNSHUFFLE_RSRC_ID (* rsrc_id )].size = size ;
239
280
resource_types_table [TSRM_UNSHUFFLE_RSRC_ID (* rsrc_id )].ctor = ctor ;
240
281
resource_types_table [TSRM_UNSHUFFLE_RSRC_ID (* rsrc_id )].dtor = dtor ;
@@ -248,21 +289,24 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate
248
289
if (p -> count < id_count ) {
249
290
int j ;
250
291
251
- p -> storage = (void * ) realloc (p -> storage , sizeof (void * )* id_count );
292
+ p -> storage = realloc (p -> storage , offset + size );
293
+ #ifdef USE___THREAD
294
+ tsrm_ls_cache = p -> storage ;
295
+ #endif
252
296
for (j = p -> count ; j < id_count ; j ++ ) {
253
- p -> storage [j ] = (void * ) malloc (resource_types_table [j ].size );
254
297
if (resource_types_table [j ].ctor ) {
255
- resource_types_table [j ].ctor (p -> storage [j ], & p -> storage );
298
+ CALL_TSRMG_CTOR ( resource_types_table [j ].ctor , TSRMG_PTR (p -> storage , resource_types_table [j ]. offset ) , & p -> storage );
256
299
}
257
300
}
258
301
p -> count = id_count ;
259
302
}
260
303
p = p -> next ;
261
304
}
262
305
}
306
+ rsrcs_size = offset + size ;
263
307
tsrm_mutex_unlock (tsmm_mutex );
264
308
265
- TSRM_ERROR ((TSRM_ERROR_LEVEL_CORE , "Successfully allocated new resource id %d" , * rsrc_id ));
309
+ TSRM_ERROR ((TSRM_ERROR_LEVEL_CORE , "Successfully allocated new resource id %d, offset %u " , * rsrc_id , * rsrc_offset ));
266
310
return * rsrc_id ;
267
311
}
268
312
@@ -273,31 +317,31 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_
273
317
274
318
TSRM_ERROR ((TSRM_ERROR_LEVEL_CORE , "Creating data structures for thread %x" , thread_id ));
275
319
(* thread_resources_ptr ) = (tsrm_tls_entry * ) malloc (sizeof (tsrm_tls_entry ));
276
- (* thread_resources_ptr )-> storage = ( void * * ) malloc (sizeof ( void * ) * id_count );
320
+ (* thread_resources_ptr )-> storage = malloc (rsrcs_size );
277
321
(* thread_resources_ptr )-> count = id_count ;
278
322
(* thread_resources_ptr )-> thread_id = thread_id ;
279
323
(* thread_resources_ptr )-> next = NULL ;
280
324
281
325
/* Set thread local storage to this new thread resources structure */
282
326
tsrm_tls_set (* thread_resources_ptr );
283
327
328
+ #ifdef USE___THREAD
329
+ tsrm_ls_cache = (* thread_resources_ptr )-> storage ;
330
+ #endif
331
+
284
332
if (tsrm_new_thread_begin_handler ) {
285
- tsrm_new_thread_begin_handler (thread_id , & (( * thread_resources_ptr )-> storage ) );
333
+ CALL_NEW_THREAD_BEGIN_HANDLER (thread_id , & (* thread_resources_ptr )-> storage );
286
334
}
287
335
for (i = 0 ; i < id_count ; i ++ ) {
288
336
if (resource_types_table [i ].done ) {
289
- (* thread_resources_ptr )-> storage [i ] = NULL ;
290
- } else
291
- {
292
- (* thread_resources_ptr )-> storage [i ] = (void * ) malloc (resource_types_table [i ].size );
293
337
if (resource_types_table [i ].ctor ) {
294
- resource_types_table [i ].ctor ((* thread_resources_ptr )-> storage [i ], & (* thread_resources_ptr )-> storage );
338
+ CALL_TSRMG_CTOR ( resource_types_table [i ].ctor , TSRMG_PTR ((* thread_resources_ptr )-> storage , resource_types_table [i ]. offset ) , & (* thread_resources_ptr )-> storage );
295
339
}
296
340
}
297
341
}
298
342
299
343
if (tsrm_new_thread_end_handler ) {
300
- tsrm_new_thread_end_handler (thread_id , & (( * thread_resources_ptr )-> storage ) );
344
+ CALL_NEW_THREAD_END_HANDLER (thread_id , & (* thread_resources_ptr )-> storage );
301
345
}
302
346
303
347
tsrm_mutex_unlock (tsmm_mutex );
@@ -390,12 +434,10 @@ void tsrm_free_interpreter_context(void *context)
390
434
391
435
for (i = 0 ; i < thread_resources -> count ; i ++ ) {
392
436
if (resource_types_table [i ].dtor ) {
393
- resource_types_table [i ].dtor (thread_resources -> storage [i ], & thread_resources -> storage );
437
+ CALL_TSRMG_DTOR ( resource_types_table [i ].dtor , TSRMG_PTR (thread_resources -> storage , resource_types_table [i ]. offset ) , & thread_resources -> storage );
394
438
}
395
439
}
396
- for (i = 0 ; i < thread_resources -> count ; i ++ ) {
397
- free (thread_resources -> storage [i ]);
398
- }
440
+
399
441
free (thread_resources -> storage );
400
442
free (thread_resources );
401
443
thread_resources = next ;
@@ -413,6 +455,10 @@ void *tsrm_set_interpreter_context(void *new_ctx)
413
455
414
456
/* Set thread local storage to this new thread resources structure */
415
457
tsrm_tls_set (new_ctx );
458
+
459
+ #ifdef USE___THREAD
460
+ tsrm_ls_cache = ((tsrm_tls_entry * )new_ctx )-> storage ;
461
+ #endif
416
462
417
463
/* return old context, so caller can restore it when they're done */
418
464
return current ;
@@ -455,12 +501,9 @@ void ts_free_thread(void)
455
501
if (thread_resources -> thread_id == thread_id ) {
456
502
for (i = 0 ; i < thread_resources -> count ; i ++ ) {
457
503
if (resource_types_table [i ].dtor ) {
458
- resource_types_table [i ].dtor (thread_resources -> storage [i ], & thread_resources -> storage );
504
+ CALL_TSRMG_DTOR ( resource_types_table [i ].dtor , TSRMG_PTR (thread_resources -> storage , resource_types_table [i ]. offset ) , & thread_resources -> storage );
459
505
}
460
506
}
461
- for (i = 0 ; i < thread_resources -> count ; i ++ ) {
462
- free (thread_resources -> storage [i ]);
463
- }
464
507
free (thread_resources -> storage );
465
508
if (last ) {
466
509
last -> next = thread_resources -> next ;
@@ -497,12 +540,9 @@ void ts_free_worker_threads(void)
497
540
if (thread_resources -> thread_id != thread_id ) {
498
541
for (i = 0 ; i < thread_resources -> count ; i ++ ) {
499
542
if (resource_types_table [i ].dtor ) {
500
- resource_types_table [i ].dtor (thread_resources -> storage [i ], & thread_resources -> storage );
543
+ CALL_TSRMG_DTOR ( resource_types_table [i ].dtor , TSRMG_PTR (thread_resources -> storage , resource_types_table [i ]. offset ) , & thread_resources -> storage );
501
544
}
502
545
}
503
- for (i = 0 ; i < thread_resources -> count ; i ++ ) {
504
- free (thread_resources -> storage [i ]);
505
- }
506
546
free (thread_resources -> storage );
507
547
if (last ) {
508
548
last -> next = thread_resources -> next ;
@@ -541,12 +581,10 @@ void ts_free_id(ts_rsrc_id id)
541
581
tsrm_tls_entry * p = tsrm_tls_table [i ];
542
582
543
583
while (p ) {
544
- if (p -> count > j && p -> storage [ j ] ) {
584
+ if (p -> count > j ) {
545
585
if (resource_types_table && resource_types_table [j ].dtor ) {
546
- resource_types_table [j ].dtor (p -> storage [j ], & p -> storage );
586
+ CALL_TSRMG_DTOR ( resource_types_table [j ].dtor , TSRMG_PTR (p -> storage , resource_types_table [j ]. offset ) , & p -> storage );
547
587
}
548
- free (p -> storage [j ]);
549
- p -> storage [j ] = NULL ;
550
588
}
551
589
p = p -> next ;
552
590
}
0 commit comments