提交 d82fe219 编写于 作者: H haotuo

Add getpid cached

Change-Id: I88b39f14aac0ab9c47982c90672de0d35386cbc2
Signed-off-by: Nhaotuo <haotuo@huawei.com>
上级 3f5c39b2
......@@ -1555,7 +1555,7 @@ if (musl_arch == "arm") {
"src/math/fmaf.c",
"src/math/sqrt.c",
"src/math/sqrtf.c",
"src/process/vfork.c",
"src/process/arm/fork.s",
"src/setjmp/longjmp.c",
"src/setjmp/setjmp.c",
"src/signal/restore.c",
......@@ -1647,7 +1647,7 @@ if (musl_arch == "arm") {
"src/math/sqrtf.c",
"src/math/sqrtl.c",
"src/math/truncl.c",
"src/process/vfork.c",
"src/process/x86_64/fork.s",
"src/setjmp/longjmp.c",
"src/setjmp/setjmp.c",
"src/signal/restore.c",
......@@ -2061,6 +2061,7 @@ musl_src_porting_file = [
"ldso/ns_config.h",
"ldso/strops.h",
"src/legacy/ulimit.c",
"src/linux/clone.c",
"src/linux/gettid.c",
"src/linux/reboot.c",
"src/linux/tgkill.c",
......@@ -2124,6 +2125,11 @@ musl_src_porting_file = [
"src/ldso/arm/dlvsym.s",
"src/ldso/riscv64/dlvsym.s",
"src/ldso/x86_64/dlvsym.s",
"src/unistd/getpid.c",
"src/process/fork.c",
"src/process/vfork.c",
"src/process/arm/__vfork.s",
"src/process/x86_64/__vfork.s",
]
musl_inc_hook_files = [
......
......@@ -19,7 +19,7 @@ int __init_tp(void *p)
if (r < 0) return -1;
if (!r) libc.can_do_threads = 1;
td->detach_state = DT_JOINABLE;
td->tid = __syscall(SYS_set_tid_address, &__thread_list_lock);
td->tid = td->cached_pid = __syscall(SYS_set_tid_address, &__thread_list_lock);
td->locale = &libc.global_locale;
td->robust_list.head = &td->robust_list.head;
td->sysinfo = __sysinfo;
......
......@@ -39,6 +39,7 @@ struct pthread {
/* Part 2 -- implementation details, non-ABI. */
int tid;
int cached_pid;
int errno_val;
volatile int detach_state;
volatile int cancel;
......
......@@ -48,19 +48,36 @@ int clone(int (*func)(void *), void *stack, int flags, void *arg, ...)
tls = va_arg(ap, void *);
ctid = va_arg(ap, pid_t *);
va_end(ap);
if (!(flags & (CLONE_VM | CLONE_VFORK)) && func) {
clone_args = (struct __clone_args *)malloc(sizeof(struct __clone_args));
if (clone_args == NULL) {
errno = ENOMEM;
return -1;
pthread_t self = __pthread_self();
pid_t parent_pid = self->cached_pid;
self->cached_pid = 0;
pid_t caller_tid = self->tid;
if (!(flags & (CLONE_VM | CLONE_VFORK))) {
self->tid = -1;
if (func) {
clone_args = (struct __clone_args *)malloc(sizeof(struct __clone_args));
if (clone_args == NULL) {
errno = ENOMEM;
return -1;
}
clone_args->func = clone_func;
clone_args->arg = arg;
clone_func = __start_child;
}
clone_args->func = clone_func;
clone_args->arg = arg;
clone_func = __start_child;
}
ret = __syscall_ret(__clone(clone_func, stack, flags, (void *)clone_args, ptid, tls, ctid));
if (!(flags & (CLONE_VM | CLONE_VFORK)) && func) {
free(clone_args);
}
if (ret != 0) {
self->cached_pid = parent_pid;
self->tid = caller_tid;
} else if (self->tid == -1) {
self->tid = __syscall(SYS_gettid);
self->cached_pid = self->tid;
}
return ret;
}
.syntax unified
.hidden __vfork
.type __vfork,%function
__vfork:
mov ip, r7
mov r7, 190
svc 0
mov r7, ip
.hidden __syscall_ret
b __syscall_ret
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include "syscall.h"
#include "libc.h"
#include "pthread_impl.h"
static void dummy(int x)
{
}
weak_alias(dummy, __fork_handler);
pid_t fork(void)
{
pid_t ret;
sigset_t set;
__fork_handler(-1);
__block_all_sigs(&set);
#ifdef SYS_fork
ret = __syscall(SYS_fork);
#else
ret = __syscall(SYS_clone, SIGCHLD, 0);
#endif
if (!ret) {
pthread_t self = __pthread_self();
self->tid = __syscall(SYS_gettid);
self->cached_pid = self->tid;
self->robust_list.off = 0;
self->robust_list.pending = 0;
self->next = self->prev = self;
__thread_list_lock = 0;
libc.threads_minus_1 = 0;
}
__restore_sigs(&set);
__fork_handler(!ret);
return __syscall_ret(ret);
}
#define _GNU_SOURCE
#include <unistd.h>
#include <signal.h>
#include "syscall.h"
#include "pthread_impl.h"
hidden pid_t __vfork(void)
{
/* vfork syscall cannot be made from C code */
#ifdef SYS_fork
return syscall(SYS_fork);
#else
return syscall(SYS_clone, SIGCHLD, 0);
#endif
}
pid_t vfork(void)
{
pthread_t self = __pthread_self();
pid_t parent_pid = self->cached_pid;
self->cached_pid = 0;
pid_t ret = __vfork();
if (ret != 0) {
self->cached_pid = parent_pid;
}
return ret;
}
.hidden __vfork
.type __vfork,@function
__vfork:
pop %rdx
mov $58,%eax
syscall
push %rdx
mov %rax,%rdi
.hidden __syscall_ret
jmp __syscall_ret
......@@ -10,6 +10,8 @@
#include <stddef.h>
#include <stdarg.h>
pid_t getpid(void);
void log_print(const char* info,...)
{
va_list ap;
......@@ -389,6 +391,7 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att
new->stack_size = stack - stack_limit;
new->guard_size = guard;
new->self = new;
new->cached_pid = getpid();
new->tsd = (void *)tsd;
new->locale = &libc.global_locale;
if (attr._a_detach) {
......@@ -424,7 +427,7 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att
__tl_lock();
libc.threads_minus_1++;
ret = __clone((c11 ? start_c11 : start), stack, flags, args, &new->tid, TP_ADJ(new), &__thread_list_lock);
ret = clone((c11 ? start_c11 : start), stack, flags, args, &new->tid, TP_ADJ(new), &__thread_list_lock);
/* All clone failures translate to EAGAIN. If explicit scheduling
* was requested, attempt it before unlocking the thread list so
......
#include <unistd.h>
#include "pthread_impl.h"
#include "syscall.h"
static pid_t __get_cached_pid()
{
return __pthread_self()->cached_pid;
}
pid_t getpid(void)
{
pid_t cached_pid = __get_cached_pid();
if (cached_pid != 0) {
return cached_pid;
}
return __syscall(SYS_getpid);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册