Exemple #1
0
void mp_thread_create_ex(void *(*entry)(void*), void *arg, size_t *stack_size, int priority, char *name) {
    // store thread entry function into a global variable so we can access it
    //ext_thread_entry = entry;

    if (*stack_size == 0) {
        *stack_size = MP_THREAD_DEFAULT_STACK_SIZE; // default stack size
    } else if (*stack_size < MP_THREAD_MIN_STACK_SIZE) {
        *stack_size = MP_THREAD_MIN_STACK_SIZE; // minimum stack size
    }

    // allocate TCB, stack and linked-list node (must be outside thread_mutex lock)
    StackType_t *stack = NULL;

    // thread_t *th = m_new_obj(thread_t);
    thread_t *th = (thread_t*)malloc(sizeof(thread_t));

    mp_thread_mutex_lock(&thread_mutex, 1);

    // create thread
    TaskHandle_t thread_id;
    TaskStatus_t task_status;
	//todo add schedule processor
    xTaskCreateAtProcessor(0, // processor
						   entry, // function entry
						   name, //task name
						   *stack_size / sizeof(StackType_t), //stack_deepth
						   arg, //function arg
						   priority, //task priority,please don't change this parameter,because it will impack function running
						   &thread_id);//task handle
    //mp_printf(&mp_plat_print, "[MAIXPY]: thread_id %p created \n",thread_id);
    if (thread_id == NULL) {
        // m_del_obj(thread_t,th);
        free(th);
        mp_thread_mutex_unlock(&thread_mutex);
        nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "can't create thread"));
    }
	vTaskGetInfo(thread_id,&task_status,(BaseType_t)pdTRUE,(eTaskState)eInvalid);
	stack = task_status.pxStackBase;
    // adjust the stack_size to provide room to recover from hitting the limit
    *stack_size -= 1024;

    // add thread to linked list of all threads
    th->id = thread_id;
    th->ready = 0;
    th->arg = arg;
    th->stack = stack;
	//stack_len may be a bug,because that k210 addr width is 64 bit ,but addr width is 32bit
	//the StackType_t type is a type of the uintprt_t,uintprt_t in k210 is 64bit 
    th->stack_len = *stack_size / sizeof(StackType_t);
    th->next = thread;
    thread = th;
    mp_thread_mutex_unlock(&thread_mutex);

}
STATIC mp_obj_t thread_lock_release(mp_obj_t self_in) {
    mp_obj_thread_lock_t *self = MP_OBJ_TO_PTR(self_in);
    // TODO check if already unlocked
    self->locked = false;
    MP_THREAD_GIL_EXIT();
    mp_thread_mutex_unlock(&self->mutex);
    MP_THREAD_GIL_ENTER();
    return mp_const_none;
}
Exemple #3
0
STATIC mp_obj_t thread_lock_release(mp_obj_t self_in) {
    mp_obj_thread_lock_t *self = MP_OBJ_TO_PTR(self_in);
    // TODO check if already unlocked
    self->locked = false;
    #if !MICROPY_PY_THREAD_GIL
    mp_thread_mutex_unlock(&self->mutex);
    #endif
    return mp_const_none;
}
Exemple #4
0
void mp_thread_start(void) {
    mp_thread_mutex_lock(&thread_mutex, 1);
    for (thread_t *th = thread; th != NULL; th = th->next) {
        if (th->id == xTaskGetCurrentTaskHandle()) {
            th->ready = 1;
            break;
        }
    }
    mp_thread_mutex_unlock(&thread_mutex);
}
Exemple #5
0
STATIC mp_obj_t thread_lock_release(mp_obj_t self_in) {
    mp_obj_thread_lock_t *self = MP_OBJ_TO_PTR(self_in);
    if (!self->locked) {
        mp_raise_msg(&mp_type_RuntimeError, NULL);
    }
    self->locked = false;
    MP_THREAD_GIL_EXIT();
    mp_thread_mutex_unlock(&self->mutex);
    MP_THREAD_GIL_ENTER();
    return mp_const_none;
}
Exemple #6
0
void mp_thread_finish(void) {
    mp_thread_mutex_lock(&thread_mutex, 1);
    // TODO unlink from list
    for (thread_t *th = thread; th != NULL; th = th->next) {
        if (th->id == xTaskGetCurrentTaskHandle()) {
            th->ready = 0;
            break;
        }
    }
    mp_thread_mutex_unlock(&thread_mutex);
}
Exemple #7
0
int mp_thread_gc_others(void) {
/*    mp_thread_mutex_lock(&thread_mutex, 1);
    for (thread_t *th = thread; th != NULL; th = th->next) {
        gc_collect_root((void**)&th, 1);
        gc_collect_root(&th->arg, 1); // probably not needed
        if (th->id == xTaskGetCurrentTaskHandle()) {
            continue;
        }
        if (!th->ready) {
            continue;
        }
        gc_collect_root(th->stack, th->stack_len); // probably not needed
    }
    mp_thread_mutex_unlock(&thread_mutex);
*/
    int n_th = 0;
    void **ptrs;
    mp_state_thread_t *state;

    mp_thread_mutex_lock(&thread_mutex, 1);
    for (thread_t *th = thread; th != NULL; th = th->next) {
        if (!th->ready) continue;                               // thread not ready
		//if (th->type == THREAD_TYPE_SERVICE) continue;          // Only scan PYTHON threads
        if (th->id == xTaskGetCurrentTaskHandle()) continue;    // Do not process the running thread

        //state = (mp_state_thread_t *)th->state_thread;
        n_th++;

        // Mark the root pointers on thread
        //gc_collect_root((void **)state->dict_locals, 1);

        if (th->arg) {
            // Mark the pointers on thread arguments
            ptrs = (void**)(void*)&th->arg;
            gc_collect_root(ptrs, 1);
        }

        #if MICROPY_ENABLE_PYSTACK
        // Mark the pointers on thread pystack
        //ptrs = (void**)(void*)state->pystack_start;
        //gc_collect_root(ptrs, (state->pystack_cur - state->pystack_start) / sizeof(void*));
        #endif

        // If PyStack is used, no pointers to MPy heap are placed on tasks stack
        #if !MICROPY_ENABLE_PYSTACK
        // Mark the pointers on thread stack
        //gc_collect_root(th->curr_sp, ((void *)state->stack_top - th->curr_sp) / sizeof(void*)); // probably not needed
        #endif
    }
    mp_thread_mutex_unlock(&thread_mutex);
    return n_th;
	
}
Exemple #8
0
void mp_thread_create(void *(*entry)(void*), void *arg, size_t *stack_size) {
    // store thread entry function into a global variable so we can access it
    ext_thread_entry = entry;

    if (*stack_size == 0) {
        *stack_size = 4096; // default stack size
    } else if (*stack_size < 2048) {
        *stack_size = 2048; // minimum stack size
    }

    // allocate TCB, stack and linked-list node (must be outside thread_mutex lock)
    StaticTask_t *tcb = m_new(StaticTask_t, 1);
    StackType_t *stack = m_new(StackType_t, *stack_size / sizeof(StackType_t));
    thread_t *th = m_new_obj(thread_t);

    mp_thread_mutex_lock(&thread_mutex, 1);

    // create thread
    TaskHandle_t id = xTaskCreateStatic(freertos_entry, "Thread", *stack_size / sizeof(void*), arg, 2, stack, tcb);
    if (id == NULL) {
        mp_thread_mutex_unlock(&thread_mutex);
        mp_raise_msg(&mp_type_OSError, "can't create thread");
    }

    // add thread to linked list of all threads
    th->id = id;
    th->ready = 0;
    th->arg = arg;
    th->stack = stack;
    th->stack_len = *stack_size / sizeof(StackType_t);
    th->next = thread;
    thread = th;

    mp_thread_mutex_unlock(&thread_mutex);

    // adjust stack_size to provide room to recover from hitting the limit
    *stack_size -= 512;
}
Exemple #9
0
void mp_thread_finish(void) {
    mp_thread_mutex_lock(&thread_mutex, 1);
    thread_t *th = thread;
    thread_t *pre_th = NULL;
    for (th = thread; th != NULL; th = th->next) {
        if (th->id == xTaskGetCurrentTaskHandle()) {
            th->ready = 0;
            //mp_thread_delete(pre_th,th);//TODO:wether need to delete threand to free memory
            break;
        }
        pre_th = th;
    }
    mp_thread_mutex_unlock(&thread_mutex);
}
Exemple #10
0
void mp_thread_gc_others(void) {
    mp_thread_mutex_lock(&thread_mutex, 1);
    for (thread_t *th = thread; th != NULL; th = th->next) {
        gc_collect_root((void**)&th, 1);
        gc_collect_root(&th->arg, 1); // probably not needed
        if (th->id == xTaskGetCurrentTaskHandle()) {
            continue;
        }
        if (!th->ready) {
            continue;
        }
        gc_collect_root(th->stack, th->stack_len); // probably not needed
    }
    mp_thread_mutex_unlock(&thread_mutex);
}
Exemple #11
0
void mp_thread_deinit(void) {

    mp_thread_mutex_lock(&thread_mutex, 1);
    for (thread_t *th = thread; th != NULL; th = th->next) {
        // don't delete the current task
        if (th->id == xTaskGetCurrentTaskHandle()) {
            continue;
        }
        vTaskDelete(th->id);
        // m_del_obj(thread_t,th);
        free(th);
    }
    mp_thread_mutex_unlock(&thread_mutex);
    // allow FreeRTOS to clean-up the threads
    vTaskDelay(2);

}