/// Change prority of an active thread osStatus osThreadSetPriority(osThreadId thread_id, osPriority priority) { rt_err_t result; if (thread_id == RT_NULL) return osErrorOS; if (priority < osPriorityIdle || priority > osPriorityRealtime) return osErrorPriority; result = rt_thread_control(thread_id, RT_THREAD_CTRL_CHANGE_PRIORITY, &priority); if (result == RT_EOK) return osOK; else return osErrorOS; }
/** * This function will release a mutex, if there are threads suspended on mutex, * it will be waked up. * * @param mutex the mutex object * * @return the error code */ rt_err_t rt_mutex_release(rt_mutex_t mutex) { register rt_base_t temp; struct rt_thread* thread; rt_bool_t need_schedule; need_schedule = RT_FALSE; /* get current thread */ thread = rt_thread_self(); /* disable interrupt */ temp = rt_hw_interrupt_disable(); #ifdef RT_IPC_DEBUG rt_kprintf("mutex_release:current thread %s, mutex value: %d, hold: %d\n", thread->name, mutex->value, mutex->hold); #endif #ifdef RT_USING_HOOK if (rt_object_put_hook != RT_NULL) rt_object_put_hook(&(mutex->parent.parent)); #endif /* mutex only can be released by owner */ if (thread != mutex->owner) { thread->error = -RT_ERROR; /* enable interrupt */ rt_hw_interrupt_enable(temp); return -RT_ERROR; } /* decrease hold */ mutex->hold --; /* if no hold */ if (mutex->hold == 0) { /* change the owner thread to original priority */ if (mutex->owner->init_priority != mutex->owner->current_priority) { rt_thread_control(mutex->owner, RT_THREAD_CTRL_CHANGE_PRIORITY, &(mutex->owner->init_priority)); } /* wakeup suspended thread */ if (mutex->parent.suspend_thread_count > 0) { /* get thread entry */ thread = rt_list_entry(mutex->parent.suspend_thread.next, struct rt_thread, tlist); #ifdef RT_IPC_DEBUG rt_kprintf("mutex_release: resume thread: %s\n", thread->name); #endif /* set new owner and priority */ mutex->owner = thread; mutex->original_priority = thread->current_priority; mutex->hold ++; /* resume thread */ rt_ipc_object_resume(&(mutex->parent)); need_schedule = RT_TRUE; } else {
/** * This function will take a mutex, if the mutex is unavailable, the * thread shall wait for a specified time. * * @param mutex the mutex object * @param time the waiting time * * @return the error code */ rt_err_t rt_mutex_take (rt_mutex_t mutex, rt_int32_t time) { register rt_base_t temp; struct rt_thread* thread; RT_ASSERT(mutex != RT_NULL); /* disable interrupt */ temp = rt_hw_interrupt_disable(); /* get current thread */ thread = rt_thread_self(); #ifdef RT_USING_HOOK if (rt_object_trytake_hook != RT_NULL) rt_object_trytake_hook(&(mutex->parent.parent)); #endif #ifdef RT_IPC_DEBUG rt_kprintf("mutex_take: current thread %s, mutex value: %d, hold: %d\n", thread->name, mutex->value, mutex->hold); #endif /* reset thread error */ thread->error = RT_EOK; if (mutex->owner == thread) { /* it's the same thread */ mutex->hold ++; } else { /* in initialization status, the value is 1. Therefore, if the * value is great than 1, which indicates the mutex is avaible. */ if (mutex->value > 0) { /* mutex is available */ mutex->value --; /* set mutex owner and original priority */ mutex->owner = thread; mutex->original_priority = thread->current_priority; mutex->hold ++; } else { /* no waiting, return with timeout */ if (time == 0 ) { /* set error as timeout */ thread->error = -RT_ETIMEOUT; /* enable interrupt */ rt_hw_interrupt_enable(temp); return -RT_ETIMEOUT; } else { /* mutex is unavailable, push to suspend list */ #ifdef RT_IPC_DEBUG rt_kprintf("mutex_take: suspend thread: %s\n", thread->name); #endif /* change the owner thread priority of mutex */ if (thread->current_priority < mutex->owner->current_priority) { /* change the owner thread priority */ rt_thread_control(mutex->owner, RT_THREAD_CTRL_CHANGE_PRIORITY, &thread->current_priority); } /* suspend current thread */ rt_ipc_object_suspend(&(mutex->parent), thread); /* has waiting time, start thread timer */ if (time > 0) { #ifdef RT_IPC_DEBUG rt_kprintf("mutex_take: start the timer of thread:%s\n", thread->name); #endif /* reset the timeout of thread timer and start it */ rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &time); rt_timer_start(&(thread->thread_timer)); } /* enable interrupt */ rt_hw_interrupt_enable(temp); /* do schedule */ rt_schedule(); if (thread->error != RT_EOK) { /* decrease suspended thread count */ rt_ipc_object_decrease(&(mutex->parent)); /* return error */ return thread->error; } else { /* the mutex is taken successfully. */ /* disable interrupt */ temp = rt_hw_interrupt_disable(); } } } } /* enable interrupt */ rt_hw_interrupt_enable(temp); #ifdef RT_USING_HOOK if (rt_object_take_hook != RT_NULL) rt_object_take_hook(&(mutex->parent.parent)); #endif return RT_EOK; }