166 lines
4.0 KiB
C
166 lines
4.0 KiB
C
#include "tlang.h"
|
|
|
|
#if defined(USE_THREADS)
|
|
|
|
bool thread_init=false;
|
|
#if defined(GEKKO)
|
|
#include <ogc/mutex.h>
|
|
#include <ogc/lwp.h>
|
|
#else
|
|
#include <pthread.h>
|
|
#endif
|
|
|
|
tmutex_t global_mutex;
|
|
|
|
tmutex_t Mutex_Create()
|
|
{
|
|
#if defined(GEKKO)
|
|
mutex_t mutex=LWP_MUTEX_NULL;
|
|
LWP_MutexInit(&mutex,true);
|
|
return (tmutex_t)mutex;
|
|
#else
|
|
pthread_mutex_t* mtx= (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
|
|
memset(mtx,0,sizeof(pthread_mutex_t));
|
|
pthread_mutexattr_t attr;
|
|
pthread_mutexattr_init(&attr);
|
|
#if defined(PTHREAD_MUTEX_RECURSIVE_NP)
|
|
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
|
|
#else
|
|
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
|
#endif
|
|
pthread_mutex_init(mtx,&attr);
|
|
return (tmutex_t)mtx;
|
|
#endif
|
|
}
|
|
void Mutex_Free(tmutex_t mutex)
|
|
{
|
|
#if defined(GEKKO)
|
|
LWP_MutexDestroy((mutex_t)mutex);
|
|
#else
|
|
pthread_mutex_destroy((pthread_mutex_t*)mutex);
|
|
free(mutex);
|
|
#endif
|
|
|
|
}
|
|
int64_t Mutex_Lock(tmutex_t mutex)
|
|
{
|
|
#if defined(GEKKO)
|
|
return LWP_MutexLock((mutex_t)mutex);
|
|
#else
|
|
return pthread_mutex_lock((pthread_mutex_t*)mutex);
|
|
#endif
|
|
}
|
|
int64_t Mutex_Unlock(tmutex_t mutex)
|
|
{
|
|
#if defined(GEKKO)
|
|
LWP_MutexUnlock((mutex_t)mutex);
|
|
#else
|
|
return pthread_mutex_unlock((pthread_mutex_t*)mutex);
|
|
#endif
|
|
}
|
|
void Global_Mutex_Lock()
|
|
{
|
|
if(thread_init)
|
|
Mutex_Lock(global_mutex);
|
|
}
|
|
void Global_Mutex_Unlock()
|
|
{
|
|
if(thread_init)
|
|
Mutex_Unlock(global_mutex);
|
|
}
|
|
|
|
|
|
void Threading_Thread_Create(void*(*entry)(void*),void* arg)
|
|
{
|
|
#if defined(GEKKO)
|
|
lwp_t lwp=LWP_THREAD_NULL;
|
|
LWP_CreateThread(&lwp,entry,arg,NULL,0,64);
|
|
#else
|
|
pthread_t thrd;
|
|
pthread_create(&thrd,NULL,entry,arg);
|
|
pthread_detach(thrd);
|
|
#endif
|
|
|
|
}
|
|
typedef struct {
|
|
tobject_t* obj;
|
|
runtime_t* rt;
|
|
|
|
} __thread_arg_ctx;
|
|
|
|
static void* __create_thread_thread_func(void* data)
|
|
{
|
|
__thread_arg_ctx* ctx = (__thread_arg_ctx*)data;
|
|
list_tobject_t objs;
|
|
list_create(ctx->rt,&objs,0);
|
|
tobject_t* obj=tobject_call(ctx->rt->globals,ctx->obj,&objs);
|
|
tobject_freeifzero(obj);
|
|
tobject_rmref(ctx->obj);
|
|
free(data);
|
|
}
|
|
void __create_mutex_destroy(tobject_t* obj)
|
|
{
|
|
Mutex_Free((tmutex_t)obj->ptr_data);
|
|
}
|
|
tobject_t* __create_mutex_lock_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
Mutex_Lock((tmutex_t)ptr);
|
|
return tobject_basic(rt,tundef);
|
|
}
|
|
tobject_t* __create_mutex_unlock_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
Mutex_Unlock((tmutex_t)ptr);
|
|
return tobject_basic(rt,tundef);
|
|
}
|
|
tobject_t* __create_mutex_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
tobject_t* o = tobject_create(rt);
|
|
o->type = tdict;
|
|
o->data.dict = dict_create();
|
|
tmutex_t* mutex=Mutex_Create();
|
|
o->ptr_data = mutex;
|
|
runtime_create_method_on_dict(o->data.dict,"lock",rt,mutex,__create_mutex_lock_external_method,NULL);
|
|
runtime_create_method_on_dict(o->data.dict,"unlock",rt,mutex,__create_mutex_unlock_external_method,NULL);
|
|
o->free = __create_mutex_destroy;
|
|
return o;
|
|
}
|
|
tobject_t* __create_thread_external_method(runtime_t* rt,void* ptr,list_tobject_t* args)
|
|
{
|
|
if(args->length > 0)
|
|
{
|
|
tobject_t* data=args->items[0];
|
|
if(data->type == tinternalmethod || data->type == texternalmethod)
|
|
{
|
|
data->count++;
|
|
__thread_arg_ctx* ctx = (__thread_arg_ctx*)malloc(sizeof(__thread_arg_ctx));
|
|
ctx->obj = data;
|
|
ctx->rt = rt;
|
|
Threading_Thread_Create(__create_thread_thread_func,(void*)ctx);
|
|
}
|
|
}
|
|
return tobject_basic(rt,tundef);
|
|
}
|
|
void runtime_register_threads(runtime_t* rt,dict_t* create)
|
|
{
|
|
if(!thread_init)
|
|
{
|
|
global_mutex = Mutex_Create();
|
|
thread_init = true;
|
|
}
|
|
|
|
runtime_create_method_on_dict(create,"thread",rt,NULL,__create_thread_external_method,NULL);
|
|
runtime_create_method_on_dict(create,"mutex",rt,NULL,__create_mutex_external_method,NULL);
|
|
}
|
|
|
|
#else
|
|
void Global_Mutex_Lock()
|
|
{
|
|
|
|
}
|
|
void Global_Mutex_Unlock()
|
|
{
|
|
|
|
}
|
|
#endif
|
|
|