初始化的函数还是比较简单的,主要做了下面的流程,
(1)初始化互斥结构的公共属性,比如名字、阻塞方式等等;
(2)初始化当前资源数量;
(3)初始化占有资源的线程指针,还有就是线程的优先级。
创建了互斥量之后,我们就要看看互斥量是怎么申请的?代码有点长,同学们可以心理调整一下了,
RAW_U16 raw_mutex_get(RAW_MUTEX *mutex_ptr, RAW_U32 wait_option) { RAW_U16 error_status; RAW_SR_ALLOC(); #if (RAW_MUTEX_FUNCTION_CHECK > 0) if (mutex_ptr == 0) { return RAW_NULL_OBJECT; } if (raw_int_nesting) { return RAW_NOT_CALLED_BY_ISR; } #endif RAW_CRITICAL_ENTER(); /* mutex is available */ if (mutex_ptr->count) { mutex_ptr->occupy = raw_task_active; mutex_ptr->occupy_original_priority = raw_task_active->priority; mutex_ptr->count = 0; RAW_CRITICAL_EXIT(); return RAW_SUCCESS; } /*if the same task get the same mutex again, it causes deadlock*/ if (raw_task_active == mutex_ptr->occupy) { #if (CONFIG_RAW_ASSERT > 0) RAW_ASSERT(0); #endif RAW_CRITICAL_EXIT(); return RAW_MUTEX_DEADLOCK; } /*Cann't get mutex, and return immediately if wait_option is RAW_NO_WAIT*/ if (wait_option == RAW_NO_WAIT) { RAW_CRITICAL_EXIT(); return RAW_NO_PEND_WAIT; } /*system is locked so task can not be blocked just return immediately*/ if (raw_sched_lock) { RAW_CRITICAL_EXIT(); return RAW_SCHED_DISABLE; } /*if current task is a higher priority task and block on the mutex *priority inverse condition happened, priority inherit method is used here*/ if (raw_task_active->priority < mutex_ptr->occupy->priority) { switch (mutex_ptr->occupy->task_state) { case RAW_RDY: /*remove from the ready list*/ remove_ready_list(&raw_ready_queue, mutex_ptr->occupy); /*raise the occupy task priority*/ mutex_ptr->occupy->priority = raw_task_active->priority; /*readd to the ready list head*/ add_ready_list_head(&raw_ready_queue, mutex_ptr->occupy); break; case RAW_DLY: case RAW_DLY_SUSPENDED: case RAW_SUSPENDED: /*occupy task is not on any list, so just change the priority*/ mutex_ptr->occupy->priority = raw_task_active->priority; break; case RAW_PEND: /* Change the position of the task in the wait list */ case RAW_PEND_TIMEOUT: case RAW_PEND_SUSPENDED: case RAW_PEND_TIMEOUT_SUSPENDED: /*occupy task is on the block list so change the priority on the block list*/ mutex_ptr->occupy->priority = raw_task_active->priority; change_pend_list_priority(mutex_ptr->occupy); break; default: RAW_CRITICAL_EXIT(); return RAW_INVALID_STATE; } } /*Any way block the current task*/ raw_pend_object(&mutex_ptr->common_block_obj, raw_task_active, wait_option); RAW_CRITICAL_EXIT(); /*find the next highest priority task ready to run*/ raw_sched(); /*So the task is waked up, need know which reason cause wake up.*/ error_status = block_state_post_process(raw_task_active, 0); return error_status; } |