Merge remote-tracking branch 'origin/master' into misoc

This commit is contained in:
Gregory Nutt 2016-11-06 11:09:05 -06:00
commit 89c3c20052
32 changed files with 311 additions and 127 deletions

22
TODO
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -43,6 +43,7 @@
#include <nuttx/config.h>
#include <nuttx/irq.h>
#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
****************************************************************************/

View File

@ -49,6 +49,8 @@
# include <debug.h>
# 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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -55,7 +55,8 @@
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C" {
extern "C"
{
#else
#define EXTERN extern
#endif

View File

@ -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 */

View File

@ -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

View File

@ -39,7 +39,7 @@
#include <semaphore.h>
#include <nuttx/sermaphore.h>
#include <nuttx/semaphore.h>
#include "up_internal.h"

View File

@ -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 */

View File

@ -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 */

View File

@ -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
*

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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);

View File

@ -69,5 +69,10 @@ extern "C"
* Public Function Prototypes
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* CONFIG_FS_AIO */
#endif /* __LIBC_AIO_AIO_H */

View File

@ -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)

View File

@ -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
}

View File

@ -41,8 +41,6 @@
#include <pthread.h>
#include <errno.h>
#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 */

View File

@ -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
}

View File

@ -41,8 +41,6 @@
#include <pthread.h>
#include <errno.h>
#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 */

View File

@ -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

View File

@ -68,5 +68,10 @@ extern "C"
* Public Function Prototypes
****************************************************************************/
#undef EXTERN
#ifdef __cplusplus
}
#endif
#endif /* CONFIG_NET_LOOPBACK */
#endif /* __NET_LOOPBACK_LOOBACK_H */

View File

@ -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

View File

@ -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 <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -40,9 +40,12 @@
#include <nuttx/config.h>
#include <pthread.h>
#include <semaphore.h>
#include <debug.h>
#include <errno.h>
#include <nuttx/semaphore.h>
#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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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