Managed to resolve the inter-thread communication problem, still needs tweaking but now I get the expected behaviour for my pseudo mutex, unlike pthread_mutex_t this doesn't need any init()/destroy() type constructors, also there's no "global" mutex that needs to be predeclared by developers, you just call ClaimShared( thread, object ) & YieldShared() whenever you want to access a resource without referencing an explicit global, not yet able to re-produce semaphores but that can come later once I've thought it through, incidentally I wound up not needing the time_t or clock_t types, however I still have a final bug to squash before I can be satisfied it's production ready for any system, here's some output to give an indication of what I mean:
Code:
make DEBUG=1 run
...
cd ../../bin/ && ./d-check_basic.elf
debug = 1
main_thread: sig = 0, 'SIGNAL_NULL', 70/ 0/ 1 1: 0: 0: 0, src 0 ( 0) 'kid', obj { rid = 0, nid = '(null)', def = '(null)', raw = '(null)' }
Act 63298: Hello World!
stdout now has rid 2
Spawning thread 0
main_thread: sig = 4, 'SIGNAL_EXEC', 70/ 0/ 2 4:48:19: 557947767, src 63298 ( 1) 'kid', obj { rid = 0, nid = 'PTR', def = 'void*', raw = 'void*' }
main_thread: sig = 4, 'SIGNAL_EXEC', 70/ 0/ 2 4:48:19: 557947767, src 63297 ( 0) 'top', obj { rid = 0, nid = '(null)', def = '(null)', raw = '(null)' }
Spawning thread 1
main_thread: sig = 0, 'SIGNAL_NULL', 70/ 0/ 1 1: 0: 0: 0, src 0 ( 0) 'kid', obj { rid = 0, nid = '(null)', def = '(null)', raw = '(null)' }
Spawning thread 2
main_thread: sig = 0, 'SIGNAL_NULL', 70/ 0/ 1 1: 0: 0: 0, src 0 ( 0) 'kid', obj { rid = 0, nid = '(null)', def = '(null)', raw = '(null)' }
main_thread: TestPseudoMutex(63299) claimed shared
TestPseudoMutex(63299) yielded shared
sig = 4, 'SIGNAL_EXEC', 70/ 0/ 2 4:48:19: 558122755, src 63297 ( 0) 'top', obj { rid = 2, nid = 'STDOUT', def = 'FILE*', raw = 'struct _FILE*' }
TestPseudoMutex(63301) claimed shared
TestPseudoMutex(63301) yielded shared
main_thread: TestPseudoMutex(63300) claimed shared
TestPseudoMutex(63300) yielded shared
sig = 4, 'SIGNAL_EXEC', 70/ 0/ 2 4:48:19: 558167389, src 63300 ( 4) 'kid', obj { rid = 5, nid = '(null)', def = 'THREAD', raw = 'struct _THREAD' }
make[2]: *** [makefile:30: run] Killed
...
Compilation failed.
I had to manually kill the app at the end there despite all but the main thread being dead. I'll add the link for the upload in a sec, just gotta grab the url
Edit: Here's the url:
Files * 74e130e1c58d262286e2877dd78634236aea4ef1 * Lee Shallis / Dragonbuilder * GitLab
For reference this is what the test code looks like:
Code:
#include <basic/natives.h>
#include <pthread.h>
typedef struct _ARGS {
uint stdout_rid;
dint argc; char **argv;
} ARGS;
time_t pseudo_mutex_start = 0;
#ifndef _DEBUG
pthread_mutex_t debug_mutex;
#endif
dint TestPseudoMutex( OBJ *obj )
{
ACT *src = obj->src;
ACT *top = TopThread();
ARGS *args = GetThreadUD(top);
OBJ o = {0};
ucap tid = GetThreadTid(src);
o.rid = args->stdout_rid;
o.nid = "STDOUT";
o.raw = "struct _FILE*";
o.def = "FILE*";
o.ptr = stdout;
o.src = src;
while ( !pseudo_mutex_start )
PauseThread();
/* Test our pseduo mutices */
ClaimShared( src, &o );
printf("TestPseudoMutex(%zu) claimed shared\n", tid );
YieldShared( src, &o );
printf("TestPseudoMutex(%zu) yielded shared\n", tid );
return 0;
}
dint HelloWorld( OBJ *obj )
{
ACT *src = obj->src;
ACT *top = TopThread();
ARGS *args = GetThreadUD(top);
REF *ref = GetThreadRef(src);
ACT *kids[3] = { NULL };
dint i, err;
args->stdout_rid = SpawnRid( src );
/* We test our pseudo mutices later, at this point we just want to know
* our threads launched */
pthread_mutex_lock(&debug_mutex);
printf( "Act %zu: Hello World!\n", GetThreadTid(src) );
if ( !(args->stdout_rid) )
{
printf("failed to allocate rid\n");
pthread_mutex_unlock(&debug_mutex);
return ECANCELED;
}
printf("stdout now has rid %u\n", args->stdout_rid );
pthread_mutex_unlock(&debug_mutex);
for ( i = 0; i < 3; ++i )
{
pthread_mutex_lock(&debug_mutex);
printf( "Spawning thread %d\n", i );
pthread_mutex_unlock(&debug_mutex);
err = SpawnThread( src, TestPseudoMutex );
if ( err )
break;
kids[i] = ref->Last;
}
pseudo_mutex_start = time(NULL);
while ( i )
{
--i;
AwaitThread( kids[i] );
EraseThread( src, kids[i] );
}
return 0;
}
int main( int argc, char *argv[] )
{
ARGS args = { 0, argc, argv };
dint err;
setbuf( stdout, NULL );
setbuf( stderr, NULL );
#ifndef _DEBUG
pthread_mutex_init( &debug_mutex, NULL );
#endif
SetAllocator( TopThread(), NULL, &args );
err = ExecThreads( HelloWorld, true );
#ifndef _DEBUG
pthread_mutex_destroy( &debug_mutex, NULL );
#endif
return err ? EXIT_FAILURE : EXIT_SUCCESS;
}