diff options
author | Justus Winter <4winter@informatik.uni-hamburg.de> | 2013-11-23 16:12:55 +0100 |
---|---|---|
committer | Justus Winter <4winter@informatik.uni-hamburg.de> | 2015-04-07 14:23:36 +0200 |
commit | 4241dd5673566a61add85bd9eb52d4ae7db2750a (patch) | |
tree | 0c7ce8514067068a877d8181544c2870af1dac7d /libports/port-deref-deferred.h | |
parent | 785f4aea18b5705e63609001d2aa12871a774804 (diff) | |
download | hurd-4241dd5673566a61add85bd9eb52d4ae7db2750a.tar.gz hurd-4241dd5673566a61add85bd9eb52d4ae7db2750a.tar.bz2 hurd-4241dd5673566a61add85bd9eb52d4ae7db2750a.zip |
libports: use protected payloads to optimize the object lookup
* NEWS: Mention protected payloads.
* libports/Makefile (SRCS): Add `port-deref-deferred.c'.
* libports/create-internal.c (_ports_create_port_internal): Set the
protected payload to the objects address.
* libports/import-port.c (ports_import_port): Likewise.
* libports/reallocate-from-external.c (ports_reallocate_from_external):
Likewise.
* libports/reallocate-port.c (ports_reallocate_port): Likewise.
* libports/transfer-right.c (ports_transfer_right): Likewise.
* libports/manage-multithread.c (ports_manage_port_operations_multithread):
Use the protected payload for the object lookup if provided. Add
thread pool management calls.
* libports/manage-one-thread.c (ports_manage_port_operations_one_thread):
Likewise.
* libports/destroy-right.c (ports_destroy_right): Defer the
dereferencing of outstanding send rights to avoid a port_info
use-after-free.
* libports/port-deref-deferred.c: New file.
* libports/port-deref-deferred.h: Likewise.
* libports/ports.h (struct port_bucket): New field `threadpool'.
(ports_lookup_payload): Check `port_right'.
Diffstat (limited to 'libports/port-deref-deferred.h')
-rw-r--r-- | libports/port-deref-deferred.h | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/libports/port-deref-deferred.h b/libports/port-deref-deferred.h new file mode 100644 index 00000000..1589cb20 --- /dev/null +++ b/libports/port-deref-deferred.h @@ -0,0 +1,89 @@ +/* Delayed deallocation of port_info objects. + + Copyright (C) 2015 Free Software Foundation, Inc. + + Written by Justus Winter <4winter@informatik.uni-hamburg.de> + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the GNU Hurd. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef _HURD_PORTS_DEREF_DEFERRED_ +#define _HURD_PORTS_DEREF_DEFERRED_ + +#include <pthread.h> + +/* A list of port_info objects. */ +struct pi_list; + +/* We use protected payloads to look up objects without taking a lock. + A complication arises if we destroy an object using + ports_destroy_right. To avoid payloads from becoming stale (and + resulting in invalid memory accesses when being interpreted as + pointer), we delay the deallocation of those object until all + threads running at the time of the objects destruction are done + with whatever they were doing and entered a quiescent period. */ +struct ports_threadpool +{ + /* Access to the threadpool object is serialized by this lock. */ + pthread_spinlock_t lock; + + /* We maintain two sets of objects and threads. Each thread and the + threadpool itself has a color. If a thread has the same color as + the thread pool, it belongs to the old generation. */ + unsigned int color; + + /* The number of old threads. When an old thread enters its + quiescent period, it decrements OLD_THREADS and flips its color + (hence becoming a young thread). */ + size_t old_threads; + + /* A list of old objects. Once OLD_THREADS drops to zero, they are + deallocated, and all young threads and objects become old threads + and objects. */ + struct pi_list *old_objects; + + /* The number of young threads. Any thread joining or leaving the + thread group must be a young thread. */ + size_t young_threads; + + /* The list of young objects. Any object being marked for delayed + deallocation is added to this list. */ + struct pi_list *young_objects; +}; + +/* Per-thread state. */ +struct ports_thread +{ + unsigned int color; +}; + +/* Initialize the thread pool. */ +void _ports_threadpool_init (struct ports_threadpool *); + +/* Called by a thread to join a thread pool. */ +void _ports_thread_online (struct ports_threadpool *, struct ports_thread *); + +/* Called by a thread that enters its quiescent period. */ +void _ports_thread_quiescent (struct ports_threadpool *, struct ports_thread *); + +/* Called by a thread to leave a thread pool. */ +void _ports_thread_offline (struct ports_threadpool *, struct ports_thread *); + +struct port_info; + +/* Schedule an object for deallocation. */ +void _ports_port_deref_deferred (struct port_info *); + +#endif /* _HURD_PORTS_DEREF_DEFERRED_ */ |