_thread.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #include "_thread.h"
  2. #include "PikaVM.h"
  3. #include "TinyObj.h"
  4. static volatile int g_thread_stack_size = PIKA_THREAD_STACK_SIZE;
  5. extern volatile PikaMemInfo g_PikaMemInfo;
  6. typedef struct pika_thread_info {
  7. Arg* function;
  8. Arg* args;
  9. pika_platform_thread_t* thread;
  10. int stack_size;
  11. } pika_thread_info;
  12. static void _thread_func(void* arg) {
  13. pika_debug("thread start");
  14. pika_GIL_ENTER();
  15. PikaObj* ctx = New_TinyObj(NULL);
  16. pika_thread_info* info = (pika_thread_info*)arg;
  17. if (NULL != info->args) {
  18. obj_setArg(ctx, "args", info->args);
  19. }
  20. obj_setArg(ctx, "thread", info->function);
  21. if (NULL == info->args) {
  22. /* clang-format off */
  23. PIKA_PYTHON(
  24. thread()
  25. )
  26. /* clang-format on */
  27. const uint8_t bytes[] = {
  28. 0x04, 0x00, 0x00, 0x00, /* instruct array size */
  29. 0x00, 0x82, 0x01, 0x00, /* instruct array */
  30. 0x08, 0x00, 0x00, 0x00, /* const pool size */
  31. 0x00, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x00, /* const pool */
  32. };
  33. pikaVM_runByteCode(ctx, (uint8_t*)bytes);
  34. } else {
  35. /* clang-format off */
  36. PIKA_PYTHON(
  37. thread(*args)
  38. )
  39. /* clang-format on */
  40. const uint8_t bytes[] = {
  41. 0x0c, 0x00, 0x00, 0x00, /* instruct array size */
  42. 0x20, 0x81, 0x01, 0x00, 0x10, 0x08, 0x06, 0x00, 0x00, 0x02, 0x08,
  43. 0x00,
  44. /* instruct array */
  45. 0x0f, 0x00, 0x00, 0x00, /* const pool size */
  46. 0x00, 0x61, 0x72, 0x67, 0x73, 0x00, 0x2a, 0x00, 0x74, 0x68, 0x72,
  47. 0x65, 0x61, 0x64, 0x00, /* const pool */
  48. };
  49. pikaVM_runByteCode(ctx, (uint8_t*)bytes);
  50. }
  51. obj_deinit(ctx);
  52. arg_deinit(info->function);
  53. if (NULL != info->args) {
  54. arg_deinit(info->args);
  55. }
  56. g_PikaMemInfo.heapUsed -= info->stack_size;
  57. pika_debug("thread exiting");
  58. pika_platform_thread_t* thread = info->thread;
  59. pikaFree(info, sizeof(pika_thread_info));
  60. pika_GIL_EXIT();
  61. #if PIKA_FREERTOS_ENABLE
  62. pikaFree(thread, sizeof(pika_platform_thread_t));
  63. pika_platform_thread_exit(NULL);
  64. #else
  65. pika_platform_thread_exit(thread);
  66. #endif
  67. }
  68. int PikaStdData_Tuple_len(PikaObj* self);
  69. void _thread_start_new_thread(PikaObj* self, Arg* function, Arg* args_) {
  70. pika_thread_info* info =
  71. (pika_thread_info*)pikaMalloc(sizeof(pika_thread_info));
  72. pika_platform_memset(info, 0, sizeof(pika_thread_info));
  73. info->function = arg_copy(function);
  74. if (arg_isObject(args_)) {
  75. PikaObj* tuple = arg_getPtr(args_);
  76. size_t tuple_size = PikaStdData_Tuple_len(tuple);
  77. if (tuple_size > 0) {
  78. info->args = arg_copy(args_);
  79. }
  80. } else {
  81. info->args = arg_copy(args_);
  82. }
  83. _VM_lock_init();
  84. if (!_VM_is_first_lock()) {
  85. pika_debug("first lock for main thread");
  86. pika_GIL_ENTER();
  87. pika_debug("VM num %d", _VMEvent_getVMCnt());
  88. }
  89. info->stack_size = g_thread_stack_size;
  90. info->thread = pika_platform_thread_init("pika_thread", _thread_func, info,
  91. info->stack_size, PIKA_THREAD_PRIO,
  92. PIKA_THREAD_TICK);
  93. if (NULL == info->thread) {
  94. pikaFree(info, sizeof(pika_thread_info));
  95. obj_setErrorCode(self, PIKA_RES_ERR_RUNTIME_ERROR);
  96. obj_setSysOut(self, "thread create failed");
  97. return;
  98. }
  99. g_PikaMemInfo.heapUsed += info->stack_size;
  100. }
  101. int _thread_stack_size(PikaObj* self, PikaTuple* size) {
  102. if (pikaTuple_getSize(size) == 1) {
  103. int stack_size = pikaTuple_getInt(size, 0);
  104. if (stack_size == 0) {
  105. stack_size = PIKA_THREAD_STACK_SIZE;
  106. }
  107. g_thread_stack_size = stack_size;
  108. }
  109. return g_thread_stack_size;
  110. }