@@ -34,6 +34,7 @@ typedef struct {
3434 size_t size ;
3535 ts_allocate_ctor ctor ;
3636 ts_allocate_dtor dtor ;
37+ size_t fast_offset ;
3738 int done ;
3839} tsrm_resource_type ;
3940
@@ -47,6 +48,9 @@ static ts_rsrc_id id_count;
4748static tsrm_resource_type * resource_types_table = NULL ;
4849static int resource_types_table_size ;
4950
51+ /* Reserved space for fast globals access */
52+ static size_t tsrm_reserved_pos = 0 ;
53+ static size_t tsrm_reserved_size = 0 ;
5054
5155static MUTEX_T tsmm_mutex ; /* thread-safe memory manager mutex */
5256
@@ -160,6 +164,10 @@ TSRM_API int tsrm_startup(int expected_threads, int expected_resources, int debu
160164 tsmm_mutex = tsrm_mutex_alloc ();
161165
162166 TSRM_ERROR ((TSRM_ERROR_LEVEL_CORE , "Started up TSRM, %d expected threads, %d expected resources" , expected_threads , expected_resources ));
167+
168+ tsrm_reserved_pos = 0 ;
169+ tsrm_reserved_size = 0 ;
170+
163171 return 1 ;
164172}/*}}}*/
165173
@@ -187,7 +195,9 @@ TSRM_API void tsrm_shutdown(void)
187195 if (resource_types_table && !resource_types_table [j ].done && resource_types_table [j ].dtor ) {
188196 resource_types_table [j ].dtor (p -> storage [j ]);
189197 }
190- free (p -> storage [j ]);
198+ if (!resource_types_table [j ].fast_offset ) {
199+ free (p -> storage [j ]);
200+ }
191201 }
192202 }
193203 free (p -> storage );
@@ -222,14 +232,46 @@ TSRM_API void tsrm_shutdown(void)
222232 tsrm_new_thread_begin_handler = NULL ;
223233 tsrm_new_thread_end_handler = NULL ;
224234 tsrm_shutdown_handler = NULL ;
235+
236+ tsrm_reserved_pos = 0 ;
237+ tsrm_reserved_size = 0 ;
225238}/*}}}*/
226239
227240
228- /* allocates a new thread-safe-resource id */
229- TSRM_API ts_rsrc_id ts_allocate_id ( ts_rsrc_id * rsrc_id , size_t size , ts_allocate_ctor ctor , ts_allocate_dtor dtor )
241+ /* enlarge the arrays for the already active threads */
242+ static void tsrm_update_active_threads ( void )
230243{/*{{{*/
231244 int i ;
232245
246+ for (i = 0 ; i < tsrm_tls_table_size ; i ++ ) {
247+ tsrm_tls_entry * p = tsrm_tls_table [i ];
248+
249+ while (p ) {
250+ if (p -> count < id_count ) {
251+ int j ;
252+
253+ p -> storage = (void * ) realloc (p -> storage , sizeof (void * )* id_count );
254+ for (j = p -> count ; j < id_count ; j ++ ) {
255+ if (resource_types_table [j ].fast_offset ) {
256+ p -> storage [j ] = (void * ) (((char * )p ) + resource_types_table [j ].fast_offset );
257+ } else {
258+ p -> storage [j ] = (void * ) malloc (resource_types_table [j ].size );
259+ }
260+ if (resource_types_table [j ].ctor ) {
261+ resource_types_table [j ].ctor (p -> storage [j ]);
262+ }
263+ }
264+ p -> count = id_count ;
265+ }
266+ p = p -> next ;
267+ }
268+ }
269+ }/*}}}*/
270+
271+
272+ /* allocates a new thread-safe-resource id */
273+ TSRM_API ts_rsrc_id ts_allocate_id (ts_rsrc_id * rsrc_id , size_t size , ts_allocate_ctor ctor , ts_allocate_dtor dtor )
274+ {/*{{{*/
233275 TSRM_ERROR ((TSRM_ERROR_LEVEL_CORE , "Obtaining a new resource id, %d bytes" , size ));
234276
235277 tsrm_mutex_lock (tsmm_mutex );
@@ -254,28 +296,68 @@ TSRM_API ts_rsrc_id ts_allocate_id(ts_rsrc_id *rsrc_id, size_t size, ts_allocate
254296 resource_types_table [TSRM_UNSHUFFLE_RSRC_ID (* rsrc_id )].size = size ;
255297 resource_types_table [TSRM_UNSHUFFLE_RSRC_ID (* rsrc_id )].ctor = ctor ;
256298 resource_types_table [TSRM_UNSHUFFLE_RSRC_ID (* rsrc_id )].dtor = dtor ;
299+ resource_types_table [TSRM_UNSHUFFLE_RSRC_ID (* rsrc_id )].fast_offset = 0 ;
257300 resource_types_table [TSRM_UNSHUFFLE_RSRC_ID (* rsrc_id )].done = 0 ;
258301
259- /* enlarge the arrays for the already active threads */
260- for (i = 0 ; i < tsrm_tls_table_size ; i ++ ) {
261- tsrm_tls_entry * p = tsrm_tls_table [i ];
302+ tsrm_update_active_threads ();
303+ tsrm_mutex_unlock (tsmm_mutex );
262304
263- while ( p ) {
264- if ( p -> count < id_count ) {
265- int j ;
305+ TSRM_ERROR (( TSRM_ERROR_LEVEL_CORE , "Successfully allocated new resource id %d" , * rsrc_id ));
306+ return * rsrc_id ;
307+ } /*}}}*/
266308
267- p -> storage = (void * ) realloc (p -> storage , sizeof (void * )* id_count );
268- for (j = p -> count ; j < id_count ; j ++ ) {
269- p -> storage [j ] = (void * ) malloc (resource_types_table [j ].size );
270- if (resource_types_table [j ].ctor ) {
271- resource_types_table [j ].ctor (p -> storage [j ]);
272- }
273- }
274- p -> count = id_count ;
275- }
276- p = p -> next ;
309+
310+ /* Reserve space for fast thread-safe-resources */
311+ TSRM_API void tsrm_reserve (size_t size )
312+ {/*{{{*/
313+ tsrm_reserved_pos = 0 ;
314+ tsrm_reserved_size = TSRM_ALIGNED_SIZE (size );
315+ }/*}}}*/
316+
317+
318+ /* allocates a new fast thread-safe-resource id */
319+ TSRM_API ts_rsrc_id ts_allocate_fast_id (ts_rsrc_id * rsrc_id , size_t * offset , size_t size , ts_allocate_ctor ctor , ts_allocate_dtor dtor )
320+ {/*{{{*/
321+ TSRM_ERROR ((TSRM_ERROR_LEVEL_CORE , "Obtaining a new fast resource id, %d bytes" , size ));
322+
323+ tsrm_mutex_lock (tsmm_mutex );
324+
325+ /* obtain a resource id */
326+ * rsrc_id = TSRM_SHUFFLE_RSRC_ID (id_count ++ );
327+ TSRM_ERROR ((TSRM_ERROR_LEVEL_CORE , "Obtained resource id %d" , * rsrc_id ));
328+
329+ size = TSRM_ALIGNED_SIZE (size );
330+ if (tsrm_reserved_size - tsrm_reserved_pos < size ) {
331+ tsrm_mutex_unlock (tsmm_mutex );
332+ TSRM_ERROR ((TSRM_ERROR_LEVEL_ERROR , "Unable to allocate space for fast resource" ));
333+ * rsrc_id = 0 ;
334+ * offset = 0 ;
335+ return 0 ;
336+ }
337+
338+ * offset = TSRM_ALIGNED_SIZE (sizeof (tsrm_tls_entry )) + tsrm_reserved_pos ;
339+ tsrm_reserved_pos += size ;
340+
341+ /* store the new resource type in the resource sizes table */
342+ if (resource_types_table_size < id_count ) {
343+ tsrm_resource_type * _tmp ;
344+ _tmp = (tsrm_resource_type * ) realloc (resource_types_table , sizeof (tsrm_resource_type )* id_count );
345+ if (!_tmp ) {
346+ tsrm_mutex_unlock (tsmm_mutex );
347+ TSRM_ERROR ((TSRM_ERROR_LEVEL_ERROR , "Unable to allocate storage for resource" ));
348+ * rsrc_id = 0 ;
349+ return 0 ;
277350 }
351+ resource_types_table = _tmp ;
352+ resource_types_table_size = id_count ;
278353 }
354+ resource_types_table [TSRM_UNSHUFFLE_RSRC_ID (* rsrc_id )].size = size ;
355+ resource_types_table [TSRM_UNSHUFFLE_RSRC_ID (* rsrc_id )].ctor = ctor ;
356+ resource_types_table [TSRM_UNSHUFFLE_RSRC_ID (* rsrc_id )].dtor = dtor ;
357+ resource_types_table [TSRM_UNSHUFFLE_RSRC_ID (* rsrc_id )].fast_offset = * offset ;
358+ resource_types_table [TSRM_UNSHUFFLE_RSRC_ID (* rsrc_id )].done = 0 ;
359+
360+ tsrm_update_active_threads ();
279361 tsrm_mutex_unlock (tsmm_mutex );
280362
281363 TSRM_ERROR ((TSRM_ERROR_LEVEL_CORE , "Successfully allocated new resource id %d" , * rsrc_id ));
@@ -288,7 +370,7 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_
288370 int i ;
289371
290372 TSRM_ERROR ((TSRM_ERROR_LEVEL_CORE , "Creating data structures for thread %x" , thread_id ));
291- (* thread_resources_ptr ) = (tsrm_tls_entry * ) malloc (sizeof (tsrm_tls_entry ));
373+ (* thread_resources_ptr ) = (tsrm_tls_entry * ) malloc (TSRM_ALIGNED_SIZE ( sizeof (tsrm_tls_entry )) + tsrm_reserved_size );
292374 (* thread_resources_ptr )-> storage = NULL ;
293375 if (id_count > 0 ) {
294376 (* thread_resources_ptr )-> storage = (void * * ) malloc (sizeof (void * )* id_count );
@@ -307,9 +389,12 @@ static void allocate_new_resource(tsrm_tls_entry **thread_resources_ptr, THREAD_
307389 for (i = 0 ; i < id_count ; i ++ ) {
308390 if (resource_types_table [i ].done ) {
309391 (* thread_resources_ptr )-> storage [i ] = NULL ;
310- } else
311- {
312- (* thread_resources_ptr )-> storage [i ] = (void * ) malloc (resource_types_table [i ].size );
392+ } else {
393+ if (resource_types_table [i ].fast_offset ) {
394+ (* thread_resources_ptr )-> storage [i ] = (void * ) (((char * )(* thread_resources_ptr )) + resource_types_table [i ].fast_offset );
395+ } else {
396+ (* thread_resources_ptr )-> storage [i ] = (void * ) malloc (resource_types_table [i ].size );
397+ }
313398 if (resource_types_table [i ].ctor ) {
314399 resource_types_table [i ].ctor ((* thread_resources_ptr )-> storage [i ]);
315400 }
@@ -402,7 +487,9 @@ void tsrm_free_interpreter_context(void *context)
402487 }
403488 }
404489 for (i = 0 ; i < thread_resources -> count ; i ++ ) {
405- free (thread_resources -> storage [i ]);
490+ if (!resource_types_table [i ].fast_offset ) {
491+ free (thread_resources -> storage [i ]);
492+ }
406493 }
407494 free (thread_resources -> storage );
408495 free (thread_resources );
@@ -467,7 +554,9 @@ void ts_free_thread(void)
467554 }
468555 }
469556 for (i = 0 ; i < thread_resources -> count ; i ++ ) {
470- free (thread_resources -> storage [i ]);
557+ if (!resource_types_table [i ].fast_offset ) {
558+ free (thread_resources -> storage [i ]);
559+ }
471560 }
472561 free (thread_resources -> storage );
473562 if (last ) {
@@ -509,7 +598,9 @@ void ts_free_worker_threads(void)
509598 }
510599 }
511600 for (i = 0 ; i < thread_resources -> count ; i ++ ) {
512- free (thread_resources -> storage [i ]);
601+ if (!resource_types_table [i ].fast_offset ) {
602+ free (thread_resources -> storage [i ]);
603+ }
513604 }
514605 free (thread_resources -> storage );
515606 if (last ) {
@@ -553,7 +644,9 @@ void ts_free_id(ts_rsrc_id id)
553644 if (resource_types_table && resource_types_table [j ].dtor ) {
554645 resource_types_table [j ].dtor (p -> storage [j ]);
555646 }
556- free (p -> storage [j ]);
647+ if (!resource_types_table [j ].fast_offset ) {
648+ free (p -> storage [j ]);
649+ }
557650 p -> storage [j ] = NULL ;
558651 }
559652 p = p -> next ;
0 commit comments