diff --git a/TODO b/TODO index 62d2e562ce7..703cfad205c 100644 --- a/TODO +++ b/TODO @@ -216,7 +216,7 @@ o Task/Scheduler (sched/) Status: Open Priority: Medium-ish - Title: ISSUES WITH PRIORITY INHERITANCE WHEN SEMAPHORE USED AS IPC + Title: ISSUES WITH PRIORITY INHERITANCE WHEN SEMAPHORE/MUTX IS USED AS IPC Description: Semaphores have multiple uses. The typical usage is where the semaphore is used as lock on one or more resources. In this typical case, priority inheritance works perfectly: The @@ -264,11 +264,25 @@ o Task/Scheduler (sched/) The fix is to call sem_setprotocol(SEM_PRIO_NONE) immediately after the sem_init() call so that there will be no priority inheritance operations on this semaphore used for signalling. - Status: Open - Priority: High. If you have priority inheritance enabled and you use + + NOTE also that in NuttX, pthread mutexes are build on top of + binary semaphores. As a result, the above recommendation also + applies when pthread mutexes are used for inter-thread + signaling. That is, a mutex that is used for signaling should + be initialize like this (simplified, no error checking here): + + pthread_mutexattr_t attr; + pthread_mutex_t mutex; + + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_PRIO_NONE); + pthread_mutex_init(&mutex, &attr); + + Status: Closed. If you have priority inheritance enabled and you use semaphores for signalling events, then you *must* call sem_setprotocol(SEM_PRIO_NONE) immediately after initializing the semaphore. + Priority: High. Title: SCALABILITY Description: Task control information is retained in simple lists. This @@ -452,7 +466,7 @@ o pthreads (sched/pthreads) Priority: Low, probably not that useful Title: PTHREAD_PRIO_PROTECT - Description: Extended pthread_mutexattr_setprotocol() support PTHREAD_PRIO_PROTECT: + Description: Extend pthread_mutexattr_setprotocol() support PTHREAD_PRIO_PROTECT: "When a thread owns one or more mutexes initialized with the PTHREAD_PRIO_PROTECT protocol, it shall execute at the higher of its priority or the highest of the priority ceilings of all the mutexes diff --git a/arch/arm/src/armv7-r/Kconfig b/arch/arm/src/armv7-r/Kconfig index 810e80601d6..1f46770cb6a 100644 --- a/arch/arm/src/armv7-r/Kconfig +++ b/arch/arm/src/armv7-r/Kconfig @@ -3,7 +3,7 @@ # see the file kconfig-language.txt in the NuttX tools repository. # -comment "ARMv7-A Configuration Options" +comment "ARMv7-R Configuration Options" config ARMV7R_MEMINIT bool @@ -19,6 +19,29 @@ config ARMV7R_MEMINIT the memory initialization first, then explicitly call arm_data_initialize(). +config ARMV7R_HAVE_ICACHE + bool + default n + +config ARMV7R_HAVE_DCACHE + bool + default n + +config ARMV7R_ICACHE + bool "Use I-Cache" + default n + depends on ARMV7R_HAVE_ICACHE + +config ARMV7R_DCACHE + bool "Use D-Cache" + default n + depends on ARMV7R_HAVE_DCACHE + +config ARMV7R_DCACHE_WRITETHROUGH + bool "D-Cache Write-Through" + default n + depends on ARMV7R_DCACHE + config ARMV7R_HAVE_L2CC bool default n diff --git a/arch/arm/src/armv7-r/arm_fullcontextrestore.S b/arch/arm/src/armv7-r/arm_fullcontextrestore.S index 9f197063b27..06daa221826 100644 --- a/arch/arm/src/armv7-r/arm_fullcontextrestore.S +++ b/arch/arm/src/armv7-r/arm_fullcontextrestore.S @@ -60,7 +60,6 @@ .cpu cortex-r4f #endif .syntax unified - .file "arm_fullcontextrestore.S" /**************************************************************************** * Public Functions @@ -157,20 +156,11 @@ up_fullcontextrestore: */ ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the stored CPSR value */ - msr cpsr, r1 /* Set the CPSR */ + msr spsr_cxsf, r1 /* Set the SPSR */ - /* Now recover r0 and r1 */ - - ldr r0, [sp] - ldr r1, [sp, #4] - add sp, sp, #(2*4) - - /* Then return to the address at the stop of the stack, - * destroying the stack frame - */ - - ldr pc, [sp], #4 + /* Now recover r0-r1, pc and cpsr, destroying the stack frame */ + ldmia sp!, {r0-r1, pc}^ #endif .size up_fullcontextrestore, . - up_fullcontextrestore diff --git a/arch/arm/src/armv7-r/arm_vectors.S b/arch/arm/src/armv7-r/arm_vectors.S index 216633e3a36..bea7c927bce 100644 --- a/arch/arm/src/armv7-r/arm_vectors.S +++ b/arch/arm/src/armv7-r/arm_vectors.S @@ -202,7 +202,7 @@ arm_vectorirq: /* Restore the CPSR, SVC mode registers and return */ ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ - msr spsr, r1 /* Set the return mode SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ #ifdef CONFIG_BUILD_PROTECTED /* Are we leaving in user mode? If so then we need to restore the @@ -331,7 +331,7 @@ arm_vectorsvc: /* Restore the CPSR, SVC mode registers and return */ ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ - msr spsr, r1 /* Set the return mode SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ #ifdef CONFIG_BUILD_PROTECTED /* Are we leaving in user mode? If so then we need to restore the @@ -913,7 +913,7 @@ arm_vectorfiq: /* Restore the CPSR, SVC mode registers and return */ ldr r1, [r0, #(4*REG_CPSR)] /* Fetch the return SPSR */ - msr spsr, r1 /* Set the return mode SPSR */ + msr spsr_cxsf, r1 /* Set the return mode SPSR */ #ifdef CONFIG_BUILD_PROTECTED /* Are we leaving in user mode? If so then we need to restore the diff --git a/arch/arm/src/armv7-r/cache.h b/arch/arm/src/armv7-r/cache.h index 2c60fe2c3d6..a0d25c89410 100644 --- a/arch/arm/src/armv7-r/cache.h +++ b/arch/arm/src/armv7-r/cache.h @@ -43,6 +43,7 @@ #include #include +#include "sctlr.h" #include "cp15_cacheops.h" #include "l2cc.h" @@ -50,6 +51,16 @@ * Pre-processor Definitions ************************************************************************************/ +/* intrinsics are used in these inline functions */ + +#define arm_isb(n) __asm__ __volatile__ ("isb " #n : : : "memory") +#define arm_dsb(n) __asm__ __volatile__ ("dsb " #n : : : "memory") +#define arm_dmb(n) __asm__ __volatile__ ("dmb " #n : : : "memory") + +#define ARM_DSB() arm_dsb(15) +#define ARM_ISB() arm_isb(15) +#define ARM_DMB() arm_dmb(15) + /************************************************************************************ * Inline Functions ************************************************************************************/ @@ -183,6 +194,70 @@ static inline void arch_flush_dcache(uintptr_t start, uintptr_t end) l2cc_flush(start, end); } +/**************************************************************************** + * Name: arch_enable_icache + * + * Description: + * Enable the I-Cache + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static inline void arch_enable_icache(void) +{ +#ifdef CONFIG_ARMV7R_ICACHE + uint32_t regval; + + ARM_DSB(); + ARM_ISB(); + + /* Enable the I-Cache */ + + regval = cp15_rdsctlr(); + if ((regval & SCTLR_I) == 0) + { + cp15_wrsctlr(regval | SCTLR_I); + } + + ARM_DSB(); + ARM_ISB(); +#endif +} + +/**************************************************************************** +* Name: arch_enable_dcache +* +* Description: +* Enable the D-Cache +* +* Input Parameters: +* None +* +* Returned Value: +* None +* +****************************************************************************/ + +static inline void arch_enable_dcache(void) +{ +#ifdef CONFIG_ARMV7R_DCACHE + uint32_t regval; + + /* Enable the D-Cache */ + + regval = cp15_rdsctlr(); + if ((regval & SCTLR_C) == 0) + { + cp15_wrsctlr(regval | SCTLR_C); + } +#endif +} + /**************************************************************************** * Public Data ****************************************************************************/ diff --git a/arch/arm/src/armv7-r/mpu.h b/arch/arm/src/armv7-r/mpu.h index e9e29cf13f8..7c1a201567d 100644 --- a/arch/arm/src/armv7-r/mpu.h +++ b/arch/arm/src/armv7-r/mpu.h @@ -49,6 +49,8 @@ # include # include "up_arch.h" +# include "cache.h" +# include "sctlr.h" # include "cp15.h" #endif @@ -66,7 +68,7 @@ /* Region Base Address Register Definitions */ -#define MPU_RBAR_MASK 0xfffffffc +#define MPU_RBAR_ADDR_MASK 0xfffffffc /* Region Size and Enable Register */ @@ -201,7 +203,7 @@ static inline unsigned int mpu_get_mpuir(void) unsigned int mpuir; __asm__ __volatile__ ( - "\tmrc " CP15_MPUIR(%0) + "\tmrc p15, 0, %0, c0, c0, 4" : "=r" (mpuir) : : "memory" @@ -222,7 +224,7 @@ static inline void mpu_set_drbar(unsigned int drbar) { __asm__ __volatile__ ( - "\tmcr " CP15_DRBAR(%0) + "\tmcr p15, 0, %0, c6, c1, 0" : : "r" (drbar) : "memory" @@ -241,7 +243,7 @@ static inline void mpu_set_drsr(unsigned int drsr) { __asm__ __volatile__ ( - "\tmcr " CP15_DRSR(%0) + "\tmcr p15, 0, %0, c6, c1, 2" : : "r" (drsr) : "memory" @@ -260,7 +262,7 @@ static inline void mpu_set_dracr(unsigned int dracr) { __asm__ __volatile__ ( - "\tmcr " CP15_DRACR(%0) + "\tmcr p15, 0, %0, c6, c1, 4" : : "r" (dracr) : "memory" @@ -280,7 +282,7 @@ static inline void mpu_set_irbar(unsigned int irbar) { __asm__ __volatile__ ( - "\tmcr " CP15_IRBAR(%0) + "\tmcr p15, 0, %0, c6, c1, 1" : : "r" (irbar) : "memory" @@ -301,7 +303,7 @@ static inline void mpu_set_irsr(unsigned int irsr) { __asm__ __volatile__ ( - "\tmcr " CP15_IRSR(%0) + "\tmcr p15, 0, %0, c6, c1, 3" : : "r" (irsr) : "memory" @@ -322,7 +324,7 @@ static inline void mpu_set_iracr(unsigned int iracr) { __asm__ __volatile__ ( - "\tmcr " CP15_IRACR(%0) + "\tmcr p15, 0, %0, c6, c1, 5" : : "r" (iracr) : "memory" @@ -342,7 +344,7 @@ static inline void mpu_set_rgnr(unsigned int rgnr) { __asm__ __volatile__ ( - "\tmcr " CP15_RGNR(%0) + "\tmcr p15, 0, %0, c6, c2, 0" : : "r" (rgnr) : "memory" @@ -390,7 +392,6 @@ static inline void mpu_control(bool enable) if (enable) { regval |= (SCTLR_M | SCTLR_BR); - cp15_wrsctlr(regval); } else { @@ -408,7 +409,7 @@ static inline void mpu_control(bool enable) * ****************************************************************************/ -#if defined(CONFIG_ARMV7M_HAVE_ICACHE) || defined(CONFIG_ARMV7M_DCACHE) +#if defined(CONFIG_ARMV7R_HAVE_ICACHE) || defined(CONFIG_ARMV7R_DCACHE) static inline void mpu_priv_stronglyordered(uintptr_t base, size_t size) { unsigned int region = mpu_allocregion(); @@ -422,7 +423,7 @@ static inline void mpu_priv_stronglyordered(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar(base & MPU_RBAR_ADDR_MASK) | region | MPU_RBAR_VALID); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -465,7 +466,7 @@ static inline void mpu_user_flash(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -506,7 +507,7 @@ static inline void mpu_priv_flash(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -546,7 +547,7 @@ static inline void mpu_user_intsram(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -587,7 +588,7 @@ static inline void mpu_priv_intsram(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -628,7 +629,7 @@ static inline void mpu_user_extsram(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -670,7 +671,7 @@ static inline void mpu_priv_extsram(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ @@ -712,7 +713,7 @@ static inline void mpu_peripheral(uintptr_t base, size_t size) /* Select the region base address */ - mpu_set_drbar((base & MPU_RBAR_ADDR_MASK) | region); + mpu_set_drbar(base & MPU_RBAR_ADDR_MASK); /* Select the region size and the sub-region map */ diff --git a/arch/arm/src/kl/kl_spi.h b/arch/arm/src/kl/kl_spi.h index 466ab832f8e..227ab9e6c5d 100644 --- a/arch/arm/src/kl/kl_spi.h +++ b/arch/arm/src/kl/kl_spi.h @@ -126,6 +126,11 @@ int kl_spi1cmddata(FAR struct spi_dev_s *dev, enum spi_dev_e devid, bool cmd); #endif #endif +#if defined(__cplusplus) +} +#endif +#undef EXTERN + #endif /* __ASSEMBLY__ */ #endif /* CONFIG_KL_SPI0 || CONFIG_KL_SPI1 */ #endif /* __ARCH_ARM_SRC_KL_KL_SPI_H */ diff --git a/arch/arm/src/lpc43xx/chip/lpc43_ethernet.h b/arch/arm/src/lpc43xx/chip/lpc43_ethernet.h index 6da125a6fee..d03ed7123b0 100644 --- a/arch/arm/src/lpc43xx/chip/lpc43_ethernet.h +++ b/arch/arm/src/lpc43xx/chip/lpc43_ethernet.h @@ -653,15 +653,5 @@ struct eth_rxdesc_s * Public Functions ****************************************************************************************************/ -#undef EXTERN -#if defined(__cplusplus) -#define EXTERN extern "C" -extern "C" -{ -#else -#define EXTERN extern -#endif - #endif /* __ASSEMBLY__ */ #endif /* __ARCH_ARM_SRC_LPC43XX_CHIP_LPC43_ETHERNET_H */ - diff --git a/arch/arm/src/lpc43xx/lpc43_ethernet.h b/arch/arm/src/lpc43xx/lpc43_ethernet.h index 55888fc7270..7d60a43697b 100644 --- a/arch/arm/src/lpc43xx/lpc43_ethernet.h +++ b/arch/arm/src/lpc43xx/lpc43_ethernet.h @@ -55,7 +55,8 @@ #undef EXTERN #if defined(__cplusplus) #define EXTERN extern "C" -extern "C" { +extern "C" +{ #else #define EXTERN extern #endif diff --git a/arch/mips/src/pic32mz/pic32mz-dma.h b/arch/mips/src/pic32mz/pic32mz-dma.h index 99cc6c47c53..3bea2172eee 100644 --- a/arch/mips/src/pic32mz/pic32mz-dma.h +++ b/arch/mips/src/pic32mz/pic32mz-dma.h @@ -224,5 +224,10 @@ void pic32mx_dmadump(DMA_HANDLE handle, const struct pic32mx_dmaregs_s *regs, #endif #endif +#if defined(__cplusplus) +} +#endif +#undef EXTERN + #endif /* __ASSEMBLY__ */ #endif /* __ARCH_MIPS_SRC_PIC32MZ_PIC32MZ_DMA_H */ diff --git a/arch/risc-v/src/common/up_internal.h b/arch/risc-v/src/common/up_internal.h index f4481a2269a..f18d9371508 100644 --- a/arch/risc-v/src/common/up_internal.h +++ b/arch/risc-v/src/common/up_internal.h @@ -104,13 +104,17 @@ * Public Variables ****************************************************************************/ -extern volatile uint32_t *g_current_regs; +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif -extern uint32_t g_idle_topstack; - -/**************************************************************************** - * Inline Functions - ****************************************************************************/ +EXTERN volatile uint32_t *g_current_regs; +EXTERN uint32_t g_idle_topstack; /**************************************************************************** * Public Functions diff --git a/arch/sim/src/up_uartwait.c b/arch/sim/src/up_uartwait.c index 50f6b5f2811..681e87dcdd3 100644 --- a/arch/sim/src/up_uartwait.c +++ b/arch/sim/src/up_uartwait.c @@ -39,7 +39,7 @@ #include -#include +#include #include "up_internal.h" diff --git a/arch/xtensa/src/esp32/esp32_gpio.h b/arch/xtensa/src/esp32/esp32_gpio.h index ea09df24394..e4b647b9764 100644 --- a/arch/xtensa/src/esp32/esp32_gpio.h +++ b/arch/xtensa/src/esp32/esp32_gpio.h @@ -199,13 +199,6 @@ void esp32_gpioirqdisable(int irq); # define esp32_gpioirqdisable(irq) #endif -#undef EXTERN -#if defined(__cplusplus) -} -#endif - -#endif /* __ASSEMBLY__ */ - int digitalRead(uint8_t pin); void attachInterrupt(uint8_t pin, void (*)(void), int mode); @@ -214,5 +207,7 @@ void detachInterrupt(uint8_t pin); #ifdef __cplusplus } #endif +#undef EXTERN +#endif /* __ASSEMBLY__ */ #endif /* __ARCH_XTENSA_SRC_ESP32_ESP32_GPIO_H */ diff --git a/configs/fire-stm32v2/include/board.h b/configs/fire-stm32v2/include/board.h index 0f9e7c11aaf..4319e397a9e 100644 --- a/configs/fire-stm32v2/include/board.h +++ b/configs/fire-stm32v2/include/board.h @@ -371,7 +371,8 @@ #undef EXTERN #if defined(__cplusplus) #define EXTERN extern "C" -extern "C" { +extern "C" +{ #else #define EXTERN extern #endif @@ -406,5 +407,10 @@ void stm32_boardinitialize(void); void fire_lcdclear(uint16_t color); #endif +#if defined(__cplusplus) +} +#endif +#undef EXTERN + #endif /* __ASSEMBLY__ */ #endif /* __CONFIGS_FIRE_STM32V2_INCLUDE_BOARD_H */ diff --git a/drivers/usbhost/usbhost_composite.h b/drivers/usbhost/usbhost_composite.h index 4d1e35d0d1d..765624da2a5 100644 --- a/drivers/usbhost/usbhost_composite.h +++ b/drivers/usbhost/usbhost_composite.h @@ -51,6 +51,15 @@ * Public Function Prototypes ****************************************************************************/ +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + /**************************************************************************** * Name: usbhost_composite * diff --git a/fs/aio/aio.h b/fs/aio/aio.h index f74269a19a1..73ff7faa79f 100644 --- a/fs/aio/aio.h +++ b/fs/aio/aio.h @@ -277,5 +277,10 @@ int aio_queue(FAR struct aio_container_s *aioc, worker_t worker); int aio_signal(pid_t pid, FAR struct aiocb *aiocbp); +#undef EXTERN +#if defined(__cplusplus) +} +#endif + #endif /* CONFIG_FS_AIO */ #endif /* __FS_AIO_AIO_H */ diff --git a/include/nuttx/arch.h b/include/nuttx/arch.h index 1ef8efe4b18..8b83308fc80 100644 --- a/include/nuttx/arch.h +++ b/include/nuttx/arch.h @@ -2294,9 +2294,8 @@ void arch_sporadic_resume(FAR struct tcb_s *tcb); #endif #undef EXTERN -#ifdef __cplusplus +#if defined(__cplusplus) } #endif #endif /* __INCLUDE_NUTTX_ARCH_H */ - diff --git a/include/nuttx/binfmt/symtab.h b/include/nuttx/binfmt/symtab.h index 9e51ca35398..affb7cda17b 100644 --- a/include/nuttx/binfmt/symtab.h +++ b/include/nuttx/binfmt/symtab.h @@ -90,4 +90,9 @@ void exec_getsymtab(FAR const struct symtab_s **symtab, FAR int *nsymbols); void exec_setsymtab(FAR const struct symtab_s *symtab, int nsymbols); +#undef EXTERN +#if defined(__cplusplus) +} +#endif + #endif /* __INCLUDE_NUTTX_BINFMT_SYMTAB_H */ diff --git a/include/pthread.h b/include/pthread.h index 1c368d737b7..ac495e44c29 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -96,12 +96,10 @@ * An implementation is allowed to map this mutex to one of the other mutex types. */ -#ifdef CONFIG_MUTEX_TYPES -# define PTHREAD_MUTEX_NORMAL 0 -# define PTHREAD_MUTEX_ERRORCHECK 1 -# define PTHREAD_MUTEX_RECURSIVE 2 -# define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL -#endif +#define PTHREAD_MUTEX_NORMAL 0 +#define PTHREAD_MUTEX_ERRORCHECK 1 +#define PTHREAD_MUTEX_RECURSIVE 2 +#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL /* Valid ranges for the pthread stacksize attribute */ @@ -389,10 +387,12 @@ int pthread_mutexattr_getpshared(FAR const pthread_mutexattr_t *attr, FAR int *pshared); int pthread_mutexattr_setpshared(FAR pthread_mutexattr_t *attr, int pshared); -#ifdef CONFIG_MUTEX_TYPES int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type); int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type); -#endif +int pthread_mutexattr_getprotocol(FAR const pthread_mutexattr_t *attr, + FAR int *protocol); +int pthread_mutexattr_setprotocol(FAR pthread_mutexattr_t *attr, + int protocol); /* The following routines create, delete, lock and unlock mutexes. */ @@ -403,15 +403,6 @@ int pthread_mutex_lock(FAR pthread_mutex_t *mutex); int pthread_mutex_trylock(FAR pthread_mutex_t *mutex); int pthread_mutex_unlock(FAR pthread_mutex_t *mutex); -#ifdef CONFIG_PRIORITY_INHERITANCE -/* Manage priority inheritance */ - -int pthread_mutexattr_getprotocol(FAR const pthread_mutexattr_t *attr, - FAR int *protocol); -int pthread_mutexattr_setprotocol(FAR pthread_mutexattr_t *attr, - int protocol); -#endif - /* Operations on condition variables */ int pthread_condattr_init(FAR pthread_condattr_t *attr); diff --git a/libc/aio/aio.h b/libc/aio/aio.h index f28340f3c2f..f61e6908f59 100644 --- a/libc/aio/aio.h +++ b/libc/aio/aio.h @@ -69,5 +69,10 @@ extern "C" * Public Function Prototypes ****************************************************************************/ +#undef EXTERN +#if defined(__cplusplus) +} +#endif + #endif /* CONFIG_FS_AIO */ #endif /* __LIBC_AIO_AIO_H */ diff --git a/libc/pthread/Make.defs b/libc/pthread/Make.defs index 9d343f6052f..bbb3280959d 100644 --- a/libc/pthread/Make.defs +++ b/libc/pthread/Make.defs @@ -35,27 +35,24 @@ # Add the pthread C files to the build -CSRCS += pthread_attr_init.c pthread_attr_destroy.c \ - pthread_attr_setschedpolicy.c pthread_attr_getschedpolicy.c \ - pthread_attr_setinheritsched.c pthread_attr_getinheritsched.c \ - pthread_attr_setstacksize.c pthread_attr_getstacksize.c \ - pthread_attr_setschedparam.c pthread_attr_getschedparam.c \ - pthread_barrierattr_init.c pthread_barrierattr_destroy.c \ - pthread_barrierattr_getpshared.c pthread_barrierattr_setpshared.c \ - pthread_condattr_init.c pthread_condattr_destroy.c \ - pthread_mutexattr_init.c pthread_mutexattr_destroy.c \ - pthread_mutexattr_getpshared.c pthread_mutexattr_setpshared.c +CSRCS += pthread_attr_init.c pthread_attr_destroy.c +CSRCS += pthread_attr_setschedpolicy.c pthread_attr_getschedpolicy.c +CSRCS += pthread_attr_setinheritsched.c pthread_attr_getinheritsched.c +CSRCS += pthread_attr_setstacksize.c pthread_attr_getstacksize.c +CSRCS += pthread_attr_setschedparam.c pthread_attr_getschedparam.c +CSRCS += pthread_barrierattr_init.c pthread_barrierattr_destroy.c +CSRCS += pthread_barrierattr_getpshared.c pthread_barrierattr_setpshared.c +CSRCS += pthread_condattr_init.c pthread_condattr_destroy.c +CSRCS += pthread_mutexattr_init.c pthread_mutexattr_destroy.c +CSRCS += pthread_mutexattr_getpshared.c pthread_mutexattr_setpshared.c +CSRCS += pthread_mutexattr_setprotocol.c pthread_mutexattr_getprotocol.c +CSRCS += pthread_mutexattr_settype.c pthread_mutexattr_gettype.c ifeq ($(CONFIG_SMP),y) CSRCS += pthread_attr_getaffinity.c pthread_attr_setaffinity.c endif ifeq ($(CONFIG_MUTEX_TYPES),y) -CSRCS += pthread_mutexattr_settype.c pthread_mutexattr_gettype.c -endif - -ifeq ($(CONFIG_PRIORITY_INHERITANCE),y) -CSRCS += pthread_mutexattr_setprotocol.c pthread_mutexattr_getprotocol.c endif ifeq ($(CONFIG_BUILD_PROTECTED),y) diff --git a/libc/pthread/pthread_mutexattr_getprotocol.c b/libc/pthread/pthread_mutexattr_getprotocol.c index f7851855acb..f803006bb26 100644 --- a/libc/pthread/pthread_mutexattr_getprotocol.c +++ b/libc/pthread/pthread_mutexattr_getprotocol.c @@ -68,6 +68,11 @@ int pthread_mutexattr_getprotocol(FAR const pthread_mutexattr_t *attr, { DEBUGASSERT(attr != NULL && protocol != NULL); +#ifdef CONFIG_PRIORITY_INHERITANCE linfo("Returning %d\n", attr->proto); return attr->proto; +#else + linfo("Returning %d\n", PTHREAD_PRIO_NONE); + return PTHREAD_PRIO_NONE; +#endif } diff --git a/libc/pthread/pthread_mutexattr_gettype.c b/libc/pthread/pthread_mutexattr_gettype.c index c9703f5c014..9f057ae11d0 100644 --- a/libc/pthread/pthread_mutexattr_gettype.c +++ b/libc/pthread/pthread_mutexattr_gettype.c @@ -41,8 +41,6 @@ #include #include -#ifdef CONFIG_MUTEX_TYPES - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -67,13 +65,15 @@ int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type) { - if (attr && type) + if (attr != NULL && type != NULL) { +#ifdef CONFIG_MUTEX_TYPES *type = attr->type; +#else + *type = PTHREAD_MUTEX_NORMAL; +#endif return 0; } return EINVAL; } - -#endif /* CONFIG_MUTEX_TYPES */ diff --git a/libc/pthread/pthread_mutexattr_setprotocol.c b/libc/pthread/pthread_mutexattr_setprotocol.c index 621a94d1c1f..0d128e0480d 100644 --- a/libc/pthread/pthread_mutexattr_setprotocol.c +++ b/libc/pthread/pthread_mutexattr_setprotocol.c @@ -69,6 +69,7 @@ int pthread_mutexattr_setprotocol(FAR pthread_mutexattr_t *attr, linfo("attr=0x%p protocol=%d\n", attr, protocol); DEBUGASSERT(attr != NULL); +#ifdef CONFIG_PRIORITY_INHERITANCE if (protocol >= PTHREAD_PRIO_NONE && protocol <= PTHREAD_PRIO_PROTECT) { attr->proto = protocol; @@ -76,4 +77,14 @@ int pthread_mutexattr_setprotocol(FAR pthread_mutexattr_t *attr, } return EINVAL; + +#else + if (protocol == PTHREAD_PRIO_NONE) + { + return OK; + } + + return ENOSYS; +#endif + } diff --git a/libc/pthread/pthread_mutexattr_settype.c b/libc/pthread/pthread_mutexattr_settype.c index 9922a343555..b43e86fc124 100644 --- a/libc/pthread/pthread_mutexattr_settype.c +++ b/libc/pthread/pthread_mutexattr_settype.c @@ -41,8 +41,6 @@ #include #include -#ifdef CONFIG_MUTEX_TYPES - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -69,10 +67,17 @@ int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) { if (attr && type >= PTHREAD_MUTEX_NORMAL && type <= PTHREAD_MUTEX_RECURSIVE) { +#ifdef CONFIG_MUTEX_TYPES attr->type = type; +#else + if (type != PTHREAD_MUTEX_NORMAL) + { + return ENOSYS; + } +#endif + return OK; } + return EINVAL; } - -#endif /* CONFIG_MUTEX_TYPES */ diff --git a/mm/mm_heap/mm_initialize.c b/mm/mm_heap/mm_initialize.c index cacff9c0471..7696676fde3 100644 --- a/mm/mm_heap/mm_initialize.c +++ b/mm/mm_heap/mm_initialize.c @@ -79,12 +79,12 @@ void mm_addregion(FAR struct mm_heap_s *heap, FAR void *heapstart, # define IDX 0 #endif +#if defined(CONFIG_MM_SMALL) && !defined(CONFIG_SMALL_MEMORY) /* If the MCU handles wide addresses but the memory manager is configured * for a small heap, then verify that the caller is not doing something * crazy. */ -#if defined(CONFIG_MM_SMALL) && !defined(CONFIG_SMALL_MEMORY) DEBUGASSERT(heapsize <= MMSIZE_MAX+1); #endif diff --git a/net/loopback/loopback.h b/net/loopback/loopback.h index 8529fdbd1ce..a881f46fdb9 100644 --- a/net/loopback/loopback.h +++ b/net/loopback/loopback.h @@ -68,5 +68,10 @@ extern "C" * Public Function Prototypes ****************************************************************************/ +#undef EXTERN +#ifdef __cplusplus +} +#endif + #endif /* CONFIG_NET_LOOPBACK */ #endif /* __NET_LOOPBACK_LOOBACK_H */ diff --git a/sched/Kconfig b/sched/Kconfig index d06143d7d59..60156e03681 100644 --- a/sched/Kconfig +++ b/sched/Kconfig @@ -803,6 +803,18 @@ menuconfig PRIORITY_INHERITANCE default n ---help--- Set to enable support for priority inheritance on mutexes and semaphores. + When this option is enabled, the initial configuration of all seamphores + and mutexes will be with priority inheritance enabled. That configuration + may not be appropriate in all cases (such as when the semaphore or mutex + is used for signaling). In such cases, priority inheritance be be + disabled for individual semaphores by calling: + + int ret = sem_setprotocol(&sem, SEM_PRIO_NONE); + + And for individual pthread mutexes by setting the protocol attribute + before initializing the mutex: + + int ret = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_NONE); if PRIORITY_INHERITANCE diff --git a/sched/pthread/pthread_condinit.c b/sched/pthread/pthread_condinit.c index 73a6423c697..7368e0fb5a5 100644 --- a/sched/pthread/pthread_condinit.c +++ b/sched/pthread/pthread_condinit.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/pthread/pthread_condinit.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2016 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -40,9 +40,12 @@ #include #include +#include #include #include +#include + #include "pthread/pthread.h" /**************************************************************************** @@ -71,23 +74,28 @@ int pthread_cond_init(FAR pthread_cond_t *cond, FAR const pthread_condattr_t *at sinfo("cond=0x%p attr=0x%p\n", cond, attr); - if (!cond) + if (cond == NULL) { ret = EINVAL; } - /* Initialize the semaphore contained in the condition structure - * with initial count = 0 + /* Initialize the semaphore contained in the condition structure with + * initial count = 0 */ else if (sem_init((FAR sem_t *)&cond->sem, 0, 0) != OK) { ret = EINVAL; } + else + { + /* The contained semaphore is used for signaling and, hence, should + * not have priority inheritance enabled. + */ + + sem_setprotocol(&cond->sem, SEM_PRIO_NONE); + } sinfo("Returning %d\n", ret); return ret; } - - - diff --git a/sched/semaphore/sem_post.c b/sched/semaphore/sem_post.c index 1c904499536..47487db42a8 100644 --- a/sched/semaphore/sem_post.c +++ b/sched/semaphore/sem_post.c @@ -98,7 +98,22 @@ int sem_post(FAR sem_t *sem) flags = enter_critical_section(); - /* Perform the semaphore unlock operation. */ + /* Perform the semaphore unlock operation, releasing this task as a + * holder then also incrementing the count on the semaphore. + * + * NOTE: When semaphores are used for signaling purposes, the holder + * of the semaphore may not be this thread! In this case, + * sem_releaseholder() will do nothing. + * + * In the case of a mutex this could be simply resolved since there is + * only one holder but for the case of counting semaphores, there may + * be many holders and if the holder is not this thread, then it is + * not possible to know which thread/holder should be released. + * + * For this reason, it is recommended that priority inheritance be + * disabled via sem_setprotocol(SEM_PRIO_NONE) when the semahore is + * initialixed if the semaphore is to used for signaling purposes. + */ ASSERT(sem->semcount < SEM_VALUE_MAX); sem_releaseholder(sem); diff --git a/sched/wqueue/kwork_queue.c b/sched/wqueue/kwork_queue.c index 3c4acb2d00a..0ac27a87b7a 100644 --- a/sched/wqueue/kwork_queue.c +++ b/sched/wqueue/kwork_queue.c @@ -152,7 +152,7 @@ int work_queue(int qid, FAR struct work_s *work, worker_t worker, #ifdef CONFIG_SCHED_HPWORK if (qid == HPWORK) { - /* Cancel high priority work */ + /* Queue high priority work */ work_qqueue((FAR struct kwork_wqueue_s *)&g_hpwork, work, worker, arg, delay); return work_signal(HPWORK); @@ -162,7 +162,7 @@ int work_queue(int qid, FAR struct work_s *work, worker_t worker, #ifdef CONFIG_SCHED_LPWORK if (qid == LPWORK) { - /* Cancel low priority work */ + /* Queue low priority work */ work_qqueue((FAR struct kwork_wqueue_s *)&g_lpwork, work, worker, arg, delay); return work_signal(LPWORK); diff --git a/sched/wqueue/kwork_signal.c b/sched/wqueue/kwork_signal.c index 9359fb2e2a4..9c5b9a8e975 100644 --- a/sched/wqueue/kwork_signal.c +++ b/sched/wqueue/kwork_signal.c @@ -85,12 +85,11 @@ int work_signal(int qid) #ifdef CONFIG_SCHED_LPWORK if (qid == LPWORK) { - int wndx; int i; /* Find an IDLE worker thread */ - for (wndx = 0, i = 0; i < CONFIG_SCHED_LPNTHREADS; i++) + for (i = 0; i < CONFIG_SCHED_LPNTHREADS; i++) { /* Is this worker thread busy? */ @@ -98,16 +97,20 @@ int work_signal(int qid) { /* No.. select this thread */ - wndx = i; break; } } - /* Use the process ID of the IDLE worker thread (or the ID of worker - * thread 0 if all of the worker threads are busy). - */ + /* If all of the IDLE threads are busy, then just return successfully */ - pid = g_lpwork.worker[wndx].pid; + if (i >= CONFIG_SCHED_LPNTHREADS) + { + return OK; + } + + /* Otherwise, signal the first IDLE thread found */ + + pid = g_lpwork.worker[i].pid; } else #endif