Just to expand a bit on hamster_nz's suggestion, after learning of that extension I went and did a bit of research, for now I have this:
Code:
/* Thanks to hamster_nz for identifying this to me :)
* https://cboard.cprogramming.com/c-programming/181257-possible-set-get-user-data-handle-pthread_t.html
* */
#ifdef __GNUC__
#define paw_thread_local __thread
#elif defined( _MSC )
#define paw_thread_local _declspec(thread)
#elseif PAW_STDC >= 202300L
#define paw_thread_local thread_local
#else /*if PAW_STDC >= 201113L*/
#define paw_thread_local _Thread_local
#endif
thread_local pawRUN _pawRUN = NULL;
It's actually supposed to have a #ifdef guard for paw_thread_local but I'll deal with that later, as for the fallback I decided that I won't both with a buffer for now and instead just rely on the environment variables to extract the pointer, here's a snippet from my current code, haven't tested it but I know the stringify/numerify functions work just fine so in theory no issue:
Code:
void* pawRUN_initCB( void *ud )
{
pawRUN Run = ud;
_pawRUN = Run;
Run->tid = pawthis_tid();
if ( Run->initCB )
{
pawsu *key = &(Run->env_key), *val = &(Run->env_val);
pawju2pawsu( key, Run->tid, PAWS_BASE10 );
pawju2pawsu( val, (pawvu)Run, PAWS_BASE16X );
paw_ins( key->txt, key->len, PAWRUN_PFX, sizeof(PAWRUN_PFX) - 1 );
setenv( key->txt, val->txt, 1 );
pawgc_decl_ud( Run->id, Run );
pawgc_decl_voidCB( Run->id, pawRUN_voidCB );
Run->initCB( Run->id, Run->ud );
unsetenv( key->txt );
}
return NULL;
}
static pthread_t pawrun_pthread( pawrun run )
{
paws txt = NULL;
pawsu key = BAD_pawsu, val = BAD_pawsu;
pawju addr = 0;
pawRUN Run = NULL;
pawju2pawsu( &key, run, PAWS_BASE16X );
/* We get at least 48 remaining characters to work with so no fear of
* buffer overruns */
paw_ins( key.txt, key.len, PAWRUN_PFX, sizeof(PAWRUN_PFX)-1 );
txt = getenv( key.txt );
paw_cpy( val.txt, txt, paws_len(txt) );
pawsu2pawju( &addr, &val, PAWS_BASE16X );
Run = (void*)addr;
return Run->thread;
}
Just on the off chance the environment decides to use the text pointers as is I attached them to the thread object directly, I just gotta get round to clearing the variable prior to deleting the object.