diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2013-02-03 16:43:58 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2013-02-03 16:43:58 +0000 |
commit | 32dde889e28f1e15c4a97f3e701800ba22ab849d (patch) | |
tree | 83fc8fbb0fcef9302298d1ccb819cfba26ec8825 /nuttx | |
parent | 0066db82f921ad84a9017242396e37259f3d71f4 (diff) | |
download | px4-nuttx-32dde889e28f1e15c4a97f3e701800ba22ab849d.tar.gz px4-nuttx-32dde889e28f1e15c4a97f3e701800ba22ab849d.tar.bz2 px4-nuttx-32dde889e28f1e15c4a97f3e701800ba22ab849d.zip |
Move pthread join and key creation data into the task group
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5602 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx')
-rw-r--r-- | nuttx/ChangeLog | 3 | ||||
-rw-r--r-- | nuttx/include/nuttx/sched.h | 16 | ||||
-rw-r--r-- | nuttx/sched/Makefile | 3 | ||||
-rw-r--r-- | nuttx/sched/group_create.c | 21 | ||||
-rw-r--r-- | nuttx/sched/group_find.c | 2 | ||||
-rw-r--r-- | nuttx/sched/group_internal.h | 6 | ||||
-rw-r--r-- | nuttx/sched/group_leave.c | 6 | ||||
-rw-r--r-- | nuttx/sched/pthread_cancel.c | 6 | ||||
-rw-r--r-- | nuttx/sched/pthread_completejoin.c | 98 | ||||
-rw-r--r-- | nuttx/sched/pthread_create.c | 33 | ||||
-rw-r--r-- | nuttx/sched/pthread_detach.c | 23 | ||||
-rw-r--r-- | nuttx/sched/pthread_findjoininfo.c | 17 | ||||
-rw-r--r-- | nuttx/sched/pthread_getspecific.c | 8 | ||||
-rw-r--r-- | nuttx/sched/pthread_initialize.c | 36 | ||||
-rw-r--r-- | nuttx/sched/pthread_internal.h | 52 | ||||
-rw-r--r-- | nuttx/sched/pthread_join.c | 28 | ||||
-rw-r--r-- | nuttx/sched/pthread_keycreate.c | 14 | ||||
-rw-r--r-- | nuttx/sched/pthread_setspecific.c | 9 | ||||
-rw-r--r-- | nuttx/sched/task_getgroup.c (renamed from nuttx/sched/pthread_removejoininfo.c) | 126 | ||||
-rw-r--r-- | nuttx/sched/task_spawn.c | 8 |
20 files changed, 302 insertions, 213 deletions
diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index c3e16607f..6e2f5bd02 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -4106,4 +4106,5 @@ task_create(). * Corrected all argv[] arguments. Should be char * const *, not const char **. - + * sched/pthread* and include/nuttx/sched: Move pthread join data + and pthread key calculation data into the "task group" structure. diff --git a/nuttx/include/nuttx/sched.h b/nuttx/include/nuttx/sched.h index f8b4eb0dc..75c478220 100644 --- a/nuttx/include/nuttx/sched.h +++ b/nuttx/include/nuttx/sched.h @@ -273,6 +273,12 @@ struct dspace_s */ #ifdef HAVE_TASK_GROUP + +#ifndef CONFIG_DISABLE_PTHREAD +struct join_s; /* Forward reference */ + /* Defined in pthread_internal.h */ +#endif + struct task_group_s { #ifdef HAVE_GROUP_MEMBERS @@ -296,6 +302,16 @@ struct task_group_s FAR struct child_status_s *tg_children; /* Head of a list of child status */ #endif + /* Pthreads *******************************************************************/ + +#ifndef CONFIG_DISABLE_PTHREAD + /* Pthread join Info: */ + sem_t tg_joinsem; /* Mutually exclusive access to join data */ + FAR struct join_s *tg_joinhead; /* Head of a list of join data */ + FAR struct join_s *tg_jointail; /* Tail of a list of join data */ + uint8_t tg_nkeys; /* Number pthread keys allocated */ +#endif + /* Environment variables ******************************************************/ #ifndef CONFIG_DISABLE_ENVIRON diff --git a/nuttx/sched/Makefile b/nuttx/sched/Makefile index 0b0173306..780549abf 100644 --- a/nuttx/sched/Makefile +++ b/nuttx/sched/Makefile @@ -86,6 +86,7 @@ endif GRP_SRCS = group_create.c group_join.c group_leave.c group_find.c GRP_SRCS += group_setupstreams.c group_setupidlefiles.c group_setuptaskfiles.c +GRP_SRCS += task_getgroup.c ifeq ($(CONFIG_SCHED_HAVE_PARENT),y) GRP_SRCS += task_reparent.c @@ -145,7 +146,7 @@ PTHREAD_SRCS += pthread_barrierinit.c pthread_barrierdestroy.c pthread_barrierwa PTHREAD_SRCS += pthread_cancel.c pthread_setcancelstate.c PTHREAD_SRCS += pthread_keycreate.c pthread_setspecific.c pthread_getspecific.c pthread_keydelete.c PTHREAD_SRCS += pthread_initialize.c pthread_completejoin.c pthread_findjoininfo.c -PTHREAD_SRCS += pthread_removejoininfo.c pthread_once.c pthread_setschedprio.c +PTHREAD_SRCS += pthread_once.c pthread_setschedprio.c ifneq ($(CONFIG_DISABLE_SIGNALS),y) PTHREAD_SRCS += pthread_condtimedwait.c pthread_kill.c pthread_sigmask.c diff --git a/nuttx/sched/group_create.c b/nuttx/sched/group_create.c index 24f6923aa..58eb60606 100644 --- a/nuttx/sched/group_create.c +++ b/nuttx/sched/group_create.c @@ -176,36 +176,47 @@ void group_assigngid(FAR struct task_group_s *group) int group_allocate(FAR _TCB *tcb) { + FAR struct task_group_s *group; int ret; DEBUGASSERT(tcb && !tcb->group); /* Allocate the group structure and assign it to the TCB */ - tcb->group = (FAR struct task_group_s *)kzalloc(sizeof(struct task_group_s)); - if (!tcb->group) + group = (FAR struct task_group_s *)kzalloc(sizeof(struct task_group_s)); + if (!group) { return -ENOMEM; } + /* Attach the group to the TCB */ + + tcb->group = group; + /* Assign the group a unique ID. If g_gidcounter were to wrap before we * finish with task creation, that would be a problem. */ #ifdef HAVE_GROUP_MEMBERS - group_assigngid(tcb->group); + group_assigngid(group); #endif /* Duplicate the parent tasks envionment */ - ret = env_dup(tcb->group); + ret = env_dup(group); if (ret < 0) { - kfree(tcb->group); + kfree(group); tcb->group = NULL; return ret; } + /* Initialize the pthread join semaphore */ + +#ifndef CONFIG_DISABLE_PTHREAD + (void)sem_init(&group->tg_joinsem, 0, 1); +#endif + return OK; } diff --git a/nuttx/sched/group_find.c b/nuttx/sched/group_find.c index eb3989223..8683990dd 100644 --- a/nuttx/sched/group_find.c +++ b/nuttx/sched/group_find.c @@ -90,7 +90,7 @@ * Return Value: * On success, a pointer to the group task structure is returned. This * function can fail only if there is no group that corresponds to the - * groupd ID. + * group ID. * * Assumptions: * Called during when signally tasks in a safe context. No special diff --git a/nuttx/sched/group_internal.h b/nuttx/sched/group_internal.h index ca6aacff7..c949968cf 100644 --- a/nuttx/sched/group_internal.h +++ b/nuttx/sched/group_internal.h @@ -88,6 +88,12 @@ int group_addmember(FAR struct task_group_s *group, pid_t pid); int group_removemember(FAR struct task_group_s *group, pid_t pid); #endif +/* Convenience functions */ + +FAR struct task_group_s *task_getgroup(pid_t pid); + +/* Signaling group members */ + #ifndef CONFIG_DISABLE_SIGNALS int group_signal(FAR struct task_group_s *group, FAR siginfo_t *info); #endif diff --git a/nuttx/sched/group_leave.c b/nuttx/sched/group_leave.c index 4dec30633..d87420d1c 100644 --- a/nuttx/sched/group_leave.c +++ b/nuttx/sched/group_leave.c @@ -154,6 +154,12 @@ static inline void group_release(FAR struct task_group_s *group) group_removechildren(group); #endif + /* Free pthread join data */ + +#ifndef CONFIG_DISABLE_PTHREAD + (void)sem_destroy(&group->tg_joinsem); +#endif + /* Free all file-related resources now. We really need to close files as * soon as possible while we still have a functioning task. */ diff --git a/nuttx/sched/pthread_cancel.c b/nuttx/sched/pthread_cancel.c index 5e34eeaba..4dd209aeb 100644 --- a/nuttx/sched/pthread_cancel.c +++ b/nuttx/sched/pthread_cancel.c @@ -1,7 +1,7 @@ /************************************************************************** * sched/pthread_cancel.c * - * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -93,7 +93,9 @@ int pthread_cancel(pthread_t thread) tcb = sched_gettcb((pid_t)thread); if (!tcb) { - /* The pid does not correspond to any known thread */ + /* The pid does not correspond to any known thread. The thread + * has probably already exited. + */ return ESRCH; } diff --git a/nuttx/sched/pthread_completejoin.c b/nuttx/sched/pthread_completejoin.c index 7c5191034..86f4eac3d 100644 --- a/nuttx/sched/pthread_completejoin.c +++ b/nuttx/sched/pthread_completejoin.c @@ -1,7 +1,7 @@ /************************************************************************ * sched/pthread_completejoin.c * - * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011, 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -46,6 +46,7 @@ #include <debug.h> #include "os_internal.h" +#include "group_internal.h" #include "pthread_internal.h" /************************************************************************ @@ -78,7 +79,7 @@ * ************************************************************************/ -static bool pthread_notifywaiters(FAR join_t *pjoin) +static bool pthread_notifywaiters(FAR struct join_s *pjoin) { int ntasks_waiting; int status; @@ -122,6 +123,76 @@ static bool pthread_notifywaiters(FAR join_t *pjoin) } /************************************************************************ + * Name: pthread_removejoininfo + * + * Description: + * Remove a join structure from the local data set. + * + * Parameters: + * pid + * + * Return Value: + * None. + * + * Assumptions: + * The caller has provided protection from re-entrancy. + * + ************************************************************************/ + +static void pthread_removejoininfo(FAR struct task_group_s *group, + pid_t pid) +{ + FAR struct join_s *prev; + FAR struct join_s *join; + + /* Find the entry with the matching pid */ + + for (prev = NULL, join = group->tg_joinhead; + (join && (pid_t)join->thread != pid); + prev = join, join = join->next); + + /* Remove it from the data set. */ + + /* First check if this is the entry at the head of the list. */ + + if (join) + { + if (!prev) + { + /* Check if this is the only entry in the list */ + + if (!join->next) + { + group->tg_joinhead = NULL; + group->tg_jointail = NULL; + } + + /* Otherwise, remove it from the head of the list */ + + else + { + group->tg_joinhead = join->next; + } + } + + /* It is not at the head of the list, check if it is at the tail. */ + + else if (!join->next) + { + group->tg_jointail = prev; + prev->next = NULL; + } + + /* No, remove it from the middle of the list. */ + + else + { + prev->next = join->next; + } + } +} + +/************************************************************************ * Public Functions ************************************************************************/ @@ -147,18 +218,20 @@ static bool pthread_notifywaiters(FAR join_t *pjoin) int pthread_completejoin(pid_t pid, FAR void *exit_value) { - FAR join_t *pjoin; + FAR struct task_group_s *group = task_getgroup(pid); + FAR struct join_s *pjoin; - svdbg("pid=%d exit_value=%p\n", pid, exit_value); + svdbg("pid=%d exit_value=%p group=%p\n", pid, exit_value, group); + DEBUGASSERT(group); /* First, find thread's structure in the private data set. */ - (void)pthread_takesemaphore(&g_join_semaphore); - pjoin = pthread_findjoininfo(pid); + (void)pthread_takesemaphore(&group->tg_joinsem); + pjoin = pthread_findjoininfo(group, pid); if (!pjoin) { sdbg("Could not find join info, pid=%d\n", pid); - (void)pthread_givesemaphore(&g_join_semaphore); + (void)pthread_givesemaphore(&group->tg_joinsem); return ERROR; } else @@ -182,14 +255,14 @@ int pthread_completejoin(pid_t pid, FAR void *exit_value) if (!waiters && pjoin->detached) { - pthread_destroyjoin(pjoin); + pthread_destroyjoin(group, pjoin); } /* Giving the following semaphore will allow the waiters * to call pthread_destroyjoin. */ - (void)pthread_givesemaphore(&g_join_semaphore); + (void)pthread_givesemaphore(&group->tg_joinsem); } return OK; @@ -207,17 +280,18 @@ int pthread_completejoin(pid_t pid, FAR void *exit_value) * no thread ever calls pthread_join. In case, there is a memory leak! * * Assumptions: - * The caller holds g_join_semaphore + * The caller holds tg_joinsem * ************************************************************************/ -void pthread_destroyjoin(FAR join_t *pjoin) +void pthread_destroyjoin(FAR struct task_group_s *group, + FAR struct join_s *pjoin) { sdbg("pjoin=0x%p\n", pjoin); /* Remove the join info from the set of joins */ - (void)pthread_removejoininfo((pid_t)pjoin->thread); + pthread_removejoininfo(group, (pid_t)pjoin->thread); /* Destroy its semaphores */ diff --git a/nuttx/sched/pthread_create.c b/nuttx/sched/pthread_create.c index 48a0788a6..82a5bc271 100644 --- a/nuttx/sched/pthread_create.c +++ b/nuttx/sched/pthread_create.c @@ -147,7 +147,7 @@ static void pthread_argsetup(FAR _TCB *tcb, pthread_addr_t arg) * Name: pthread_addjoininfo * * Description: - * Add a join_t to the local data set. + * Add a join structure to the local data set. * * Parameters: * pjoin @@ -160,27 +160,27 @@ static void pthread_argsetup(FAR _TCB *tcb, pthread_addr_t arg) * ****************************************************************************/ -static void pthread_addjoininfo(FAR join_t *pjoin) +static inline void pthread_addjoininfo(FAR struct task_group_s *group, + FAR struct join_s *pjoin) { pjoin->next = NULL; - if (!g_pthread_tail) + if (!group->tg_jointail) { - g_pthread_head = pjoin; + group->tg_joinhead = pjoin; } else { - g_pthread_tail->next = pjoin; + group->tg_jointail->next = pjoin; } - g_pthread_tail = pjoin; + group->tg_jointail = pjoin; } /**************************************************************************** * Name: pthread_start * * Description: - * This function is the low level entry point into the - * pthread + * This function is the low level entry point into the pthread * * Parameters: * None @@ -190,16 +190,19 @@ static void pthread_addjoininfo(FAR join_t *pjoin) static void pthread_start(void) { FAR _TCB *ptcb = (FAR _TCB*)g_readytorun.head; - FAR join_t *pjoin = (FAR join_t*)ptcb->joininfo; + FAR struct task_group_s *group = ptcb->group; + FAR struct join_s *pjoin = (FAR struct join_s*)ptcb->joininfo; pthread_addr_t exit_status; + DEBUGASSERT(group && pjoin); + /* Sucessfully spawned, add the pjoin to our data set. * Don't re-enable pre-emption until this is done. */ - (void)pthread_takesemaphore(&g_join_semaphore); - pthread_addjoininfo(pjoin); - (void)pthread_givesemaphore(&g_join_semaphore); + (void)pthread_takesemaphore(&group->tg_joinsem); + pthread_addjoininfo(group, pjoin); + (void)pthread_givesemaphore(&group->tg_joinsem); /* Report to the spawner that we successfully started. */ @@ -245,7 +248,7 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, pthread_startroutine_t start_routine, pthread_addr_t arg) { FAR _TCB *ptcb; - FAR join_t *pjoin; + FAR struct join_s *pjoin; int priority; #if CONFIG_RR_INTERVAL > 0 int policy; @@ -298,7 +301,7 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, /* Allocate a detachable structure to support pthread_join logic */ - pjoin = (FAR join_t*)kzalloc(sizeof(join_t)); + pjoin = (FAR struct join_s*)kzalloc(sizeof(struct join_s)); if (!pjoin) { errcode = ENOMEM; @@ -424,7 +427,7 @@ int pthread_create(FAR pthread_t *thread, FAR pthread_attr_t *attr, if (ret == OK) { /* Wait for the task to actually get running and to register - * its join_t + * its join structure. */ (void)pthread_takesemaphore(&pjoin->data_sem); diff --git a/nuttx/sched/pthread_detach.c b/nuttx/sched/pthread_detach.c index a959d94b3..6c4b17bee 100644 --- a/nuttx/sched/pthread_detach.c +++ b/nuttx/sched/pthread_detach.c @@ -1,7 +1,7 @@ /************************************************************************ * sched/pthread_detach.c * - * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -43,9 +43,11 @@ #include <stdbool.h> #include <pthread.h> #include <errno.h> +#include <assert.h> #include <debug.h> #include "os_internal.h" +#include "group_internal.h" #include "pthread_internal.h" /************************************************************************ @@ -79,6 +81,10 @@ * A thread object may be "detached" to specify that the return value * and completion status will not be requested. * + * The caller's task/thread must belong to the same "task group" as the + * pthread is (or was) a member of. The thread may or may not still + * be running. + * * Parameters: * thread * @@ -91,15 +97,18 @@ int pthread_detach(pthread_t thread) { - FAR join_t *pjoin; + FAR _TCB *rtcb = (FAR _TCB *)g_readytorun.head; + FAR struct task_group_s *group = rtcb->group; + FAR struct join_s *pjoin; int ret; - sdbg("Thread=%d\n", thread); + sdbg("Thread=%d group=%p\n", thread, group); + DEBUGASSERT(group); /* Find the entry associated with this pthread. */ - (void)pthread_takesemaphore(&g_join_semaphore); - pjoin = pthread_findjoininfo((pid_t)thread); + (void)pthread_takesemaphore(&group->tg_joinsem); + pjoin = pthread_findjoininfo(group, (pid_t)thread); if (!pjoin) { sdbg("Could not find thread entry\n"); @@ -113,7 +122,7 @@ int pthread_detach(pthread_t thread) { /* YES.. just remove the thread entry. */ - pthread_destroyjoin(pjoin); + pthread_destroyjoin(group, pjoin); } else { @@ -130,7 +139,7 @@ int pthread_detach(pthread_t thread) ret = OK; } - (void)pthread_givesemaphore(&g_join_semaphore); + (void)pthread_givesemaphore(&group->tg_joinsem); sdbg("Returning %d\n", ret); return ret; diff --git a/nuttx/sched/pthread_findjoininfo.c b/nuttx/sched/pthread_findjoininfo.c index 584ed8f96..8bcb4e407 100644 --- a/nuttx/sched/pthread_findjoininfo.c +++ b/nuttx/sched/pthread_findjoininfo.c @@ -1,7 +1,7 @@ /************************************************************************ * pthread_findjoininfo.c * - * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -41,6 +41,7 @@ #include <sys/types.h> +#include "group_internal.h" #include "pthread_internal.h" /************************************************************************ @@ -71,10 +72,11 @@ * Name: thread_findjoininfo * * Description: - * Find a join_t to the local data set. + * Find a join structure in a local data set. * * Parameters: - * pid + * group - The that the pid is (or was) a member of of + * pid - The ID of the pthread * * Return Value: * None or pointer to the found entry. @@ -84,13 +86,16 @@ * ************************************************************************/ -FAR join_t *pthread_findjoininfo(pid_t pid) +FAR struct join_s *pthread_findjoininfo(FAR struct task_group_s *group, + pid_t pid) { - FAR join_t *pjoin; + FAR struct join_s *pjoin; + + DEBUGASSERT(group); /* Find the entry with the matching pid */ - for (pjoin = g_pthread_head; + for (pjoin = group->tg_joinhead; (pjoin && (pid_t)pjoin->thread != pid); pjoin = pjoin->next); diff --git a/nuttx/sched/pthread_getspecific.c b/nuttx/sched/pthread_getspecific.c index eeead14fa..c6c61fed6 100644 --- a/nuttx/sched/pthread_getspecific.c +++ b/nuttx/sched/pthread_getspecific.c @@ -1,7 +1,7 @@ /************************************************************************ * sched/pthread_getspecific.c * - * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -41,6 +41,7 @@ #include <sched.h> #include <errno.h> +#include <assert.h> #include <debug.h> #include "os_internal.h" @@ -104,11 +105,14 @@ FAR void *pthread_getspecific(pthread_key_t key) { #if CONFIG_NPTHREAD_KEYS > 0 FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head; + FAR struct task_group_s *group = rtcb->group; FAR void *ret = NULL; + DEBUGASSERT(group); + /* Check if the key is valid. */ - if (key < g_pthread_num_keys) + if (key < group->tg_nkeys) { /* Return the stored value. */ diff --git a/nuttx/sched/pthread_initialize.c b/nuttx/sched/pthread_initialize.c index 09db1d50e..71b13ebdc 100644 --- a/nuttx/sched/pthread_initialize.c +++ b/nuttx/sched/pthread_initialize.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/pthread_initialize.c * - * Copyright (C) 2007-2010 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2010, 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -57,25 +57,6 @@ * Global Variables ****************************************************************************/ -/* This is the head of a private singly linked list. It - * is used to retain information about the spawned threads. - */ - -FAR join_t *g_pthread_head = NULL; -FAR join_t *g_pthread_tail = NULL; - -/* Mutually exclusive access to this data set is enforced with - * the following (un-named) semaphore. - */ - -sem_t g_join_semaphore; - -/* This keys track of the number of global keys that have been - * allocated. - */ - -uint8_t g_pthread_num_keys; - /**************************************************************************** * Private Variables ****************************************************************************/ @@ -92,7 +73,9 @@ uint8_t g_pthread_num_keys; * Name: pthread_initialize * * Description: - * This is an internal OS function called only at power-up boot time. + * This is an internal OS function called only at power-up boot time. It + * no longer does anything since all of the pthread data structures have + * been moved into the "task group" * * Parameters: * None @@ -106,17 +89,6 @@ uint8_t g_pthread_num_keys; void pthread_initialize(void) { - /* Initialize some global variables */ - - g_pthread_head = NULL; - g_pthread_tail = NULL; - g_pthread_num_keys = 0; - - /* Initialize the join semaphore to one (to support one-at- - * a-time access to private data sets). - */ - - (void)sem_init(&g_join_semaphore, 0, 1); } /**************************************************************************** diff --git a/nuttx/sched/pthread_internal.h b/nuttx/sched/pthread_internal.h index ca70ab291..b5c4c3743 100644 --- a/nuttx/sched/pthread_internal.h +++ b/nuttx/sched/pthread_internal.h @@ -1,7 +1,7 @@ /**************************************************************************** * sched/pthread_internal.h * - * Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2011, 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -75,53 +75,37 @@ struct join_s sem_t exit_sem; /* Implements join */ sem_t data_sem; /* Implements join */ pthread_addr_t exit_value; /* Returned data */ - }; -typedef struct join_s join_t; - /**************************************************************************** * Public Variables ****************************************************************************/ -/* This is the head of a private singly linked list. It is used to retain - * information about the spawned threads. - */ - -extern FAR join_t *g_pthread_head; -extern FAR join_t *g_pthread_tail; - -/* Mutually exclusive access to this data set is enforced with the following - * (un-named) semaphore. - */ - -extern sem_t g_join_semaphore; - -/* This keys track of the number of global keys that have been allocated. */ - -extern uint8_t g_pthread_num_keys; - -/**************************************************************************** - * Public Function Prototypes - ****************************************************************************/ - #ifdef __cplusplus #define EXTERN extern "C" -extern "C" { +extern "C" +{ #else #define EXTERN extern #endif -EXTERN void weak_function pthread_initialize(void); -EXTERN int pthread_completejoin(pid_t pid, FAR void *exit_value); -EXTERN void pthread_destroyjoin(FAR join_t *pjoin); -EXTERN FAR join_t *pthread_findjoininfo(pid_t pid); -EXTERN int pthread_givesemaphore(sem_t *sem); -EXTERN FAR join_t *pthread_removejoininfo(pid_t pid); -EXTERN int pthread_takesemaphore(sem_t *sem); +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +struct task_group_s; /* Forward reference */ + +void weak_function pthread_initialize(void); +int pthread_completejoin(pid_t pid, FAR void *exit_value); +void pthread_destroyjoin(FAR struct task_group_s *group, + FAR struct join_s *pjoin); +FAR struct join_s *pthread_findjoininfo(FAR struct task_group_s *group, + pid_t pid); +int pthread_givesemaphore(sem_t *sem); +int pthread_takesemaphore(sem_t *sem); #ifdef CONFIG_MUTEX_TYPES -EXTERN int pthread_mutexattr_verifytype(int type); +int pthread_mutexattr_verifytype(int type); #endif #undef EXTERN diff --git a/nuttx/sched/pthread_join.c b/nuttx/sched/pthread_join.c index d3f648dc7..e5ff56734 100644 --- a/nuttx/sched/pthread_join.c +++ b/nuttx/sched/pthread_join.c @@ -1,7 +1,7 @@ /**************************************************************************** * pthread_join.c * - * Copyright (C) 2007, 2008, 2011 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2008, 2011, 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -44,6 +44,7 @@ #include <debug.h> #include "os_internal.h" +#include "group_internal.h" #include "pthread_internal.h" /**************************************************************************** @@ -77,6 +78,10 @@ * A thread can await termination of another thread and retrieve the * return value of the thread. * + * The caller's task/thread must belong to the same "task group" as the + * pthread is (or was) a member of. The thread may or may not still + * be running. + * * Parameters: * thread * pexit_value @@ -97,10 +102,13 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value) { - FAR join_t *pjoin; + FAR _TCB *rtcb = (FAR _TCB *)g_readytorun.head; + FAR struct task_group_s *group = rtcb->group; + FAR struct join_s *pjoin; int ret; - sdbg("thread=%d\n", thread); + sdbg("thread=%d group=%p\n", thread, group); + DEBUGASSERT(group); /* First make sure that this is not an attempt to join to * ourself. @@ -117,7 +125,7 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value) * because it will also attempt to get this semaphore. */ - (void)pthread_takesemaphore(&g_join_semaphore); + (void)pthread_takesemaphore(&group->tg_joinsem); /* Find the join information associated with this thread. * This can fail for one of three reasons: (1) There is no @@ -126,7 +134,7 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value) * was detached and has exited. */ - pjoin = pthread_findjoininfo((pid_t)thread); + pjoin = pthread_findjoininfo(group, (pid_t)thread); if (!pjoin) { /* Determine what kind of error to return */ @@ -151,7 +159,7 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value) ret = EINVAL; } - (void)pthread_givesemaphore(&g_join_semaphore); + (void)pthread_givesemaphore(&group->tg_joinsem); } else { @@ -192,7 +200,7 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value) * semaphore. */ - (void)pthread_givesemaphore(&g_join_semaphore); + (void)pthread_givesemaphore(&group->tg_joinsem); /* Take the thread's thread exit semaphore. We will sleep here * until the thread exits. We need to exercise caution because @@ -220,7 +228,7 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value) * pthread_destroyjoin is called. */ - (void)pthread_takesemaphore(&g_join_semaphore); + (void)pthread_takesemaphore(&group->tg_joinsem); } /* Pre-emption is okay now. The logic still cannot be re-entered @@ -235,10 +243,10 @@ int pthread_join(pthread_t thread, FAR pthread_addr_t *pexit_value) if (--pjoin->crefs <= 0) { - (void)pthread_destroyjoin(pjoin); + (void)pthread_destroyjoin(group, pjoin); } - (void)pthread_givesemaphore(&g_join_semaphore); + (void)pthread_givesemaphore(&group->tg_joinsem); ret = OK; } diff --git a/nuttx/sched/pthread_keycreate.c b/nuttx/sched/pthread_keycreate.c index 7579e4c11..db09d035f 100644 --- a/nuttx/sched/pthread_keycreate.c +++ b/nuttx/sched/pthread_keycreate.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/pthread_keycreate.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -41,8 +41,10 @@ #include <sched.h> #include <errno.h> +#include <assert.h> #include <debug.h> +#include "os_internal.h" #include "pthread_internal.h" /**************************************************************************** @@ -109,19 +111,23 @@ int pthread_key_create(FAR pthread_key_t *key, CODE void (*destructor)(void*)) { #if CONFIG_NPTHREAD_KEYS > 0 + FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head; + FAR struct task_group_s *group = rtcb->group; int ret = EAGAIN; + DEBUGASSERT(group); + /* Check if we have exceeded the system-defined number of keys. */ - if (g_pthread_num_keys < PTHREAD_KEYS_MAX) + if (group->tg_nkeys < PTHREAD_KEYS_MAX) { /* Return the key value */ - *key = g_pthread_num_keys; + *key = group->tg_nkeys; /* Increment the count of global keys. */ - g_pthread_num_keys++; + group->tg_nkeys++; /* Return success. */ diff --git a/nuttx/sched/pthread_setspecific.c b/nuttx/sched/pthread_setspecific.c index 33fb4aeeb..8d32772ef 100644 --- a/nuttx/sched/pthread_setspecific.c +++ b/nuttx/sched/pthread_setspecific.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/pthread_setspecific.c * - * Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2007-2009, 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -41,7 +41,9 @@ #include <sched.h> #include <errno.h> +#include <assert.h> #include <debug.h> + #include "os_internal.h" #include "pthread_internal.h" @@ -114,11 +116,14 @@ int pthread_setspecific(pthread_key_t key, FAR void *value) { #if CONFIG_NPTHREAD_KEYS > 0 FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head; + FAR struct task_group_s *group = rtcb->group; int ret = EINVAL; + DEBUGASSERT(group); + /* Check if the key is valid. */ - if (key < g_pthread_num_keys) + if (key < group->tg_nkeys) { /* Store the data in the TCB. */ diff --git a/nuttx/sched/pthread_removejoininfo.c b/nuttx/sched/task_getgroup.c index defc02991..fc5bd166e 100644 --- a/nuttx/sched/pthread_removejoininfo.c +++ b/nuttx/sched/task_getgroup.c @@ -1,7 +1,7 @@ -/************************************************************************ - * sched/pthread_removejoininfo.c +/***************************************************************************** + * sched/task_getgroup.c * - * Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved. + * Copyright (C) 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt <gnutt@nuttx.org> * * Redistribution and use in source and binary forms, with or without @@ -31,107 +31,75 @@ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - ************************************************************************/ + *****************************************************************************/ -/************************************************************************ +/***************************************************************************** * Included Files - ************************************************************************/ + *****************************************************************************/ -#include <sys/types.h> -#include "pthread_internal.h" +#include <nuttx/config.h> -/************************************************************************ - * Definitions - ************************************************************************/ +#include <sched.h> -/************************************************************************ - * Private Type Declarations - ************************************************************************/ +#include "os_internal.h" +#include "group_internal.h" -/************************************************************************ - * Global Variables - ************************************************************************/ +#ifdef HAVE_TASK_GROUP -/************************************************************************ - * Private Variables - ************************************************************************/ +/***************************************************************************** + * Pre-processor Definitions + *****************************************************************************/ -/************************************************************************ +/***************************************************************************** + * Private Types + *****************************************************************************/ + +/***************************************************************************** + * Private Data + *****************************************************************************/ + +/***************************************************************************** + * Public Data + *****************************************************************************/ + +/***************************************************************************** * Private Functions - ************************************************************************/ + *****************************************************************************/ -/************************************************************************ +/***************************************************************************** * Public Functions - ************************************************************************/ + *****************************************************************************/ -/************************************************************************ - * Name: pthread_removejoininfo +/***************************************************************************** + * Name: task_getgroup * * Description: - * Remove a join_t from the local data set. + * Given a task ID, return the group structure of this task. * * Parameters: - * pid + * pid - The task ID to use in the lookup. * * Return Value: - * None or pointer to the found entry. + * On success, a pointer to the group task structure is returned. This + * function can fail only if there is no group that corresponds to the + * groupd ID. * * Assumptions: - * The caller has provided protection from re-entrancy. + * Called during when signally tasks in a safe context. No special + * precautions should be required here. However, extra care is taken when + * accessing the global g_grouphead list. * - ************************************************************************/ + *****************************************************************************/ -FAR join_t *pthread_removejoininfo(pid_t pid) +FAR struct task_group_s *task_getgroup(pid_t pid) { - FAR join_t *prev; - FAR join_t *join; - - /* Find the entry with the matching pid */ - - for (prev = NULL, join = g_pthread_head; - (join && (pid_t)join->thread != pid); - prev = join, join = join->next); - - /* Remove it from the data set. */ - - /* First check if this is the entry at the head of the list. */ - - if (join) + FAR _TCB *tcb = sched_gettcb(pid); + if (tcb) { - if (!prev) - { - /* Check if this is the only entry in the list */ - - if (!join->next) - { - g_pthread_head = NULL; - g_pthread_tail = NULL; - } - - /* Otherwise, remove it from the head of the list */ - - else - { - g_pthread_head = join->next; - } - } - - /* It is not at the head of the list, check if it is at the tail. */ - - else if (!join->next) - { - g_pthread_tail = prev; - prev->next = NULL; - } - - /* No, remove it from the middle of the list. */ - - else - { - prev->next = join->next; - } + return tcb->group; } - return join; + return NULL; } +#endif /* HAVE_TASK_GROUP */ diff --git a/nuttx/sched/task_spawn.c b/nuttx/sched/task_spawn.c index 61a835c91..ec6408df1 100644 --- a/nuttx/sched/task_spawn.c +++ b/nuttx/sched/task_spawn.c @@ -49,6 +49,14 @@ #include "spawn_internal.h" /**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_POSIX_SPAWN_PROXY_STACKSIZE +# define CONFIG_POSIX_SPAWN_PROXY_STACKSIZE 1024 +#endif + +/**************************************************************************** * Private Types ****************************************************************************/ |