static rt_err_t _rt_thread_init(struct rt_thread *thread, const char *name, void (*entry)(void *parameter), void *parameter, void *stack_start, rt_uint32_t stack_size, rt_uint8_t priority, rt_uint32_t tick) { /* init thread list */ rt_list_init(&(thread->tlist)); thread->entry = (void *)entry; thread->parameter = parameter; /* stack init */ thread->stack_addr = stack_start; thread->stack_size = (rt_uint16_t)stack_size; /* init thread stack */ rt_memset(thread->stack_addr, '#', thread->stack_size); thread->sp = (void *)rt_hw_stack_init(thread->entry, thread->parameter, (void *)((char *)thread->stack_addr + thread->stack_size - 4), (void *)rt_thread_exit); /* priority init */ RT_ASSERT(priority < RT_THREAD_PRIORITY_MAX); thread->init_priority = priority; thread->current_priority = priority; /* tick init */ thread->init_tick = tick; thread->remaining_tick = tick; /* error and flags */ thread->error = RT_EOK; thread->stat = RT_THREAD_INIT; /* initialize cleanup function and user data */ thread->cleanup = 0; thread->user_data = 0; /* init thread timer */ rt_timer_init(&(thread->thread_timer), thread->name, rt_thread_timeout, thread, 0, RT_TIMER_FLAG_ONE_SHOT); return RT_EOK; }
static void _signal_deliver(rt_thread_t tid) { rt_ubase_t level; /* thread is not interested in pended signals */ if (!(tid->sig_pending & tid->sig_mask)) return; level = rt_hw_interrupt_disable(); if (tid->stat == RT_THREAD_SUSPEND) { /* resume thread to handle signal */ rt_thread_resume(tid); /* add signal state */ tid->stat |= RT_THREAD_STAT_SIGNAL; rt_hw_interrupt_enable(level); /* re-schedule */ rt_schedule(); } else { if (tid == rt_thread_self()) { /* add signal state */ tid->stat |= RT_THREAD_STAT_SIGNAL; rt_hw_interrupt_enable(level); /* do signal action in self thread context */ rt_thread_handle_sig(RT_TRUE); } else if (!(tid->stat & RT_THREAD_STAT_SIGNAL)) { tid->stat |= RT_THREAD_STAT_SIGNAL; /* point to the signal handle entry */ tid->sig_ret = tid->sp; tid->sp = rt_hw_stack_init((void*)_signal_entry, RT_NULL, (void *)((char *)tid->sig_ret - 32), RT_NULL); rt_hw_interrupt_enable(level); dbg_log(DBG_LOG, "signal stack pointer @ 0x%08x\n", tid->sp); /* re-schedule */ rt_schedule(); } else { rt_hw_interrupt_enable(level); } } }