/** * This function will release a semaphore, if there are threads suspended on * semaphore, it will be waked up. * * @param sem the semaphore object * * @return the error code */ rt_err_t rt_sem_release(rt_sem_t sem) { register rt_base_t temp; register rt_bool_t need_schedule; #ifdef RT_USING_HOOK if (rt_object_put_hook != RT_NULL) rt_object_put_hook(&(sem->parent.parent)); #endif need_schedule = RT_FALSE; /* disable interrupt */ temp = rt_hw_interrupt_disable(); #ifdef RT_IPC_DEBUG rt_kprintf("thread %s releases sem:%s, which value is: %d\n", rt_thread_self()->name, ((struct rt_object*)sem)->name, sem->value); #endif if (sem->parent.suspend_thread_count > 0) { /* resume the suspended thread */ rt_ipc_object_resume(&(sem->parent)); need_schedule = RT_TRUE; } else sem->value ++; /* increase value */ /* enable interrupt */ rt_hw_interrupt_enable(temp); /* resume a thread, re-schedule */ if (need_schedule == RT_TRUE) rt_schedule(); return RT_EOK; }
/** * This function will stop the timer * * @param timer the timer to be stopped * * @return the operation status, RT_EOK on OK, -RT_ERROR on error * */ rt_err_t rt_timer_stop(rt_timer_t timer) { register rt_base_t level; /* timer check */ RT_ASSERT(timer != RT_NULL); if(!(timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)) return -RT_ERROR; #ifdef RT_USING_HOOK if (rt_object_put_hook != RT_NULL) rt_object_put_hook(&(timer->parent)); #endif /* disable interrupt */ level = rt_hw_interrupt_disable(); /* change stat */ timer->parent.flag &= ~RT_TIMER_FLAG_ACTIVATED; /* remove it from timer list */ rt_list_remove(&(timer->list)); /* enable interrupt */ rt_hw_interrupt_enable(level); return RT_EOK; }
/** * 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 {