sched/gettid: Move thread ID to TLS
There is no need for a gettid() syscall, as the thread ID is stable through the life of the process. It is safe to put a copy of TID to TLS. This way a user processes can access TID quickly via its own stack, instead of having to use an expensive syscall. Signed-off-by: Ville Juven <ville.juven@unikie.com>
This commit is contained in:
parent
b3567fe964
commit
04e760b1c2
10 changed files with 79 additions and 37 deletions
|
|
@ -223,6 +223,7 @@ struct tls_info_s
|
||||||
|
|
||||||
uint16_t tl_size; /* Actual size with alignments */
|
uint16_t tl_size; /* Actual size with alignments */
|
||||||
int tl_errno; /* Per-thread error number */
|
int tl_errno; /* Per-thread error number */
|
||||||
|
pid_t tl_tid; /* Thread ID */
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@
|
||||||
SYSCALL_LOOKUP1(_exit, 1)
|
SYSCALL_LOOKUP1(_exit, 1)
|
||||||
SYSCALL_LOOKUP(_assert, 4)
|
SYSCALL_LOOKUP(_assert, 4)
|
||||||
SYSCALL_LOOKUP(getpid, 0)
|
SYSCALL_LOOKUP(getpid, 0)
|
||||||
SYSCALL_LOOKUP(gettid, 0)
|
|
||||||
SYSCALL_LOOKUP(prctl, 2)
|
SYSCALL_LOOKUP(prctl, 2)
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_HAVE_PARENT
|
#ifdef CONFIG_SCHED_HAVE_PARENT
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@ set(SRCS
|
||||||
task_cancelpt.c
|
task_cancelpt.c
|
||||||
task_setcancelstate.c
|
task_setcancelstate.c
|
||||||
task_setcanceltype.c
|
task_setcanceltype.c
|
||||||
task_testcancel.c)
|
task_testcancel.c
|
||||||
|
task_gettid.c)
|
||||||
|
|
||||||
if(CONFIG_SMP)
|
if(CONFIG_SMP)
|
||||||
list(APPEND SRCS sched_cpucount.c)
|
list(APPEND SRCS sched_cpucount.c)
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
CSRCS += sched_getprioritymax.c sched_getprioritymin.c
|
CSRCS += sched_getprioritymax.c sched_getprioritymin.c
|
||||||
CSRCS += clock_getcpuclockid.c clock_getres.c
|
CSRCS += clock_getcpuclockid.c clock_getres.c
|
||||||
CSRCS += task_cancelpt.c task_setcancelstate.c task_setcanceltype.c
|
CSRCS += task_cancelpt.c task_setcancelstate.c task_setcanceltype.c
|
||||||
CSRCS += task_testcancel.c
|
CSRCS += task_testcancel.c task_gettid.c
|
||||||
|
|
||||||
ifeq ($(CONFIG_SMP),y)
|
ifeq ($(CONFIG_SMP),y)
|
||||||
CSRCS += sched_cpucount.c
|
CSRCS += sched_cpucount.c
|
||||||
|
|
|
||||||
56
libs/libc/sched/task_gettid.c
Normal file
56
libs/libc/sched/task_gettid.c
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
/****************************************************************************
|
||||||
|
* libs/libc/sched/task_gettid.c
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* 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 <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <nuttx/tls.h>
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Public Functions
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: gettid
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Get the thread ID of the currently executing thread.
|
||||||
|
*
|
||||||
|
* Input parameters:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* On success, returns the thread ID of the calling process.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
pid_t gettid(void)
|
||||||
|
{
|
||||||
|
FAR struct tls_info_s *tls = tls_get_info();
|
||||||
|
return tls->tl_tid;
|
||||||
|
}
|
||||||
|
|
@ -281,15 +281,6 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Initialize thread local storage */
|
|
||||||
|
|
||||||
ret = tls_init_info(&ptcb->cmn);
|
|
||||||
if (ret != OK)
|
|
||||||
{
|
|
||||||
errcode = -ret;
|
|
||||||
goto errout_with_tcb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Should we use the priority and scheduler specified in the pthread
|
/* Should we use the priority and scheduler specified in the pthread
|
||||||
* attributes? Or should we use the current thread's priority and
|
* attributes? Or should we use the current thread's priority and
|
||||||
* scheduler?
|
* scheduler?
|
||||||
|
|
@ -397,6 +388,15 @@ int nx_pthread_create(pthread_trampoline_t trampoline, FAR pthread_t *thread,
|
||||||
goto errout_with_tcb;
|
goto errout_with_tcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize thread local storage */
|
||||||
|
|
||||||
|
ret = tls_init_info(&ptcb->cmn);
|
||||||
|
if (ret != OK)
|
||||||
|
{
|
||||||
|
errcode = -ret;
|
||||||
|
goto errout_with_tcb;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
/* pthread_setup_scheduler() will set the affinity mask by inheriting the
|
/* pthread_setup_scheduler() will set the affinity mask by inheriting the
|
||||||
* setting from the parent task. We need to override this setting
|
* setting from the parent task. We need to override this setting
|
||||||
|
|
|
||||||
|
|
@ -91,22 +91,3 @@ pid_t nxsched_gettid(void)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: gettid
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Get the thread ID of the currently executing thread.
|
|
||||||
*
|
|
||||||
* Input parameters:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* On success, returns the thread ID of the calling process.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
pid_t gettid(void)
|
|
||||||
{
|
|
||||||
return nxsched_gettid();
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -168,18 +168,18 @@ int nxtask_init(FAR struct task_tcb_s *tcb, const char *name, int priority,
|
||||||
goto errout_with_group;
|
goto errout_with_group;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize thread local storage */
|
/* Initialize the task control block */
|
||||||
|
|
||||||
ret = tls_init_info(&tcb->cmn);
|
ret = nxtask_setup_scheduler(tcb, priority, nxtask_start,
|
||||||
|
entry, ttype);
|
||||||
if (ret < OK)
|
if (ret < OK)
|
||||||
{
|
{
|
||||||
goto errout_with_group;
|
goto errout_with_group;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the task control block */
|
/* Initialize thread local storage */
|
||||||
|
|
||||||
ret = nxtask_setup_scheduler(tcb, priority, nxtask_start,
|
ret = tls_init_info(&tcb->cmn);
|
||||||
entry, ttype);
|
|
||||||
if (ret < OK)
|
if (ret < OK)
|
||||||
{
|
{
|
||||||
goto errout_with_group;
|
goto errout_with_group;
|
||||||
|
|
|
||||||
|
|
@ -73,5 +73,10 @@ int tls_init_info(FAR struct tcb_s *tcb)
|
||||||
/* Attach per-task info in group to TLS */
|
/* Attach per-task info in group to TLS */
|
||||||
|
|
||||||
info->tl_task = tcb->group->tg_info;
|
info->tl_task = tcb->group->tg_info;
|
||||||
|
|
||||||
|
/* Thread ID */
|
||||||
|
|
||||||
|
info->tl_tid = tcb->pid;
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,6 @@
|
||||||
"getppid","unistd.h","defined(CONFIG_SCHED_HAVE_PARENT)","pid_t"
|
"getppid","unistd.h","defined(CONFIG_SCHED_HAVE_PARENT)","pid_t"
|
||||||
"getsockname","sys/socket.h","defined(CONFIG_NET)","int","int","FAR struct sockaddr *","FAR socklen_t *"
|
"getsockname","sys/socket.h","defined(CONFIG_NET)","int","int","FAR struct sockaddr *","FAR socklen_t *"
|
||||||
"getsockopt","sys/socket.h","defined(CONFIG_NET)","int","int","int","int","FAR void *","FAR socklen_t *"
|
"getsockopt","sys/socket.h","defined(CONFIG_NET)","int","int","int","int","FAR void *","FAR socklen_t *"
|
||||||
"gettid","unistd.h","","pid_t"
|
|
||||||
"gettimeofday","sys/time.h","","int","FAR struct timeval *","FAR struct timezone *"
|
"gettimeofday","sys/time.h","","int","FAR struct timeval *","FAR struct timezone *"
|
||||||
"getuid","unistd.h","defined(CONFIG_SCHED_USER_IDENTITY)","uid_t"
|
"getuid","unistd.h","defined(CONFIG_SCHED_USER_IDENTITY)","uid_t"
|
||||||
"inotify_add_watch","sys/inotify.h","defined(CONFIG_FS_NOTIFY)","int","int","FAR const char *","uint32_t"
|
"inotify_add_watch","sys/inotify.h","defined(CONFIG_FS_NOTIFY)","int","int","FAR const char *","uint32_t"
|
||||||
|
|
|
||||||
|
Can't render this file because it has a wrong number of fields in line 2.
|
Loading…
Add table
Reference in a new issue