diff options
| author | shaojinchun <[email protected]> | 2018-11-22 14:40:43 +0800 |
|---|---|---|
| committer | shaojinchun <[email protected]> | 2018-11-22 18:16:47 +0800 |
| commit | fc6bc1ad398d5fa2085320cab6cc33905f5f943d (patch) | |
| tree | a6a24a6e516add6fe47fa5a58f7307ee0cd3f6e8 /include | |
| parent | 8ea5b770117cacea7f17b2b08305f360ed71bca7 (diff) | |
Add smp support to RT-Thread 4.0
Diffstat (limited to 'include')
| -rw-r--r-- | include/rtdef.h | 56 | ||||
| -rw-r--r-- | include/rthw.h | 58 | ||||
| -rw-r--r-- | include/rtthread.h | 19 |
3 files changed, 128 insertions, 5 deletions
diff --git a/include/rtdef.h b/include/rtdef.h index fef08599c7..253ec36968 100644 --- a/include/rtdef.h +++ b/include/rtdef.h @@ -26,6 +26,9 @@ * 2018-09-14 Bernard apply Apache License v2.0 to RT-Thread Kernel * 2018-10-13 Bernard change version number to v4.0.0 * 2018-10-02 Bernard add 64bit arch support + * 2018-11-22 Jesven add smp member to struct rt_thread + * add struct rt_cpu + * add smp relevant macros */ #ifndef __RT_DEF_H__ @@ -130,11 +133,11 @@ typedef rt_base_t rt_off_t; /**< Type for offset */ #include <stdarg.h> #else /* the version of GNU GCC must be greater than 4.x */ - typedef __builtin_va_list __gnuc_va_list; - typedef __gnuc_va_list va_list; - #define va_start(v,l) __builtin_va_start(v,l) - #define va_end(v) __builtin_va_end(v) - #define va_arg(v,l) __builtin_va_arg(v,l) + typedef __builtin_va_list __gnuc_va_list; + typedef __gnuc_va_list va_list; + #define va_start(v,l) __builtin_va_start(v,l) + #define va_end(v) __builtin_va_end(v) + #define va_arg(v,l) __builtin_va_arg(v,l) #endif #define SECTION(x) __attribute__((section(x))) @@ -497,6 +500,41 @@ typedef siginfo_t rt_siginfo_t; #define RT_THREAD_CTRL_CLOSE 0x01 /**< Close thread. */ #define RT_THREAD_CTRL_CHANGE_PRIORITY 0x02 /**< Change thread priority. */ #define RT_THREAD_CTRL_INFO 0x03 /**< Get thread information. */ +#define RT_THREAD_CTRL_BIND_CPU 0x03 /**< Set thread bind cpu. */ + +#ifdef RT_USING_SMP + +#define RT_CPU_DETACHED RT_CPUS_NR /**< The thread not running on cpu. */ +#define RT_CPU_MASK ((1 << RT_CPUS_NR) - 1) /**< All CPUs mask bit. */ + +#ifndef RT_SCHEDULE_IPI_IRQ +#define RT_SCHEDULE_IPI_IRQ 0 +#endif + +/** + * CPUs definitions + * + */ +struct rt_cpu +{ + struct rt_thread *current_thread; + + rt_uint16_t irq_nest; + rt_uint8_t irq_switch_flag; + + rt_uint8_t current_priority; + rt_list_t priority_table[RT_THREAD_PRIORITY_MAX]; +#if RT_THREAD_PRIORITY_MAX > 32 + rt_uint32_t priority_group; + rt_uint8_t ready_table[32]; +#else + rt_uint32_t priority_group; +#endif + + rt_tick_t tick; +}; + +#endif /** * Thread structure @@ -527,6 +565,14 @@ struct rt_thread rt_uint8_t stat; /**< thread status */ +#ifdef RT_USING_SMP + rt_uint8_t bind_cpu; /**< thread is bind to cpu */ + rt_uint8_t oncpu; /**< process on cpu` */ + + rt_uint16_t scheduler_lock_nest; /**< scheduler lock count */ + rt_uint16_t cpus_lock_nest; /**< cpus lock count */ +#endif /*RT_USING_SMP*/ + /* priority */ rt_uint8_t current_priority; /**< current priority */ rt_uint8_t init_priority; /**< initialized priority */ diff --git a/include/rthw.h b/include/rthw.h index 17151de99a..3fa0ba301c 100644 --- a/include/rthw.h +++ b/include/rthw.h @@ -10,6 +10,8 @@ * 2006-09-24 Bernard add rt_hw_context_switch_to declaration * 2012-12-29 Bernard add rt_hw_exception_install declaration * 2017-10-17 Hichard add some micros + * 2018-11-17 Jesven add rt_hw_spinlock_t + * add smp support */ #ifndef __RT_HW_H__ @@ -92,15 +94,30 @@ rt_isr_handler_t rt_hw_interrupt_install(int vector, void *param, char *name); +#ifdef RT_USING_SMP +rt_base_t rt_hw_local_irq_disable(); +void rt_hw_local_irq_enable(rt_base_t level); + +#define rt_hw_interrupt_disable rt_cpus_lock +#define rt_hw_interrupt_enable rt_cpus_unlock + +#else rt_base_t rt_hw_interrupt_disable(void); void rt_hw_interrupt_enable(rt_base_t level); +#endif /*RT_USING_SMP*/ /* * Context interfaces */ +#ifdef RT_USING_SMP +void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread); +void rt_hw_context_switch_to(rt_ubase_t to, struct rt_thread *to_thread); +void rt_hw_context_switch_interrupt(void *context, rt_ubase_t from, rt_ubase_t to, struct rt_thread *to_thread); +#else void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to); void rt_hw_context_switch_to(rt_ubase_t to); void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to); +#endif /*RT_USING_SMP*/ void rt_hw_console_output(const char *str); @@ -117,6 +134,47 @@ void rt_hw_exception_install(rt_err_t (*exception_handle)(void *context)); */ void rt_hw_us_delay(rt_uint32_t us); +#ifdef RT_USING_SMP +typedef union { + unsigned long slock; + struct __arch_tickets { + unsigned short owner; + unsigned short next; + } tickets; +} rt_hw_spinlock_t; + +void rt_hw_spin_lock(rt_hw_spinlock_t *lock); +void rt_hw_spin_unlock(rt_hw_spinlock_t *lock); + +int rt_hw_cpu_id(void); + +extern rt_hw_spinlock_t _cpus_lock; +extern rt_hw_spinlock_t _rt_critical_lock; + +#define __RT_HW_SPIN_LOCK_INITIALIZER(lockname) {0} + +#define __RT_HW_SPIN_LOCK_UNLOCKED(lockname) \ + (struct rt_hw_spinlock ) __RT_HW_SPIN_LOCK_INITIALIZER(lockname) + +#define RT_DEFINE_SPINLOCK(x) struct rt_hw_spinlock x = __RT_HW_SPIN_LOCK_UNLOCKED(x) + +/** + * ipi function + */ +void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask); + +/** + * boot secondary cpu + */ +void rt_hw_secondary_cpu_up(void); + +/** + * secondary cpu idle function + */ +void rt_hw_secondary_cpu_idle_exec(void); + +#endif + #ifdef __cplusplus } #endif diff --git a/include/rtthread.h b/include/rtthread.h index 3fc77d343c..d2356b8eda 100644 --- a/include/rtthread.h +++ b/include/rtthread.h @@ -13,6 +13,7 @@ * 2010-04-11 yi.qiu add module feature * 2013-06-24 Bernard add rt_kprintf re-define when not use RT_USING_CONSOLE. * 2016-08-09 ArdaFu add new thread and interrupt hook. + * 2018-11-22 Jesven add all cpu's lock and ipi handler */ #ifndef __RT_THREAD_H__ @@ -184,6 +185,10 @@ rt_uint16_t rt_critical_level(void); void rt_scheduler_sethook(void (*hook)(rt_thread_t from, rt_thread_t to)); #endif +#ifdef RT_USING_SMP +void rt_scheduler_ipi_handler(int vector, void *param); +#endif + /**@}*/ /** @@ -439,6 +444,20 @@ rt_err_t rt_device_control(rt_device_t dev, int cmd, void *arg); void rt_interrupt_enter(void); void rt_interrupt_leave(void); +#ifdef RT_USING_SMP + +/* + * smp cpus lock service + */ + +rt_base_t rt_cpus_lock(void); +void rt_cpus_unlock(rt_base_t level); + +struct rt_cpu *rt_cpu_self(void); +struct rt_cpu *rt_cpu_index(int index); + +#endif + /* * the number of nested interrupts. */ |
