summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorHubretXie <[email protected]>2019-11-26 09:30:21 +0800
committerGitHub <[email protected]>2019-11-26 09:30:21 +0800
commit17f7f1c7ca2581b2e308888f8acb99ca8a541422 (patch)
tree5236e93ab1e4e24508d4ebf4540b6743dd7c9a41 /src
parent9662e18c3688681cd95ebd65242773dbe7c1366b (diff)
parente459084fe028c837762d40326a9be3dfdc179894 (diff)
Merge pull request #8 from RT-Thread/master
sync
Diffstat (limited to 'src')
-rw-r--r--src/Kconfig12
-rw-r--r--src/SConscript6
-rw-r--r--src/clock.c2
-rw-r--r--src/components.c7
-rw-r--r--src/cpu.c99
-rw-r--r--src/idle.c12
-rw-r--r--src/ipc.c132
-rw-r--r--src/mempool.c14
-rw-r--r--src/scheduler.c47
-rw-r--r--src/thread.c13
10 files changed, 286 insertions, 58 deletions
diff --git a/src/Kconfig b/src/Kconfig
index d301d25f55..22942a017e 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -20,7 +20,7 @@ config RT_USING_ARCH_DATA_TYPE
config RT_USING_SMP
bool "Enable SMP(Symmetric multiprocessing)"
default n
- help
+ help
This option should be selected by machines which have an SMP-
capable CPU.
The only effect of this option is to make the SMP-related
@@ -28,10 +28,10 @@ config RT_USING_SMP
config RT_CPUS_NR
int "Number of CPUs"
- default 2
- depends on RT_USING_SMP
+ default 2
+ depends on RT_USING_SMP
help
- Number of CPUs in the system
+ Number of CPUs in the system
config RT_ALIGN_SIZE
int "Alignment size for CPU architecture data access"
@@ -86,8 +86,8 @@ config RT_USING_IDLE_HOOK
default y if RT_USING_HOOK
if RT_USING_IDLE_HOOK
- config RT_IDEL_HOOK_LIST_SIZE
- int "The max size of idel hook list"
+ config RT_IDLE_HOOK_LIST_SIZE
+ int "The max size of idle hook list"
default 4
range 1 16
help
diff --git a/src/SConscript b/src/SConscript
index 7f448725a2..82c3b8aaf1 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -6,9 +6,6 @@ src = Glob('*.c')
CPPPATH = [RTT_ROOT + '/include']
-if GetDepend('RT_USING_COMPONENTS_INIT') == False:
- SrcRemove(src, ['components.c'])
-
if GetDepend('RT_USING_MODULE') == False:
SrcRemove(src, ['module.c'])
@@ -29,6 +26,9 @@ if GetDepend('RT_USING_MEMHEAP') == False:
if GetDepend('RT_USING_DEVICE') == False:
SrcRemove(src, ['device.c'])
+if GetDepend('RT_USING_SMP') == False:
+ SrcRemove(src, ['cpu.c'])
+
group = DefineGroup('Kernel', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
diff --git a/src/clock.c b/src/clock.c
index a652282b6e..9b54101363 100644
--- a/src/clock.c
+++ b/src/clock.c
@@ -89,6 +89,8 @@ void rt_tick_increase(void)
/* change to initialized tick */
thread->remaining_tick = thread->init_tick;
+ thread->stat |= RT_THREAD_STAT_YIELD;
+
/* yield */
rt_thread_yield();
}
diff --git a/src/components.c b/src/components.c
index b9fc4c178c..df3e0f0fb3 100644
--- a/src/components.c
+++ b/src/components.c
@@ -126,6 +126,7 @@ void rt_components_init(void)
}
#endif
}
+#endif /* RT_USING_COMPONENTS_INIT */
#ifdef RT_USING_USER_MAIN
@@ -173,10 +174,11 @@ void main_thread_entry(void *parameter)
{
extern int main(void);
extern int $Super$$main(void);
-
+
+#ifdef RT_USING_COMPONENTS_INIT
/* RT-Thread components initialization */
rt_components_init();
-
+#endif
#ifdef RT_USING_SMP
rt_hw_secondary_cpu_up();
#endif
@@ -254,4 +256,3 @@ int rtthread_startup(void)
return 0;
}
#endif
-#endif
diff --git a/src/cpu.c b/src/cpu.c
index fe3ba21bb0..96e585713b 100644
--- a/src/cpu.c
+++ b/src/cpu.c
@@ -7,15 +7,106 @@
* Date Author Notes
* 2018-10-30 Bernard The first version
*/
-
-#include <rtthread.h>
#include <rthw.h>
+#include <rtthread.h>
#ifdef RT_USING_SMP
-
static struct rt_cpu rt_cpus[RT_CPUS_NR];
rt_hw_spinlock_t _cpus_lock;
+/*
+ * disable scheduler
+ */
+static void rt_preempt_disable(void)
+{
+ register rt_base_t level;
+ struct rt_thread *current_thread;
+
+ /* disable interrupt */
+ level = rt_hw_local_irq_disable();
+
+ current_thread = rt_thread_self();
+ if (!current_thread)
+ {
+ rt_hw_local_irq_enable(level);
+ return;
+ }
+
+ /* lock scheduler for local cpu */
+ current_thread->scheduler_lock_nest ++;
+
+ /* enable interrupt */
+ rt_hw_local_irq_enable(level);
+}
+
+/*
+ * enable scheduler
+ */
+static void rt_preempt_enable(void)
+{
+ register rt_base_t level;
+ struct rt_thread *current_thread;
+
+ /* disable interrupt */
+ level = rt_hw_local_irq_disable();
+
+ current_thread = rt_thread_self();
+ if (!current_thread)
+ {
+ rt_hw_local_irq_enable(level);
+ return;
+ }
+
+ /* unlock scheduler for local cpu */
+ current_thread->scheduler_lock_nest --;
+
+ rt_schedule();
+ /* enable interrupt */
+ rt_hw_local_irq_enable(level);
+}
+
+void rt_spin_lock_init(struct rt_spinlock *lock)
+{
+ rt_hw_spin_lock_init(&lock->lock);
+}
+RTM_EXPORT(rt_spin_lock_init)
+
+void rt_spin_lock(struct rt_spinlock *lock)
+{
+ rt_preempt_disable();
+ rt_hw_spin_lock(&lock->lock);
+}
+RTM_EXPORT(rt_spin_lock)
+
+void rt_spin_unlock(struct rt_spinlock *lock)
+{
+ rt_hw_spin_unlock(&lock->lock);
+ rt_preempt_enable();
+}
+RTM_EXPORT(rt_spin_unlock)
+
+rt_base_t rt_spin_lock_irqsave(struct rt_spinlock *lock)
+{
+ unsigned long level;
+
+ rt_preempt_disable();
+
+ level = rt_hw_local_irq_disable();
+ rt_hw_spin_lock(&lock->lock);
+
+ return level;
+}
+RTM_EXPORT(rt_spin_lock_irqsave)
+
+void rt_spin_unlock_irqrestore(struct rt_spinlock *lock, rt_base_t level)
+{
+ rt_hw_spin_unlock(&lock->lock);
+ rt_hw_local_irq_enable(level);
+
+ rt_preempt_enable();
+}
+RTM_EXPORT(rt_spin_unlock_irqrestore)
+
/**
* This fucntion will return current cpu.
*/
@@ -42,7 +133,7 @@ rt_base_t rt_cpus_lock(void)
pcpu = rt_cpu_self();
if (pcpu->current_thread != RT_NULL)
{
- register rt_uint16_t lock_nest = pcpu->current_thread->cpus_lock_nest;
+ register rt_ubase_t lock_nest = pcpu->current_thread->cpus_lock_nest;
pcpu->current_thread->cpus_lock_nest++;
if (lock_nest == 0)
diff --git a/src/idle.c b/src/idle.c
index 1108bc3367..99db64f571 100644
--- a/src/idle.c
+++ b/src/idle.c
@@ -51,11 +51,11 @@ ALIGN(RT_ALIGN_SIZE)
static rt_uint8_t rt_thread_stack[_CPUS_NR][IDLE_THREAD_STACK_SIZE];
#ifdef RT_USING_IDLE_HOOK
-#ifndef RT_IDEL_HOOK_LIST_SIZE
-#define RT_IDEL_HOOK_LIST_SIZE 4
+#ifndef RT_IDLE_HOOK_LIST_SIZE
+#define RT_IDLE_HOOK_LIST_SIZE 4
#endif
-static void (*idle_hook_list[RT_IDEL_HOOK_LIST_SIZE])(void);
+static void (*idle_hook_list[RT_IDLE_HOOK_LIST_SIZE])(void);
/**
* @ingroup Hook
@@ -78,7 +78,7 @@ rt_err_t rt_thread_idle_sethook(void (*hook)(void))
/* disable interrupt */
level = rt_hw_interrupt_disable();
- for (i = 0; i < RT_IDEL_HOOK_LIST_SIZE; i++)
+ for (i = 0; i < RT_IDLE_HOOK_LIST_SIZE; i++)
{
if (idle_hook_list[i] == RT_NULL)
{
@@ -110,7 +110,7 @@ rt_err_t rt_thread_idle_delhook(void (*hook)(void))
/* disable interrupt */
level = rt_hw_interrupt_disable();
- for (i = 0; i < RT_IDEL_HOOK_LIST_SIZE; i++)
+ for (i = 0; i < RT_IDLE_HOOK_LIST_SIZE; i++)
{
if (idle_hook_list[i] == hook)
{
@@ -246,7 +246,7 @@ static void rt_thread_idle_entry(void *parameter)
#ifdef RT_USING_IDLE_HOOK
rt_size_t i;
- for (i = 0; i < RT_IDEL_HOOK_LIST_SIZE; i++)
+ for (i = 0; i < RT_IDLE_HOOK_LIST_SIZE; i++)
{
if (idle_hook_list[i] != RT_NULL)
{
diff --git a/src/ipc.c b/src/ipc.c
index c6a05e96a4..6a8234a747 100644
--- a/src/ipc.c
+++ b/src/ipc.c
@@ -33,6 +33,7 @@
* 2011-12-18 Bernard add more parameter checking in message queue
* 2013-09-14 Grissiom add an option check in rt_event_recv
* 2018-10-02 Bernard add 64bit support for mailbox
+ * 2019-09-16 tyx add send wait support for message queue
*/
#include <rtthread.h>
@@ -1823,6 +1824,9 @@ rt_err_t rt_mq_init(rt_mq_t mq,
/* the initial entry is zero */
mq->entry = 0;
+ /* init an additional list of sender suspend thread */
+ rt_list_init(&(mq->suspend_sender_thread));
+
return RT_EOK;
}
RTM_EXPORT(rt_mq_init);
@@ -1843,6 +1847,8 @@ rt_err_t rt_mq_detach(rt_mq_t mq)
/* resume all suspended thread */
rt_ipc_list_resume_all(&mq->parent.suspend_thread);
+ /* also resume all message queue private suspended thread */
+ rt_ipc_list_resume_all(&(mq->suspend_sender_thread));
/* detach message queue object */
rt_object_detach(&(mq->parent.parent));
@@ -1894,7 +1900,7 @@ rt_mq_t rt_mq_create(const char *name,
mq->msg_pool = RT_KERNEL_MALLOC((mq->msg_size + sizeof(struct rt_mq_message)) * mq->max_msgs);
if (mq->msg_pool == RT_NULL)
{
- rt_mq_delete(mq);
+ rt_object_delete(&(mq->parent.parent));
return RT_NULL;
}
@@ -1916,6 +1922,9 @@ rt_mq_t rt_mq_create(const char *name,
/* the initial entry is zero */
mq->entry = 0;
+ /* init an additional list of sender suspend thread */
+ rt_list_init(&(mq->suspend_sender_thread));
+
return mq;
}
RTM_EXPORT(rt_mq_create);
@@ -1938,6 +1947,8 @@ rt_err_t rt_mq_delete(rt_mq_t mq)
/* resume all suspended thread */
rt_ipc_list_resume_all(&(mq->parent.suspend_thread));
+ /* also resume all message queue private suspended thread */
+ rt_ipc_list_resume_all(&(mq->suspend_sender_thread));
/* free message queue pool */
RT_KERNEL_FREE(mq->msg_pool);
@@ -1951,19 +1962,25 @@ RTM_EXPORT(rt_mq_delete);
#endif
/**
- * This function will send a message to message queue object, if there are
- * threads suspended on message queue object, it will be waked up.
+ * This function will send a message to message queue object. If the message queue is full,
+ * current thread will be suspended until timeout.
*
* @param mq the message queue object
* @param buffer the message
* @param size the size of buffer
+ * @param timeout the waiting time
*
* @return the error code
*/
-rt_err_t rt_mq_send(rt_mq_t mq, const void *buffer, rt_size_t size)
+rt_err_t rt_mq_send_wait(rt_mq_t mq,
+ const void *buffer,
+ rt_size_t size,
+ rt_int32_t timeout)
{
register rt_ubase_t temp;
struct rt_mq_message *msg;
+ rt_uint32_t tick_delta;
+ struct rt_thread *thread;
/* parameter check */
RT_ASSERT(mq != RT_NULL);
@@ -1975,6 +1992,11 @@ rt_err_t rt_mq_send(rt_mq_t mq, const void *buffer, rt_size_t size)
if (size > mq->msg_size)
return -RT_ERROR;
+ /* initialize delta tick */
+ tick_delta = 0;
+ /* get current thread */
+ thread = rt_thread_self();
+
RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(mq->parent.parent)));
/* disable interrupt */
@@ -1982,14 +2004,78 @@ rt_err_t rt_mq_send(rt_mq_t mq, const void *buffer, rt_size_t size)
/* get a free list, there must be an empty item */
msg = (struct rt_mq_message *)mq->msg_queue_free;
- /* message queue is full */
- if (msg == RT_NULL)
+ /* for non-blocking call */
+ if (msg == RT_NULL && timeout == 0)
{
/* enable interrupt */
rt_hw_interrupt_enable(temp);
return -RT_EFULL;
}
+
+ /* message queue is full */
+ while ((msg = mq->msg_queue_free) == RT_NULL)
+ {
+ /* reset error number in thread */
+ thread->error = RT_EOK;
+
+ /* no waiting, return timeout */
+ if (timeout == 0)
+ {
+ /* enable interrupt */
+ rt_hw_interrupt_enable(temp);
+
+ return -RT_EFULL;
+ }
+
+ RT_DEBUG_IN_THREAD_CONTEXT;
+ /* suspend current thread */
+ rt_ipc_list_suspend(&(mq->suspend_sender_thread),
+ thread,
+ mq->parent.parent.flag);
+
+ /* has waiting time, start thread timer */
+ if (timeout > 0)
+ {
+ /* get the start tick of timer */
+ tick_delta = rt_tick_get();
+
+ RT_DEBUG_LOG(RT_DEBUG_IPC, ("mq_send_wait: start timer of thread:%s\n",
+ thread->name));
+
+ /* 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(temp);
+
+ /* re-schedule */
+ rt_schedule();
+
+ /* resume from suspend state */
+ if (thread->error != RT_EOK)
+ {
+ /* return error */
+ return thread->error;
+ }
+
+ /* disable interrupt */
+ temp = rt_hw_interrupt_disable();
+
+ /* if it's not waiting forever and then re-calculate timeout tick */
+ if (timeout > 0)
+ {
+ tick_delta = rt_tick_get() - tick_delta;
+ timeout -= tick_delta;
+ if (timeout < 0)
+ timeout = 0;
+ }
+ }
+
/* move free list pointer */
mq->msg_queue_free = msg->next;
@@ -2037,6 +2123,22 @@ rt_err_t rt_mq_send(rt_mq_t mq, const void *buffer, rt_size_t size)
return RT_EOK;
}
+RTM_EXPORT(rt_mq_send_wait)
+
+/**
+ * This function will send a message to message queue object, if there are
+ * threads suspended on message queue object, it will be waked up.
+ *
+ * @param mq the message queue object
+ * @param buffer the message
+ * @param size the size of buffer
+ *
+ * @return the error code
+ */
+rt_err_t rt_mq_send(rt_mq_t mq, const void *buffer, rt_size_t size)
+{
+ return rt_mq_send_wait(mq, buffer, size, 0);
+}
RTM_EXPORT(rt_mq_send);
/**
@@ -2257,6 +2359,22 @@ rt_err_t rt_mq_recv(rt_mq_t mq,
/* put message to free list */
msg->next = (struct rt_mq_message *)mq->msg_queue_free;
mq->msg_queue_free = msg;
+
+ /* resume suspended thread */
+ if (!rt_list_isempty(&(mq->suspend_sender_thread)))
+ {
+ rt_ipc_list_resume(&(mq->suspend_sender_thread));
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(temp);
+
+ RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(mq->parent.parent)));
+
+ rt_schedule();
+
+ return RT_EOK;
+ }
+
/* enable interrupt */
rt_hw_interrupt_enable(temp);
@@ -2292,6 +2410,8 @@ rt_err_t rt_mq_control(rt_mq_t mq, int cmd, void *arg)
/* resume all waiting thread */
rt_ipc_list_resume_all(&mq->parent.suspend_thread);
+ /* also resume all message queue private suspended thread */
+ rt_ipc_list_resume_all(&(mq->suspend_sender_thread));
/* release all message in the queue */
while (mq->msg_queue_head != RT_NULL)
diff --git a/src/mempool.c b/src/mempool.c
index 6b1fc81231..00471efb35 100644
--- a/src/mempool.c
+++ b/src/mempool.c
@@ -106,7 +106,6 @@ rt_err_t rt_mp_init(struct rt_mempool *mp,
/* initialize suspended thread list */
rt_list_init(&(mp->suspend_thread));
- mp->suspend_thread_count = 0;
/* initialize free block list */
block_ptr = (rt_uint8_t *)mp->start_address;
@@ -160,9 +159,6 @@ rt_err_t rt_mp_detach(struct rt_mempool *mp)
*/
rt_thread_resume(thread);
- /* decrease suspended thread count */
- mp->suspend_thread_count --;
-
/* enable interrupt */
rt_hw_interrupt_enable(temp);
}
@@ -226,7 +222,6 @@ rt_mp_t rt_mp_create(const char *name,
/* initialize suspended thread list */
rt_list_init(&(mp->suspend_thread));
- mp->suspend_thread_count = 0;
/* initialize free block list */
block_ptr = (rt_uint8_t *)mp->start_address;
@@ -282,9 +277,6 @@ rt_err_t rt_mp_delete(rt_mp_t mp)
*/
rt_thread_resume(thread);
- /* decrease suspended thread count */
- mp->suspend_thread_count --;
-
/* enable interrupt */
rt_hw_interrupt_enable(temp);
}
@@ -344,7 +336,6 @@ void *rt_mp_alloc(rt_mp_t mp, rt_int32_t time)
/* need suspend thread */
rt_thread_suspend(thread);
rt_list_insert_after(&(mp->suspend_thread), &(thread->tlist));
- mp->suspend_thread_count++;
if (time > 0)
{
@@ -431,7 +422,7 @@ void rt_mp_free(void *block)
*block_ptr = mp->block_list;
mp->block_list = (rt_uint8_t *)block_ptr;
- if (mp->suspend_thread_count > 0)
+ if (!rt_list_isempty(&(mp->suspend_thread)))
{
/* get the suspended thread */
thread = rt_list_entry(mp->suspend_thread.next,
@@ -444,9 +435,6 @@ void rt_mp_free(void *block)
/* resume thread */
rt_thread_resume(thread);
- /* decrease suspended thread count */
- mp->suspend_thread_count --;
-
/* enable interrupt */
rt_hw_interrupt_enable(level);
diff --git a/src/scheduler.c b/src/scheduler.c
index b487bd4b60..6baaa9627a 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -83,7 +83,7 @@ static void _rt_scheduler_stack_check(struct rt_thread *thread)
RT_ASSERT(thread != RT_NULL);
#if defined(ARCH_CPU_STACK_GROWS_UPWARD)
- if (*((rt_uint8_t *)((rt_ubase_t)thread->stack_addr + thread->stack_size - 1)) != '#' ||
+ if (*((rt_uint8_t *)((rt_ubase_t)thread->stack_addr + thread->stack_size - 1)) != '#' ||
#else
if (*((rt_uint8_t *)thread->stack_addr) != '#' ||
#endif
@@ -344,8 +344,13 @@ void rt_schedule(void)
{
to_thread = current_thread;
}
+ else if (current_thread->current_priority == highest_ready_priority && (current_thread->stat & RT_THREAD_STAT_YIELD_MASK) == 0)
+ {
+ to_thread = current_thread;
+ }
else
{
+ current_thread->stat &= ~RT_THREAD_STAT_YIELD_MASK;
rt_schedule_insert_thread(current_thread);
}
}
@@ -379,7 +384,12 @@ void rt_schedule(void)
}
}
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+
#ifdef RT_USING_SIGNALS
+ /* check stat of thread for signal */
+ level = rt_hw_interrupt_disable();
if (current_thread->stat & RT_THREAD_STAT_SIGNAL_PENDING)
{
extern void rt_thread_handle_sig(rt_bool_t clean_state);
@@ -395,9 +405,6 @@ void rt_schedule(void)
{
rt_hw_interrupt_enable(level);
}
-#else
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
#endif
__exit:
@@ -435,8 +442,13 @@ void rt_schedule(void)
{
to_thread = rt_current_thread;
}
+ else if (rt_current_thread->current_priority == highest_ready_priority && (rt_current_thread->stat & RT_THREAD_STAT_YIELD_MASK) == 0)
+ {
+ to_thread = rt_current_thread;
+ }
else
{
+ rt_current_thread->stat &= ~RT_THREAD_STAT_YIELD_MASK;
need_insert_from_thread = 1;
}
}
@@ -477,7 +489,13 @@ void rt_schedule(void)
rt_hw_context_switch((rt_ubase_t)&from_thread->sp,
(rt_ubase_t)&to_thread->sp);
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
+
#ifdef RT_USING_SIGNALS
+ /* check stat of thread for signal */
+ level = rt_hw_interrupt_disable();
if (rt_current_thread->stat & RT_THREAD_STAT_SIGNAL_PENDING)
{
extern void rt_thread_handle_sig(rt_bool_t clean_state);
@@ -493,9 +511,6 @@ void rt_schedule(void)
{
rt_hw_interrupt_enable(level);
}
-#else
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
#endif
goto __exit;
}
@@ -578,8 +593,13 @@ void rt_scheduler_do_irq_switch(void *context)
{
to_thread = current_thread;
}
+ else if (current_thread->current_priority == highest_ready_priority && (current_thread->stat & RT_THREAD_STAT_YIELD_MASK) == 0)
+ {
+ to_thread = current_thread;
+ }
else
{
+ current_thread->stat &= ~RT_THREAD_STAT_YIELD_MASK;
rt_schedule_insert_thread(current_thread);
}
}
@@ -840,11 +860,14 @@ void rt_enter_critical(void)
*/
/* lock scheduler for all cpus */
- if (current_thread->scheduler_lock_nest == !!current_thread->cpus_lock_nest)
+ if (current_thread->critical_lock_nest == 0)
{
rt_hw_spin_lock(&_rt_critical_lock);
}
+ /* critical for local cpu */
+ current_thread->critical_lock_nest ++;
+
/* lock scheduler for local cpu */
current_thread->scheduler_lock_nest ++;
@@ -892,7 +915,9 @@ void rt_exit_critical(void)
current_thread->scheduler_lock_nest --;
- if (current_thread->scheduler_lock_nest == !!current_thread->cpus_lock_nest)
+ current_thread->critical_lock_nest --;
+
+ if (current_thread->critical_lock_nest == 0)
{
rt_hw_spin_unlock(&_rt_critical_lock);
}
@@ -951,9 +976,9 @@ rt_uint16_t rt_critical_level(void)
#ifdef RT_USING_SMP
struct rt_thread *current_thread = rt_cpu_self()->current_thread;
- return current_thread->scheduler_lock_nest;
+ return current_thread->critical_lock_nest;
#else
- return rt_scheduler_lock_nest;
+ return rt_scheduler_lock_nest;
#endif /*RT_USING_SMP*/
}
RTM_EXPORT(rt_critical_level);
diff --git a/src/thread.c b/src/thread.c
index ab203b1d49..c5f75a1176 100644
--- a/src/thread.c
+++ b/src/thread.c
@@ -107,11 +107,11 @@ void rt_thread_exit(void)
rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));
}
- /* enable interrupt */
- rt_hw_interrupt_enable(level);
-
/* switch to next task */
rt_schedule();
+
+ /* enable interrupt */
+ rt_hw_interrupt_enable(level);
}
static rt_err_t _rt_thread_init(struct rt_thread *thread,
@@ -172,6 +172,7 @@ static rt_err_t _rt_thread_init(struct rt_thread *thread,
/* lock init */
thread->scheduler_lock_nest = 0;
thread->cpus_lock_nest = 0;
+ thread->critical_lock_nest = 0;
#endif /*RT_USING_SMP*/
/* initialize cleanup function and user data */
@@ -445,12 +446,12 @@ rt_err_t rt_thread_delete(rt_thread_t thread)
/* release thread timer */
rt_timer_detach(&(thread->thread_timer));
- /* change stat */
- thread->stat = RT_THREAD_CLOSE;
-
/* disable interrupt */
lock = rt_hw_interrupt_disable();
+ /* change stat */
+ thread->stat = RT_THREAD_CLOSE;
+
/* insert to defunct thread list */
rt_list_insert_after(&rt_thread_defunct, &(thread->tlist));