2023-02-01 15:54:20 +08:00
|
|
|
#include "_thread.h"
|
|
|
|
#include "PikaVM.h"
|
2023-03-08 21:14:19 +08:00
|
|
|
#include "TinyObj.h"
|
2023-02-01 15:54:20 +08:00
|
|
|
|
2023-04-17 09:42:28 +08:00
|
|
|
static volatile int g_thread_stack_size = PIKA_THREAD_STACK_SIZE;
|
|
|
|
extern volatile PikaMemInfo g_PikaMemInfo;
|
2023-02-01 15:54:20 +08:00
|
|
|
typedef struct pika_thread_info {
|
|
|
|
Arg* function;
|
|
|
|
Arg* args;
|
|
|
|
pika_platform_thread_t* thread;
|
2023-04-17 09:42:28 +08:00
|
|
|
int stack_size;
|
2023-02-01 15:54:20 +08:00
|
|
|
} pika_thread_info;
|
|
|
|
|
|
|
|
static void _thread_func(void* arg) {
|
2023-02-13 22:20:25 +08:00
|
|
|
pika_debug("waiting for first lock");
|
2023-02-26 17:00:36 +08:00
|
|
|
while (1) {
|
|
|
|
if (_VM_is_first_lock()) {
|
|
|
|
break;
|
|
|
|
}
|
2023-03-01 15:46:22 +08:00
|
|
|
//! This May break the thread
|
|
|
|
// if (_VMEvent_getVMCnt() <= 0) {
|
|
|
|
// break;
|
|
|
|
// }
|
2023-02-26 17:00:36 +08:00
|
|
|
pika_debug("VM num %d", _VMEvent_getVMCnt());
|
2023-02-01 15:54:20 +08:00
|
|
|
pika_platform_thread_delay();
|
|
|
|
}
|
2023-02-13 22:20:25 +08:00
|
|
|
pika_debug("thread start");
|
2023-02-13 20:00:51 +08:00
|
|
|
pika_GIL_ENTER();
|
2023-03-08 21:14:19 +08:00
|
|
|
PikaObj* ctx = New_TinyObj(NULL);
|
2023-02-01 15:54:20 +08:00
|
|
|
pika_thread_info* info = (pika_thread_info*)arg;
|
2023-04-15 11:34:17 +08:00
|
|
|
if (NULL != info->args) {
|
|
|
|
obj_setArg(ctx, "args", info->args);
|
|
|
|
}
|
2023-02-01 15:54:20 +08:00
|
|
|
obj_setArg(ctx, "thread", info->function);
|
2023-04-15 11:34:17 +08:00
|
|
|
|
|
|
|
if (NULL == info->args) {
|
|
|
|
/* clang-format off */
|
|
|
|
PIKA_PYTHON(
|
|
|
|
thread()
|
|
|
|
)
|
|
|
|
/* clang-format on */
|
|
|
|
const uint8_t bytes[] = {
|
|
|
|
0x04, 0x00, 0x00, 0x00, /* instruct array size */
|
|
|
|
0x00, 0x82, 0x01, 0x00, /* instruct array */
|
|
|
|
0x08, 0x00, 0x00, 0x00, /* const pool size */
|
|
|
|
0x00, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x00, /* const pool */
|
|
|
|
};
|
|
|
|
pikaVM_runByteCode(ctx, (uint8_t*)bytes);
|
|
|
|
} else {
|
|
|
|
/* clang-format off */
|
|
|
|
PIKA_PYTHON(
|
|
|
|
thread(*args)
|
|
|
|
)
|
|
|
|
/* clang-format on */
|
|
|
|
const uint8_t bytes[] = {
|
|
|
|
0x0c, 0x00, 0x00, 0x00, /* instruct array size */
|
|
|
|
0x20, 0x81, 0x01, 0x00, 0x10, 0x08, 0x06, 0x00, 0x00, 0x02, 0x08,
|
|
|
|
0x00,
|
|
|
|
/* instruct array */
|
|
|
|
0x0f, 0x00, 0x00, 0x00, /* const pool size */
|
|
|
|
0x00, 0x61, 0x72, 0x67, 0x73, 0x00, 0x2a, 0x00, 0x74, 0x68, 0x72,
|
|
|
|
0x65, 0x61, 0x64, 0x00, /* const pool */
|
|
|
|
};
|
|
|
|
pikaVM_runByteCode(ctx, (uint8_t*)bytes);
|
|
|
|
}
|
2023-02-01 15:54:20 +08:00
|
|
|
obj_deinit(ctx);
|
|
|
|
arg_deinit(info->function);
|
2023-04-15 11:34:17 +08:00
|
|
|
if (NULL != info->args) {
|
|
|
|
arg_deinit(info->args);
|
|
|
|
}
|
2023-04-17 09:42:28 +08:00
|
|
|
g_PikaMemInfo.heapUsed -= info->stack_size;
|
2023-02-13 22:20:25 +08:00
|
|
|
pika_debug("thread exiting");
|
2023-02-14 16:33:34 +08:00
|
|
|
pika_platform_thread_t* thread = info->thread;
|
2023-02-01 15:54:20 +08:00
|
|
|
pikaFree(info, sizeof(pika_thread_info));
|
2023-02-14 16:33:34 +08:00
|
|
|
pika_GIL_EXIT();
|
|
|
|
#if PIKA_FREERTOS_ENABLE
|
|
|
|
pikaFree(thread, sizeof(pika_platform_thread_t));
|
|
|
|
pika_platform_thread_exit(NULL);
|
|
|
|
#else
|
|
|
|
pika_platform_thread_exit(thread);
|
|
|
|
#endif
|
2023-02-01 15:54:20 +08:00
|
|
|
}
|
|
|
|
|
2023-04-15 11:34:17 +08:00
|
|
|
int PikaStdData_Tuple_len(PikaObj* self);
|
|
|
|
|
2023-02-01 15:54:20 +08:00
|
|
|
void _thread_start_new_thread(PikaObj* self, Arg* function, Arg* args_) {
|
|
|
|
pika_thread_info* info =
|
|
|
|
(pika_thread_info*)pikaMalloc(sizeof(pika_thread_info));
|
2023-04-15 11:34:17 +08:00
|
|
|
pika_platform_memset(info, 0, sizeof(pika_thread_info));
|
2023-02-01 15:54:20 +08:00
|
|
|
info->function = arg_copy(function);
|
2023-04-15 11:34:17 +08:00
|
|
|
|
|
|
|
PikaObj* tuple = arg_getPtr(args_);
|
|
|
|
size_t tuple_size = PikaStdData_Tuple_len(tuple);
|
|
|
|
if (tuple_size > 0) {
|
|
|
|
info->args = arg_copy(args_);
|
|
|
|
}
|
2023-02-01 15:54:20 +08:00
|
|
|
_VM_lock_init();
|
2023-04-17 09:42:28 +08:00
|
|
|
info->stack_size = g_thread_stack_size;
|
|
|
|
info->thread = pika_platform_thread_init("pika_thread", _thread_func, info,
|
|
|
|
info->stack_size, PIKA_THREAD_PRIO,
|
|
|
|
PIKA_THREAD_TICK);
|
2023-04-16 18:34:11 +08:00
|
|
|
if (NULL == info->thread) {
|
|
|
|
pikaFree(info, sizeof(pika_thread_info));
|
|
|
|
obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
|
|
|
|
obj_setSysOut(self, "thread create failed");
|
2023-04-17 09:42:28 +08:00
|
|
|
return;
|
2023-04-16 18:34:11 +08:00
|
|
|
}
|
2023-04-17 09:42:28 +08:00
|
|
|
g_PikaMemInfo.heapUsed += info->stack_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
int _thread_stack_size(PikaObj* self, PikaTuple* size) {
|
|
|
|
if (pikaTuple_getSize(size) == 1) {
|
|
|
|
int stack_size = pikaTuple_getInt(size, 0);
|
|
|
|
if (stack_size == 0) {
|
|
|
|
stack_size = PIKA_THREAD_STACK_SIZE;
|
|
|
|
}
|
|
|
|
g_thread_stack_size = stack_size;
|
|
|
|
}
|
|
|
|
return g_thread_stack_size;
|
2023-02-01 15:54:20 +08:00
|
|
|
}
|