Files
ground/libs/threading/thread.c

101 lines
2.9 KiB
C

#include "thread.h"
#include <stdarg.h>
#include <stddef.h>
#include <groundext.h>
#include <groundvm.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
GroundStruct threadStruct = {};
typedef struct {
GroundFunction* func;
GroundObject* funcArgsListStruct;
} ThreadArgs;
GroundScope copyGroundScope(GroundScope* scope);
GroundValue interpretGroundProgram(GroundProgram* in, GroundScope* inScope);
void* threadMain(void* threadArgs) {
ThreadArgs* realArgs = (ThreadArgs*)threadArgs;
GroundFunction func = *realArgs->func;
GroundObjectField* listSizeField = groundFindField(*realArgs->funcArgsListStruct, "size");
if (listSizeField == NULL) {
return NULL;
}
int64_t listSize = listSizeField->value.data.intVal;
GroundValue* listPtr = (GroundValue*)groundFindField(*realArgs->funcArgsListStruct, "ptr")->value.data.intVal;
// put args from list into func args
va_list list;
GroundScope funcScope = copyGroundScope(&func.closure);
for (int64_t i = 0; i < listSize; i++) {
groundAddValueToScope(&funcScope, func.args[i].name, listPtr[i]);
}
// run func
free(realArgs);
interpretGroundProgram(&func.program, &funcScope);
return NULL;
}
GroundValue threadStructStart(GroundScope* scope, List args) {
GroundVariable* funcField = groundFindVariable(scope, "fn");
GroundVariable* argsField = groundFindVariable(scope, "args");
pthread_t newThread;
ThreadArgs *threadArgs = malloc(sizeof(ThreadArgs));
threadArgs->func = funcField->value.data.fnVal;
threadArgs->funcArgsListStruct = (GroundObject*)argsField->value.data.customVal;
pthread_create(&newThread, NULL, threadMain, threadArgs);
return groundCreateValue(INT, 0);
}
GroundValue threadStructConstructor(GroundScope* scope, List args) {
GroundValue value = groundCreateValue(CUSTOM, &threadStruct);
GroundValue function = args.values[0];
GroundValue threadFuncArgs = args.values[1];
GroundObjectField* funcField = groundFindField(*value.data.customVal, "fn");
GroundObjectField* argsField = groundFindField(*value.data.customVal, "args");
funcField->value = function;
argsField->value = threadFuncArgs;
value.type = CUSTOM;
return value;
}
void initThreadStruct(GroundScope* scope) {
threadStruct = groundCreateStruct();
groundAddFieldToStruct(&threadStruct, "fn", groundCreateValue(FUNCTION, 0));
groundAddFieldToStruct(&threadStruct, "args", groundCreateValue(INT, 0));
groundAddFieldToStruct(&threadStruct, "pthread", groundCreateValue(INT, 0));
groundAddFunctionToStruct(&threadStruct, "start", threadStructStart, INT, 0);
groundAddNativeFunction(
scope,
"Thread_SOLS_CONSTRUCTOR",
threadStructConstructor,
CUSTOM,
2,
FUNCTION,
"function",
CUSTOM,
"args"
);
}