summaryrefslogtreecommitdiff
path: root/src/ipc.c
diff options
context:
space:
mode:
authorbernard.xiong <[email protected]>2009-08-31 12:31:19 +0000
committerbernard.xiong <[email protected]>2009-08-31 12:31:19 +0000
commitdc638b887c8178cc66933ac0ea21d6bcf0e9f577 (patch)
tree58dfed52c84715d8946c24d4be54ea13e433f9dc /src/ipc.c
parentfb8925dba21c10b60c09a6fe858fd74312f16b8f (diff)
fix the fast event receive bug
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@29 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'src/ipc.c')
-rw-r--r--src/ipc.c40
1 files changed, 32 insertions, 8 deletions
diff --git a/src/ipc.c b/src/ipc.c
index 6e783f45dc..abf96c9eb7 100644
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -23,7 +23,8 @@
* 2006-06-07 Bernard fix the message queue send bug
* 2006-08-04 Bernard add hook support
* 2009-05-21 Yi.qiu fix the sem release bug
- * 2009-07-18 Bernard fix the event clear bug
+ * 2009-07-18 Bernard fix the event clear bug
+ * 2009-08-31 Bernard fix the fast event receive bug
*/
#include <rtthread.h>
@@ -979,6 +980,7 @@ rt_err_t rt_fast_event_send(rt_fast_event_t event, rt_uint8_t bit)
register rt_ubase_t level;
struct rt_thread *thread;
struct rt_list_node *n;
+ rt_bool_t need_schedule;
/* parameter check */
RT_ASSERT(event != RT_NULL);
@@ -994,6 +996,9 @@ rt_err_t rt_fast_event_send(rt_fast_event_t event, rt_uint8_t bit)
level = rt_hw_interrupt_disable();
event->set |= offset;
+
+ /* does not schedule */
+ need_schedule = RT_FALSE;
/* if thread list at offset is not empty */
n = event->thread_list[bit].next;
@@ -1005,19 +1010,19 @@ rt_err_t rt_fast_event_send(rt_fast_event_t event, rt_uint8_t bit)
/* move to next node */
n = n->next;
- /* clear bit or not */
- if (thread->event_info & RT_EVENT_FLAG_CLEAR)
- event->set &= ~offset;
-
/* resume thread */
- rt_thread_resume(thread);
+ rt_thread_resume(thread);
+
+ /* need do a scheduling */
+ need_schedule = RT_TRUE;
}
/* enable interrupt */
rt_hw_interrupt_enable(level);
- /* do a schedule */
- rt_schedule();
+ /* do a schedule */
+ if (need_schedule == RT_TRUE)
+ rt_schedule();
return RT_EOK;
}
@@ -1116,7 +1121,26 @@ rt_err_t rt_fast_event_recv(rt_fast_event_t event, rt_uint8_t bit, rt_uint8_t op
/* reset the timeout of thread timer and start it */
rt_timer_control(&(thread->thread_timer), RT_TIMER_CTRL_SET_TIME, &timeout);
rt_timer_start(&(thread->thread_timer));
+ }
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+
+ /* do a schedule */
+ rt_schedule();
+
+ /* receive a fast event */
+ if (thread->error != RT_EOK)
+ {
+ return thread->error;
}
+
+ /* received a event, disable interrupt to protect */
+ level = rt_hw_interrupt_disable();
+
+ /* clear event */
+ if (option & RT_EVENT_FLAG_CLEAR)
+ event->set &= ~offset;
}
/* enable interrupt */