diff --git a/sched/Makefile b/sched/Makefile index 9f7c7ca477..f79387de7f 100644 --- a/sched/Makefile +++ b/sched/Makefile @@ -34,6 +34,7 @@ include semaphore/Make.defs include signal/Make.defs include task/Make.defs include timer/Make.defs +include tls/Make.defs include wdog/Make.defs include wqueue/Make.defs diff --git a/sched/pthread/pthread_create.c b/sched/pthread/pthread_create.c index 9bbabb6e97..66bde29ce9 100644 --- a/sched/pthread/pthread_create.c +++ b/sched/pthread/pthread_create.c @@ -40,12 +40,12 @@ #include #include #include -#include #include "sched/sched.h" #include "group/group.h" #include "clock/clock.h" #include "pthread/pthread.h" +#include "tls/tls.h" /**************************************************************************** * Public Data @@ -215,7 +215,6 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread, pthread_startroutine_t entry, pthread_addr_t arg) { FAR struct pthread_tcb_s *ptcb; - FAR struct tls_info_s *info; FAR struct join_s *pjoin; struct sched_param param; int policy; @@ -303,21 +302,13 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread, /* Initialize thread local storage */ - info = up_stack_frame(&ptcb->cmn, up_tls_size()); - if (info == NULL) + ret = tls_init_info(&ptcb->cmn); + if (ret != OK) { - errcode = ENOMEM; + errcode = -ret; goto errout_with_join; } - DEBUGASSERT(info == ptcb->cmn.stack_alloc_ptr); - - up_tls_initialize(info); - - /* Attach per-task info in group to TLS */ - - info->tl_task = ptcb->cmn.group->tg_info; - /* Should we use the priority and scheduler specified in the pthread * attributes? Or should we use the current thread's priority and * scheduler? diff --git a/sched/task/task_init.c b/sched/task/task_init.c index 270b858893..52bbdde774 100644 --- a/sched/task/task_init.c +++ b/sched/task/task_init.c @@ -33,12 +33,12 @@ #include #include -#include #include "sched/sched.h" #include "environ/environ.h" #include "group/group.h" #include "task/task.h" +#include "tls/tls.h" /**************************************************************************** * Public Functions @@ -88,7 +88,6 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority, FAR char * const envp[]) { uint8_t ttype = tcb->cmn.flags & TCB_FLAG_TTYPE_MASK; - FAR struct tls_info_s *info; int ret; #ifndef CONFIG_DISABLE_PTHREAD @@ -141,19 +140,12 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority, /* Initialize thread local storage */ - info = up_stack_frame(&tcb->cmn, up_tls_size()); - if (info == NULL) + ret = tls_init_info(&tcb->cmn); + if (ret < OK) { - ret = -ENOMEM; goto errout_with_group; } - DEBUGASSERT(info == tcb->cmn.stack_alloc_ptr); - - info->tl_task = tcb->cmn.group->tg_info; - - up_tls_initialize(info); - /* Initialize the task control block */ ret = nxtask_setup_scheduler(tcb, priority, nxtask_start, diff --git a/sched/task/task_vfork.c b/sched/task/task_vfork.c index f535614c62..a56f8c195d 100644 --- a/sched/task/task_vfork.c +++ b/sched/task/task_vfork.c @@ -40,6 +40,7 @@ #include "environ/environ.h" #include "group/group.h" #include "task/task.h" +#include "tls/tls.h" /* vfork() requires architecture-specific support as well as waipid(). */ @@ -97,7 +98,6 @@ FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr) FAR struct tcb_s *ptcb = this_task(); FAR struct tcb_s *parent; FAR struct task_tcb_s *child; - FAR struct tls_info_s *info; size_t stack_size; uint8_t ttype; int priority; @@ -181,19 +181,12 @@ FAR struct task_tcb_s *nxtask_setup_vfork(start_t retaddr) /* Setup thread local storage */ - info = up_stack_frame(&child->cmn, up_tls_size()); - if (info == NULL) + ret = tls_dup_info(&child->cmn, parent); + if (ret < OK) { - ret = -ENOMEM; goto errout_with_tcb; } - DEBUGASSERT(info == child->cmn.stack_alloc_ptr); - memcpy(info, parent->stack_alloc_ptr, sizeof(struct tls_info_s)); - info->tl_task = child->cmn.group->tg_info; - - up_tls_initialize(info); - /* Get the priority of the parent task */ #ifdef CONFIG_PRIORITY_INHERITANCE diff --git a/sched/tls/Make.defs b/sched/tls/Make.defs new file mode 100644 index 0000000000..10f81dcdef --- /dev/null +++ b/sched/tls/Make.defs @@ -0,0 +1,26 @@ +############################################################################ +# sched/tls/Make.defs +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +CSRCS += tls_initinfo.c tls_dupinfo.c + +# Include tls build support + +DEPPATH += --dep-path tls +VPATH += :tls diff --git a/sched/tls/tls.h b/sched/tls/tls.h new file mode 100644 index 0000000000..af04963d11 --- /dev/null +++ b/sched/tls/tls.h @@ -0,0 +1,67 @@ +/**************************************************************************** + * sched/tls/tls.h + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +#ifndef __SCHED_TLS_TLS_H +#define __SCHED_TLS_TLS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: tls_init_info + * + * Description: + * Allocate and initilize tls_info_s structure. + * + * Input Parameters: + * - tcb: The TCB of new task + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int tls_init_info(FAR struct tcb_s *tcb); + +/**************************************************************************** + * Name: tls_dup_info + * + * Description: + * Allocate and duplicate tls_info_s structure. + * + * Input Parameters: + * - dst: The TCB of new task + * - src: The TCB of source task + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int tls_dup_info(FAR struct tcb_s *dst, FAR struct tcb_s *src); + +#endif /* __SCHED_TLS_TLS_H */ diff --git a/sched/tls/tls_dupinfo.c b/sched/tls/tls_dupinfo.c new file mode 100644 index 0000000000..a22efd3d0c --- /dev/null +++ b/sched/tls/tls_dupinfo.c @@ -0,0 +1,75 @@ +/**************************************************************************** + * sched/tls/tls_dupinfo.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include + +#include +#include + +#include "tls.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tls_dup_info + * + * Description: + * Allocate and duplicate tls_info_s structure. + * + * Input Parameters: + * - dst: The TCB of new task + * - src: The TCB of source task + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int tls_dup_info(FAR struct tcb_s *dst, FAR struct tcb_s *src) +{ + FAR struct tls_info_s *info; + + /* Allocate thread local storage */ + + info = up_stack_frame(dst, up_tls_size()); + if (info == NULL) + { + return -ENOMEM; + } + + DEBUGASSERT(info == dst->stack_alloc_ptr); + + /* Copy thread local storage */ + + memcpy(info, src->stack_alloc_ptr, sizeof(struct tls_info_s)); + + /* Attach per-task info in group to TLS */ + + info->tl_task = dst->group->tg_info; + return OK; +} diff --git a/sched/tls/tls_initinfo.c b/sched/tls/tls_initinfo.c new file mode 100644 index 0000000000..0b7e08ab99 --- /dev/null +++ b/sched/tls/tls_initinfo.c @@ -0,0 +1,73 @@ +/**************************************************************************** + * sched/tls/tls_initinfo.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include + +#include "tls.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: tls_init_info + * + * Description: + * Allocate and initilize tls_info_s structure. + * + * Input Parameters: + * - tcb: The TCB of new task + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int tls_init_info(FAR struct tcb_s *tcb) +{ + FAR struct tls_info_s *info; + + /* Allocate thread local storage */ + + info = up_stack_frame(tcb, up_tls_size()); + if (info == NULL) + { + return -ENOMEM; + } + + DEBUGASSERT(info == tcb->stack_alloc_ptr); + + /* Initialize thread local storage */ + + up_tls_initialize(info); + + /* Attach per-task info in group to TLS */ + + info->tl_task = tcb->group->tg_info; + return OK; +}