Split the system-wide list of all futexes into process-specific lists
authorvisa <visa@openbsd.org>
Thu, 30 Aug 2018 03:30:25 +0000 (03:30 +0000)
committervisa <visa@openbsd.org>
Thu, 30 Aug 2018 03:30:25 +0000 (03:30 +0000)
of private futexes and a shared list of shared futexes. This speeds up
futex lookups.

Tested by and OK krw@
OK mpi@

sys/kern/kern_fork.c
sys/kern/sys_futex.c
sys/sys/proc.h

index c3bbe84..93d80d2 100644 (file)
@@ -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);
index e66d11d..8e0b1be 100644 (file)
@@ -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;
index c6858d1..8ee1c85 100644 (file)
@@ -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. */