sched/pthread: Implement pthread_key_delete(). This involves some minor changes to the group data structure.
This commit is contained in:
parent
0047992349
commit
8b21960ba3
@ -375,6 +375,21 @@ struct pthread_cleanup_s
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* type pthread_keyset_t *********************************************************/
|
||||||
|
/* Smallest addressable type that can hold the entire configured number of keys */
|
||||||
|
|
||||||
|
#if defined(CONFIG_NPTHREAD_KEYS) && CONFIG_NPTHREAD_KEYS > 0
|
||||||
|
# if CONFIG_NPTHREAD_KEYS > 32
|
||||||
|
# error Too many pthread keys
|
||||||
|
# elif CONFIG_NPTHREAD_KEYS > 16
|
||||||
|
typedef uint32_t pthread_keyset_t;
|
||||||
|
# elif CONFIG_NPTHREAD_KEYS > 8
|
||||||
|
typedef uint16_t pthread_keyset_t;
|
||||||
|
# else
|
||||||
|
typedef uint8_t pthread_keyset_t;
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* struct dspace_s ***************************************************************/
|
/* struct dspace_s ***************************************************************/
|
||||||
/* This structure describes a reference counted D-Space region. This must be a
|
/* This structure describes a reference counted D-Space region. This must be a
|
||||||
* separately allocated "break-away" structure that can be owned by a task and
|
* separately allocated "break-away" structure that can be owned by a task and
|
||||||
@ -520,7 +535,7 @@ struct task_group_s
|
|||||||
FAR struct join_s *tg_jointail; /* Tail of a list of join data */
|
FAR struct join_s *tg_jointail; /* Tail of a list of join data */
|
||||||
#endif
|
#endif
|
||||||
#if CONFIG_NPTHREAD_KEYS > 0
|
#if CONFIG_NPTHREAD_KEYS > 0
|
||||||
uint8_t tg_nkeys; /* Number pthread keys allocated */
|
pthread_keyset_t tg_keyset; /* Set of pthread keys allocated */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_DISABLE_SIGNALS
|
#ifndef CONFIG_DISABLE_SIGNALS
|
||||||
|
@ -616,8 +616,10 @@ config NPTHREAD_KEYS
|
|||||||
int "Maximum number of pthread keys"
|
int "Maximum number of pthread keys"
|
||||||
default 4 if !DISABLE_PTHREAD
|
default 4 if !DISABLE_PTHREAD
|
||||||
default 0 if DISABLE_PTHREAD
|
default 0 if DISABLE_PTHREAD
|
||||||
|
range 0 32
|
||||||
---help---
|
---help---
|
||||||
The number of items of thread-specific data that can be retained
|
The number of items of thread-specific data that can be retained.
|
||||||
|
The value zero disables support for pthread-specific data.
|
||||||
|
|
||||||
if !DISABLE_PTHREAD
|
if !DISABLE_PTHREAD
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/pthread/pthread_getspecific.c
|
* sched/pthread/pthread_getspecific.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007, 2009, 2013, 2018 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -88,11 +88,11 @@ FAR void *pthread_getspecific(pthread_key_t key)
|
|||||||
FAR struct task_group_s *group = rtcb->group;
|
FAR struct task_group_s *group = rtcb->group;
|
||||||
FAR void *ret = NULL;
|
FAR void *ret = NULL;
|
||||||
|
|
||||||
DEBUGASSERT(group);
|
DEBUGASSERT(group != NULL && (unsigned)key < CONFIG_NPTHREAD_KEYS);
|
||||||
|
|
||||||
/* Check if the key is valid. */
|
/* Check if the key is valid. */
|
||||||
|
|
||||||
if (key < group->tg_nkeys)
|
if (key < CONFIG_NPTHREAD_KEYS && (group->tg_keyset & (1 << key)) != 0)
|
||||||
{
|
{
|
||||||
/* Return the stored value. */
|
/* Return the stored value. */
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/pthread/pthread_keycreate.c
|
* sched/pthread/pthread_keycreate.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2009, 2013, 2018 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -44,6 +44,8 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/irq.h>
|
||||||
|
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
#include "pthread/pthread.h"
|
#include "pthread/pthread.h"
|
||||||
|
|
||||||
@ -66,23 +68,23 @@
|
|||||||
* associated with all defined keys in the new thread.
|
* associated with all defined keys in the new thread.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* key = A pointer to the key to create.
|
* key - A pointer to the key to create.
|
||||||
* destructor = An optional destructor() function that may be associated
|
* destructor - An optional destructor() function that may be associated
|
||||||
* with each key that is invoked when a thread exits. However, this
|
* with each key that is invoked when a thread exits.
|
||||||
* argument is ignored in the current implementation.
|
* However, this argument is ignored in the current
|
||||||
|
* implementation.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* If successful, the pthread_key_create() function will store the newly
|
* If successful, the pthread_key_create() function will store the newly
|
||||||
* created key value at *key and return zero (OK). Otherwise, an error
|
* created key value at *key and return zero (OK). Otherwise, an error
|
||||||
* number will bereturned to indicate the error:
|
* number will be returned to indicate the error:
|
||||||
*
|
*
|
||||||
* EAGAIN - The system lacked sufficient resources to create another
|
* EAGAIN - The system lacked sufficient resources to create another
|
||||||
* thread-specific data key, or the system-imposed limit on the total
|
* thread-specific data key, or the system-imposed limit on
|
||||||
* number of keys pers process {PTHREAD_KEYS_MAX} has been exceeded
|
* the total number of keys pers process {PTHREAD_KEYS_MAX}
|
||||||
|
* has been exceeded
|
||||||
* ENONMEM - Insufficient memory exists to create the key.
|
* ENONMEM - Insufficient memory exists to create the key.
|
||||||
*
|
*
|
||||||
* Assumptions:
|
|
||||||
*
|
|
||||||
* POSIX Compatibility:
|
* POSIX Compatibility:
|
||||||
* - The present implementation ignores the destructor argument.
|
* - The present implementation ignores the destructor argument.
|
||||||
*
|
*
|
||||||
@ -94,25 +96,41 @@ int pthread_key_create(FAR pthread_key_t *key,
|
|||||||
#if CONFIG_NPTHREAD_KEYS > 0
|
#if CONFIG_NPTHREAD_KEYS > 0
|
||||||
FAR struct tcb_s *rtcb = this_task();
|
FAR struct tcb_s *rtcb = this_task();
|
||||||
FAR struct task_group_s *group = rtcb->group;
|
FAR struct task_group_s *group = rtcb->group;
|
||||||
|
irqstate_t flags;
|
||||||
|
int candidate;
|
||||||
int ret = EAGAIN;
|
int ret = EAGAIN;
|
||||||
|
|
||||||
DEBUGASSERT(group);
|
DEBUGASSERT(key != NULL && group != NULL);
|
||||||
|
|
||||||
/* Check if we have exceeded the system-defined number of keys. */
|
/* Search for an unused key. This is done in a critical section here to
|
||||||
|
* avoid concurrent modification of the group keyset.
|
||||||
|
*/
|
||||||
|
|
||||||
if (group->tg_nkeys < PTHREAD_KEYS_MAX)
|
flags = spin_lock_irqsave();
|
||||||
|
for (candidate = 0; candidate < PTHREAD_KEYS_MAX; candidate++)
|
||||||
{
|
{
|
||||||
/* Return the key value */
|
/* Is this candidate key available? */
|
||||||
|
|
||||||
*key = group->tg_nkeys;
|
pthread_keyset_t mask = (1 << candidate);
|
||||||
|
if ((group->tg_keyset & mask) == 0)
|
||||||
|
{
|
||||||
|
/* Yes.. allocate the key and break out of the loop */
|
||||||
|
|
||||||
/* Increment the count of global keys. */
|
group->tg_keyset |= mask;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
group->tg_nkeys++;
|
spin_unlock_irqrestore(flags);
|
||||||
|
|
||||||
/* Return success. */
|
/* Check if found a valid key. */
|
||||||
|
|
||||||
ret = OK;
|
if (candidate < PTHREAD_KEYS_MAX)
|
||||||
|
{
|
||||||
|
/* Yes.. Return the key value and success */
|
||||||
|
|
||||||
|
*key = candidate;
|
||||||
|
ret = OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/pthread/pthread_keydelete.c
|
* sched/pthread/pthread_keydelete.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007, 2009, 2018 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -43,6 +43,9 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include <nuttx/irq.h>
|
||||||
|
|
||||||
|
#include "sched/sched.h"
|
||||||
#include "pthread/pthread.h"
|
#include "pthread/pthread.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -58,7 +61,7 @@
|
|||||||
* does nothing in the present implementation.
|
* does nothing in the present implementation.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* key = the key to delete
|
* key - the key to delete
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Always returns ENOSYS.
|
* Always returns ENOSYS.
|
||||||
@ -71,6 +74,33 @@
|
|||||||
|
|
||||||
int pthread_key_delete(pthread_key_t key)
|
int pthread_key_delete(pthread_key_t key)
|
||||||
{
|
{
|
||||||
|
#if CONFIG_NPTHREAD_KEYS > 0
|
||||||
|
FAR struct tcb_s *rtcb = this_task();
|
||||||
|
FAR struct task_group_s *group = rtcb->group;
|
||||||
|
pthread_keyset_t mask;
|
||||||
|
irqstate_t flags;
|
||||||
|
int ret = EINVAL;
|
||||||
|
|
||||||
|
DEBUGASSERT((unsigned)key < PTHREAD_KEYS_MAX && group != NULL);
|
||||||
|
if ((unsigned)key < PTHREAD_KEYS_MAX)
|
||||||
|
{
|
||||||
|
/* This is done in a critical section here to avoid concurrent
|
||||||
|
* modification of the group keyset.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mask = (1 << key);
|
||||||
|
flags = spin_lock_irqsave();
|
||||||
|
|
||||||
|
DEBUGASSERT((group->tg_keyset & mask) != 0);
|
||||||
|
group->tg_keyset &= ~mask;
|
||||||
|
spin_unlock_irqrestore(flags);
|
||||||
|
|
||||||
|
ret = OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
#else
|
||||||
return ENOSYS;
|
return ENOSYS;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/pthread/pthread_setspecific.c
|
* sched/pthread/pthread_setspecific.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2009, 2013, 2018 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -99,11 +99,11 @@ int pthread_setspecific(pthread_key_t key, FAR const void *value)
|
|||||||
FAR struct task_group_s *group = rtcb->group;
|
FAR struct task_group_s *group = rtcb->group;
|
||||||
int ret = EINVAL;
|
int ret = EINVAL;
|
||||||
|
|
||||||
DEBUGASSERT(group);
|
DEBUGASSERT(group != NULL && (unsigned)key < CONFIG_NPTHREAD_KEYS);
|
||||||
|
|
||||||
/* Check if the key is valid. */
|
/* Check if the key is valid. */
|
||||||
|
|
||||||
if (key < group->tg_nkeys)
|
if (key < CONFIG_NPTHREAD_KEYS && (group->tg_keyset & (1 << key)) != 0)
|
||||||
{
|
{
|
||||||
/* Store the data in the TCB. */
|
/* Store the data in the TCB. */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user