diff options
| author | bernard.xiong <[email protected]> | 2009-10-09 23:58:46 +0000 |
|---|---|---|
| committer | bernard.xiong <[email protected]> | 2009-10-09 23:58:46 +0000 |
| commit | ff705032d81c65274c13ee9cb0d2a3e1d0026052 (patch) | |
| tree | 661d7230277c030c9602e6cc9fd3f3680e6385a2 /src | |
| parent | df1d469cd05809209b7795472adfb2eb4f9824ca (diff) | |
change semaphore and mutex value to unsigned value
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@84 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'src')
| -rw-r--r-- | src/ipc.c | 56 |
1 files changed, 24 insertions, 32 deletions
@@ -25,6 +25,7 @@ * 2009-05-21 Yi.qiu fix the sem release bug * 2009-07-18 Bernard fix the event clear bug * 2009-09-09 Bernard remove fast event and fix ipc release bug + * 2009-10-10 Bernard change semaphore and mutex value to unsigned value */ #include <rtthread.h> @@ -344,8 +345,6 @@ rt_err_t rt_sem_take (rt_sem_t sem, rt_int32_t time) else { /* semaphore is unavailable, push to suspend list */ - sem->value --; - /* get current thread */ thread = rt_thread_self(); @@ -415,11 +414,14 @@ rt_err_t rt_sem_trytake(rt_sem_t sem) 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(); @@ -428,25 +430,20 @@ rt_err_t rt_sem_release(rt_sem_t sem) ((struct rt_object*)sem)->name, sem->value); #endif - /* increase value */ - sem->value ++; - - if (sem->value <= 0 && sem->parent.suspend_thread_count > 0) + if (sem->parent.suspend_thread_count > 0) { /* resume the suspended thread */ rt_ipc_object_resume(&(sem->parent)); - - /* enable interrupt */ - rt_hw_interrupt_enable(temp); - - /* resume a thread, re-schedule */ - rt_schedule(); - return RT_EOK; + 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; } @@ -647,8 +644,6 @@ rt_err_t rt_mutex_take (rt_mutex_t mutex, rt_int32_t time) else { /* mutex is unavailable, push to suspend list */ - mutex->value --; - #ifdef RT_IPC_DEBUG rt_kprintf("mutex_take: suspend thread: %s\n", thread->name); #endif @@ -691,12 +686,8 @@ rt_err_t rt_mutex_take (rt_mutex_t mutex, rt_int32_t time) else { /* the mutex is taken successfully. */ - /* disable interrupt */ temp = rt_hw_interrupt_disable(); - - /* set thread error */ - thread->error = RT_EOK; } } } @@ -724,13 +715,16 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex) { register rt_base_t temp; struct rt_thread* thread; + rt_bool_t need_schedule; - /* disable interrupt */ - temp = rt_hw_interrupt_disable(); + 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); @@ -753,7 +747,6 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex) /* decrease hold */ mutex->hold --; - /* if no hold */ if (mutex->hold == 0) { @@ -764,11 +757,8 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex) &(mutex->owner->init_priority)); } - /* increase value */ - mutex->value ++; - /* wakeup suspended thread */ - if (mutex->value <= 0 && mutex->parent.suspend_thread_count > 0) + if (mutex->parent.suspend_thread_count > 0) { /* get thread entry */ thread = rt_list_entry(mutex->parent.suspend_thread.next, struct rt_thread, tlist); @@ -783,24 +773,26 @@ rt_err_t rt_mutex_release(rt_mutex_t mutex) /* resume thread */ rt_ipc_object_resume(&(mutex->parent)); + + need_schedule = RT_TRUE; } else { + /* increase value */ + mutex->value ++; + /* clear owner */ mutex->owner = RT_NULL; mutex->original_priority = 0; } - - /* enable interrupt */ - rt_hw_interrupt_enable(temp); - - rt_schedule(); - return RT_EOK; } /* enable interrupt */ rt_hw_interrupt_enable(temp); + /* perform a schedule */ + if (need_schedule == RT_TRUE) rt_schedule(); + return RT_EOK; } |
