From: visa Date: Thu, 30 Aug 2018 03:30:25 +0000 (+0000) Subject: Split the system-wide list of all futexes into process-specific lists X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=dbb9e73f5c4a3032c7e16db983dfa4f7c022e352;p=openbsd Split the system-wide list of all futexes into process-specific lists of private futexes and a shared list of shared futexes. This speeds up futex lookups. Tested by and OK krw@ OK mpi@ --- diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index c3bbe840d88..93d80d221ae 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_fork.c,v 1.206 2018/08/25 15:38:07 anton Exp $ */ +/* $OpenBSD: kern_fork.c,v 1.207 2018/08/30 03:30:25 visa Exp $ */ /* $NetBSD: kern_fork.c,v 1.29 1996/02/09 18:59:34 christos Exp $ */ /* @@ -206,6 +206,7 @@ process_initialize(struct process *pr, struct proc *p) KASSERT(p->p_ucred->cr_ref >= 2); /* new thread and new process */ LIST_INIT(&pr->ps_children); + LIST_INIT(&pr->ps_ftlist); LIST_INIT(&pr->ps_kqlist); timeout_set(&pr->ps_realit_to, realitexpire, pr); diff --git a/sys/kern/sys_futex.c b/sys/kern/sys_futex.c index e66d11dfdec..8e0b1be1af0 100644 --- a/sys/kern/sys_futex.c +++ b/sys/kern/sys_futex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_futex.c,v 1.8 2018/06/03 15:09:26 kettenis Exp $ */ +/* $OpenBSD: sys_futex.c,v 1.9 2018/08/30 03:30:25 visa Exp $ */ /* * Copyright (c) 2016-2017 Martin Pieuchot @@ -50,7 +50,6 @@ struct futex { TAILQ_HEAD(, proc) ft_threads; /* sleeping queue */ struct uvm_object *ft_obj; /* UVM object */ voff_t ft_off; /* UVM offset */ - pid_t ft_pid; /* process identifier */ unsigned int ft_refcnt; /* # of references */ }; @@ -67,12 +66,12 @@ struct futex *futex_get(uint32_t *, int); void futex_put(struct futex *); /* - * The global futex lock serialize futex(2) calls such that no wakeup - * event are lost, protect the global list of all futexes and their - * states. + * The global futex lock serializes futex(2) calls so that no wakeup + * event is lost, and protects all futex lists and futex states. */ struct rwlock ftlock = RWLOCK_INITIALIZER("futex"); -static LIST_HEAD(, futex) ftlist; +static struct futex_list ftlist_shared = + LIST_HEAD_INITIALIZER(ftlist_shared); struct pool ftpool; @@ -145,8 +144,8 @@ futex_get(uint32_t *uaddr, int flags) vm_map_entry_t entry; struct uvm_object *obj = NULL; voff_t off = (vaddr_t)uaddr; - pid_t pid = p->p_p->ps_pid; struct futex *f; + struct futex_list *ftlist = &p->p_p->ps_ftlist; rw_assert_wrlock(&ftlock); @@ -155,15 +154,15 @@ futex_get(uint32_t *uaddr, int flags) if (uvm_map_lookup_entry(map, (vaddr_t)uaddr, &entry) && UVM_ET_ISOBJ(entry) && entry->object.uvm_obj && entry->inheritance == MAP_INHERIT_SHARE) { + ftlist = &ftlist_shared; obj = entry->object.uvm_obj; off = entry->offset + ((vaddr_t)uaddr - entry->start); - pid = 0; } vm_map_unlock_read(map); } - LIST_FOREACH(f, &ftlist, ft_list) { - if (f->ft_obj == obj && f->ft_off == off && f->ft_pid == pid) { + LIST_FOREACH(f, ftlist, ft_list) { + if (f->ft_obj == obj && f->ft_off == off) { f->ft_refcnt++; break; } @@ -178,9 +177,8 @@ futex_get(uint32_t *uaddr, int flags) TAILQ_INIT(&f->ft_threads); f->ft_obj = obj; f->ft_off = off; - f->ft_pid = pid; f->ft_refcnt = 1; - LIST_INSERT_HEAD(&ftlist, f, ft_list); + LIST_INSERT_HEAD(ftlist, f, ft_list); } return f; diff --git a/sys/sys/proc.h b/sys/sys/proc.h index c6858d178f3..8ee1c853947 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.258 2018/08/27 15:57:39 anton Exp $ */ +/* $OpenBSD: proc.h,v 1.259 2018/08/30 03:30:25 visa Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -149,6 +149,8 @@ RBT_HEAD(unvname_rbt, unvname); * run-time information needed by threads. */ #ifdef __need_process +struct futex; +LIST_HEAD(futex_list, futex); struct unveil; struct process { /* @@ -174,6 +176,7 @@ struct process { struct vmspace *ps_vmspace; /* Address space */ pid_t ps_pid; /* Process identifier. */ + struct futex_list ps_ftlist; /* futexes attached to this process */ LIST_HEAD(, kqueue) ps_kqlist; /* kqueues attached to this process */ /* The following fields are all zeroed upon creation in process_new. */