_thread.c 3.2 KB

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