Merge branch 'rwlock'
This commit is contained in:
commit
ec2a6e3721
@ -1,5 +1,5 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* libc/pthread/pthread_rwlockread.c
|
* libc/pthread/pthread_rwlock_rdlock.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017 Mark Schulte. All rights reserved.
|
* Copyright (C) 2017 Mark Schulte. All rights reserved.
|
||||||
* Author: Mark Schulte <mark@mjs.pw>
|
* Author: Mark Schulte <mark@mjs.pw>
|
||||||
@ -50,6 +50,26 @@
|
|||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_PTHREAD_CLEANUP
|
||||||
|
static void rdlock_cleanup(FAR void *arg)
|
||||||
|
{
|
||||||
|
FAR pthread_rwlock_t *rw_lock = (FAR pthread_rwlock_t *)arg;
|
||||||
|
|
||||||
|
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
|
||||||
|
/* Check if this is a robust mutex in an inconsistent state */
|
||||||
|
|
||||||
|
if ((rw_lock->lock.flags & _PTHREAD_MFLAGS_INCONSISTENT) != 0)
|
||||||
|
{
|
||||||
|
(void)pthread_mutex_consistent(&rw_lock->lock);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
(void)pthread_mutex_unlock(&rw_lock->lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int tryrdlock(FAR pthread_rwlock_t *rw_lock)
|
static int tryrdlock(FAR pthread_rwlock_t *rw_lock)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
@ -116,6 +136,9 @@ int pthread_rwlock_timedrdlock(FAR pthread_rwlock_t *rw_lock,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PTHREAD_CLEANUP
|
||||||
|
pthread_cleanup_push(&rdlock_cleanup, rw_lock);
|
||||||
|
#endif
|
||||||
while ((err = tryrdlock(rw_lock)) == EBUSY)
|
while ((err = tryrdlock(rw_lock)) == EBUSY)
|
||||||
{
|
{
|
||||||
if (ts != NULL)
|
if (ts != NULL)
|
||||||
@ -132,6 +155,9 @@ int pthread_rwlock_timedrdlock(FAR pthread_rwlock_t *rw_lock,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_PTHREAD_CLEANUP
|
||||||
|
pthread_cleanup_pop(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
pthread_mutex_unlock(&rw_lock->lock);
|
pthread_mutex_unlock(&rw_lock->lock);
|
||||||
return err;
|
return err;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* libc/pthread/pthread_rwlockwrite.c
|
* libc/pthread/pthread_rwlock_wrlock.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017 Mark Schulte. All rights reserved.
|
* Copyright (C) 2017 Mark Schulte. All rights reserved.
|
||||||
* Author: Mark Schulte <mark@mjs.pw>
|
* Author: Mark Schulte <mark@mjs.pw>
|
||||||
@ -46,15 +46,41 @@
|
|||||||
|
|
||||||
#include <nuttx/semaphore.h>
|
#include <nuttx/semaphore.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Private Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#ifdef CONFIG_PTHREAD_CLEANUP
|
||||||
|
static void wrlock_cleanup(FAR void *arg)
|
||||||
|
{
|
||||||
|
FAR pthread_rwlock_t *rw_lock = (FAR pthread_rwlock_t *)arg;
|
||||||
|
|
||||||
|
rw_lock->num_writers--;
|
||||||
|
|
||||||
|
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
|
||||||
|
/* Check if this is a robust mutex in an inconsistent state */
|
||||||
|
|
||||||
|
if ((rw_lock->lock.flags & _PTHREAD_MFLAGS_INCONSISTENT) != 0)
|
||||||
|
{
|
||||||
|
(void)pthread_mutex_consistent(&rw_lock->lock);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
(void)pthread_mutex_unlock(&rw_lock->lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: pthread_rwlock_rdlock
|
* Name: pthread_rwlock_wrlock
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Locks a read/write lock for reading
|
* Locks a read/write lock for writing
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* None
|
* None
|
||||||
@ -106,6 +132,9 @@ int pthread_rwlock_timedwrlock(FAR pthread_rwlock_t *rw_lock,
|
|||||||
|
|
||||||
rw_lock->num_writers++;
|
rw_lock->num_writers++;
|
||||||
|
|
||||||
|
#ifdef CONFIG_PTHREAD_CLEANUP
|
||||||
|
pthread_cleanup_push(&wrlock_cleanup, rw_lock);
|
||||||
|
#endif
|
||||||
while (rw_lock->write_in_progress || rw_lock->num_readers > 0)
|
while (rw_lock->write_in_progress || rw_lock->num_readers > 0)
|
||||||
{
|
{
|
||||||
if (ts != NULL)
|
if (ts != NULL)
|
||||||
@ -122,12 +151,14 @@ int pthread_rwlock_timedwrlock(FAR pthread_rwlock_t *rw_lock,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_PTHREAD_CLEANUP
|
||||||
|
pthread_cleanup_pop(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
{
|
{
|
||||||
rw_lock->write_in_progress = true;
|
rw_lock->write_in_progress = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* In case of error, notify any blocked readers. */
|
/* In case of error, notify any blocked readers. */
|
||||||
|
@ -601,8 +601,6 @@ config PTHREAD_CLEANUP_STACKSIZE
|
|||||||
8 for a CPU with 32-bit addressing and 4 for a CPU with 16-bit
|
8 for a CPU with 32-bit addressing and 4 for a CPU with 16-bit
|
||||||
addressing.
|
addressing.
|
||||||
|
|
||||||
endmenu # Pthread Options
|
|
||||||
|
|
||||||
config CANCELLATION_POINTS
|
config CANCELLATION_POINTS
|
||||||
bool "Cancellation points"
|
bool "Cancellation points"
|
||||||
default n
|
default n
|
||||||
@ -611,6 +609,8 @@ config CANCELLATION_POINTS
|
|||||||
cancellation points will also used with the () task_delete() API even if
|
cancellation points will also used with the () task_delete() API even if
|
||||||
pthreads are not enabled.
|
pthreads are not enabled.
|
||||||
|
|
||||||
|
endmenu # Pthread Options
|
||||||
|
|
||||||
menu "Performance Monitoring"
|
menu "Performance Monitoring"
|
||||||
|
|
||||||
config SCHED_CPULOAD
|
config SCHED_CPULOAD
|
||||||
|
@ -145,6 +145,12 @@ int pthread_cancel(pthread_t thread)
|
|||||||
pthread_exit(PTHREAD_CANCELED);
|
pthread_exit(PTHREAD_CANCELED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
|
||||||
|
/* Recover any mutexes still held by the canceled thread */
|
||||||
|
|
||||||
|
pthread_mutex_inconsistent(tcb);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PTHREAD_CLEANUP
|
#ifdef CONFIG_PTHREAD_CLEANUP
|
||||||
/* Perform any stack pthread clean-up callbacks.
|
/* Perform any stack pthread clean-up callbacks.
|
||||||
*
|
*
|
||||||
@ -162,12 +168,6 @@ int pthread_cancel(pthread_t thread)
|
|||||||
|
|
||||||
(void)pthread_completejoin((pid_t)thread, PTHREAD_CANCELED);
|
(void)pthread_completejoin((pid_t)thread, PTHREAD_CANCELED);
|
||||||
|
|
||||||
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
|
|
||||||
/* Recover any mutexes still held by the canceled thread */
|
|
||||||
|
|
||||||
pthread_mutex_inconsistent(tcb);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Then let task_terminate do the real work */
|
/* Then let task_terminate do the real work */
|
||||||
|
|
||||||
return task_terminate((pid_t)thread, false);
|
return task_terminate((pid_t)thread, false);
|
||||||
|
@ -105,6 +105,12 @@ void pthread_exit(FAR void *exit_value)
|
|||||||
tcb->cpcount = 0;
|
tcb->cpcount = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
|
||||||
|
/* Recover any mutexes still held by the canceled thread */
|
||||||
|
|
||||||
|
pthread_mutex_inconsistent((FAR struct pthread_tcb_s *)tcb);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PTHREAD_CLEANUP
|
#ifdef CONFIG_PTHREAD_CLEANUP
|
||||||
/* Perform any stack pthread clean-up callbacks */
|
/* Perform any stack pthread clean-up callbacks */
|
||||||
|
|
||||||
@ -123,12 +129,6 @@ void pthread_exit(FAR void *exit_value)
|
|||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_PTHREAD_MUTEX_UNSAFE
|
|
||||||
/* Recover any mutexes still held by the canceled thread */
|
|
||||||
|
|
||||||
pthread_mutex_inconsistent((FAR struct pthread_tcb_s *)tcb);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Perform common task termination logic. This will get called again later
|
/* Perform common task termination logic. This will get called again later
|
||||||
* through logic kicked off by _exit(). However, we need to call it before
|
* through logic kicked off by _exit(). However, we need to call it before
|
||||||
* calling _exit() in order certain operations if this is the last thread
|
* calling _exit() in order certain operations if this is the last thread
|
||||||
|
@ -119,7 +119,6 @@ int pthread_mutex_consistent(FAR pthread_mutex_t *mutex)
|
|||||||
/* The thread associated with the PID no longer exists */
|
/* The thread associated with the PID no longer exists */
|
||||||
|
|
||||||
mutex->pid = -1;
|
mutex->pid = -1;
|
||||||
mutex->flags &= _PTHREAD_MFLAGS_ROBUST;
|
|
||||||
#ifdef CONFIG_PTHREAD_MUTEX_TYPES
|
#ifdef CONFIG_PTHREAD_MUTEX_TYPES
|
||||||
mutex->nlocks = 0;
|
mutex->nlocks = 0;
|
||||||
#endif
|
#endif
|
||||||
@ -132,6 +131,9 @@ int pthread_mutex_consistent(FAR pthread_mutex_t *mutex)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear the inconsistent flag in any case */
|
||||||
|
|
||||||
|
mutex->flags &= _PTHREAD_MFLAGS_ROBUST;
|
||||||
sched_unlock();
|
sched_unlock();
|
||||||
ret = OK;
|
ret = OK;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user