Skip to content

Commit b3aebda

Browse files
committed
native tls initial patch
1 parent 763bfb4 commit b3aebda

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+319
-177
lines changed

TSRM/TSRM.c

+88-50
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,15 @@
2323
typedef struct _tsrm_tls_entry tsrm_tls_entry;
2424

2525
struct _tsrm_tls_entry {
26-
void **storage;
26+
void *storage;
2727
int count;
2828
THREAD_T thread_id;
2929
tsrm_tls_entry *next;
3030
};
3131

3232

3333
typedef struct {
34+
ts_rsrc_offset offset;
3435
size_t size;
3536
ts_allocate_ctor ctor;
3637
ts_allocate_dtor dtor;
@@ -42,7 +43,7 @@ typedef struct {
4243
static tsrm_tls_entry **tsrm_tls_table=NULL;
4344
static int tsrm_tls_table_size;
4445
static ts_rsrc_id id_count;
45-
46+
static size_t rsrcs_size;
4647
/* The resource sizes table */
4748
static tsrm_resource_type *resource_types_table=NULL;
4849
static int resource_types_table_size;
@@ -61,31 +62,62 @@ int tsrm_error(int level, const char *format, ...);
6162
static int tsrm_error_level;
6263
static FILE *tsrm_error_file;
6364

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+
6496
#if TSRM_DEBUG
6597
#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) \
6799
{ \
68-
int unshuffled_offset = TSRM_UNSHUFFLE_RSRC_ID(offset); \
100+
int unshuffled_id = TSRM_UNSHUFFLE_RSRC_ID(id); \
69101
\
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)) { \
73105
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); \
76108
} else { \
77109
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))); \
79111
return NULL; \
80112
} \
81113
}
82114
#else
83115
#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); \
89121
}
90122
#endif
91123

@@ -175,12 +207,9 @@ TSRM_API void tsrm_shutdown(void)
175207

176208
next_p = p->next;
177209
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+
}
184213
}
185214
free(p->storage);
186215
free(p);
@@ -212,9 +241,10 @@ TSRM_API void tsrm_shutdown(void)
212241

213242

214243
/* 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)
216245
{
217246
int i;
247+
ts_rsrc_offset offset = 0;
218248

219249
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Obtaining a new resource id, %d bytes", size));
220250

@@ -235,6 +265,17 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate
235265
}
236266
resource_types_table_size = id_count;
237267
}
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;
238279
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].size = size;
239280
resource_types_table[TSRM_UNSHUFFLE_RSRC_ID(*rsrc_id)].ctor = ctor;
240281
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
248289
if (p->count < id_count) {
249290
int j;
250291

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
252296
for (j=p->count; j<id_count; j++) {
253-
p->storage[j] = (void *) malloc(resource_types_table[j].size);
254297
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);
256299
}
257300
}
258301
p->count = id_count;
259302
}
260303
p = p->next;
261304
}
262305
}
306+
rsrcs_size = offset + size;
263307
tsrm_mutex_unlock(tsmm_mutex);
264308

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));
266310
return *rsrc_id;
267311
}
268312

@@ -273,31 +317,31 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_
273317

274318
TSRM_ERROR((TSRM_ERROR_LEVEL_CORE, "Creating data structures for thread %x", thread_id));
275319
(*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);
277321
(*thread_resources_ptr)->count = id_count;
278322
(*thread_resources_ptr)->thread_id = thread_id;
279323
(*thread_resources_ptr)->next = NULL;
280324

281325
/* Set thread local storage to this new thread resources structure */
282326
tsrm_tls_set(*thread_resources_ptr);
283327

328+
#ifdef USE___THREAD
329+
tsrm_ls_cache = (*thread_resources_ptr)->storage;
330+
#endif
331+
284332
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);
286334
}
287335
for (i=0; i<id_count; i++) {
288336
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);
293337
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);
295339
}
296340
}
297341
}
298342

299343
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);
301345
}
302346

303347
tsrm_mutex_unlock(tsmm_mutex);
@@ -390,12 +434,10 @@ void tsrm_free_interpreter_context(void *context)
390434

391435
for (i=0; i<thread_resources->count; i++) {
392436
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);
394438
}
395439
}
396-
for (i=0; i<thread_resources->count; i++) {
397-
free(thread_resources->storage[i]);
398-
}
440+
399441
free(thread_resources->storage);
400442
free(thread_resources);
401443
thread_resources = next;
@@ -413,6 +455,10 @@ void *tsrm_set_interpreter_context(void *new_ctx)
413455

414456
/* Set thread local storage to this new thread resources structure */
415457
tsrm_tls_set(new_ctx);
458+
459+
#ifdef USE___THREAD
460+
tsrm_ls_cache = ((tsrm_tls_entry*)new_ctx)->storage;
461+
#endif
416462

417463
/* return old context, so caller can restore it when they're done */
418464
return current;
@@ -455,12 +501,9 @@ void ts_free_thread(void)
455501
if (thread_resources->thread_id == thread_id) {
456502
for (i=0; i<thread_resources->count; i++) {
457503
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);
459505
}
460506
}
461-
for (i=0; i<thread_resources->count; i++) {
462-
free(thread_resources->storage[i]);
463-
}
464507
free(thread_resources->storage);
465508
if (last) {
466509
last->next = thread_resources->next;
@@ -497,12 +540,9 @@ void ts_free_worker_threads(void)
497540
if (thread_resources->thread_id != thread_id) {
498541
for (i=0; i<thread_resources->count; i++) {
499542
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);
501544
}
502545
}
503-
for (i=0; i<thread_resources->count; i++) {
504-
free(thread_resources->storage[i]);
505-
}
506546
free(thread_resources->storage);
507547
if (last) {
508548
last->next = thread_resources->next;
@@ -541,12 +581,10 @@ void ts_free_id(ts_rsrc_id id)
541581
tsrm_tls_entry *p = tsrm_tls_table[i];
542582

543583
while (p) {
544-
if (p->count > j && p->storage[j]) {
584+
if (p->count > j) {
545585
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);
547587
}
548-
free(p->storage[j]);
549-
p->storage[j] = NULL;
550588
}
551589
p = p->next;
552590
}

0 commit comments

Comments
 (0)