cloudabi_futex.c (285908) | cloudabi_futex.c (286278) |
---|---|
1/*- 2 * Copyright (c) 2015 Nuxi, https://nuxi.nl/ 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 10 unchanged lines hidden (view full) --- 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2015 Nuxi, https://nuxi.nl/ 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 10 unchanged lines hidden (view full) --- 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 */ 25 26#include <sys/cdefs.h> |
27__FBSDID("$FreeBSD: head/sys/compat/cloudabi/cloudabi_futex.c 285908 2015-07-27 10:07:29Z ed $"); | 27__FBSDID("$FreeBSD: head/sys/compat/cloudabi/cloudabi_futex.c 286278 2015-08-04 06:02:03Z ed $"); |
28 29#include <sys/param.h> 30#include <sys/kernel.h> 31#include <sys/limits.h> 32#include <sys/lock.h> 33#include <sys/malloc.h> 34#include <sys/mutex.h> 35#include <sys/proc.h> 36#include <sys/sx.h> 37#include <sys/systm.h> | 28 29#include <sys/param.h> 30#include <sys/kernel.h> 31#include <sys/limits.h> 32#include <sys/lock.h> 33#include <sys/malloc.h> 34#include <sys/mutex.h> 35#include <sys/proc.h> 36#include <sys/sx.h> 37#include <sys/systm.h> |
38#include <sys/umtx.h> |
|
38 | 39 |
39#include <vm/vm.h> 40#include <vm/vm_param.h> 41#include <vm/pmap.h> 42#include <vm/vm_extern.h> 43#include <vm/vm_map.h> 44#include <vm/vm_object.h> 45 | |
46#include <compat/cloudabi/cloudabi_proto.h> 47#include <compat/cloudabi/cloudabi_syscalldefs.h> 48#include <compat/cloudabi/cloudabi_util.h> 49 50/* 51 * Futexes for CloudABI. 52 * 53 * On most systems, futexes are implemented as objects of a single type --- 46 unchanged lines hidden (view full) --- 100struct futex_address; 101struct futex_condvar; 102struct futex_lock; 103struct futex_queue; 104struct futex_waiter; 105 106/* Identifier of a location in memory. */ 107struct futex_address { | 40#include <compat/cloudabi/cloudabi_proto.h> 41#include <compat/cloudabi/cloudabi_syscalldefs.h> 42#include <compat/cloudabi/cloudabi_util.h> 43 44/* 45 * Futexes for CloudABI. 46 * 47 * On most systems, futexes are implemented as objects of a single type --- 46 unchanged lines hidden (view full) --- 94struct futex_address; 95struct futex_condvar; 96struct futex_lock; 97struct futex_queue; 98struct futex_waiter; 99 100/* Identifier of a location in memory. */ 101struct futex_address { |
108 /* For process-private objects: address space of the process. */ 109 struct vmspace * fa_vmspace; 110 /* For process-shared objects: VM object containing the object. */ 111 struct vm_object * fa_vmobject; 112 113 /* Memory address within address space or offset within VM object. */ 114 uintptr_t fa_offset; | 102 struct umtx_key fa_key; |
115}; 116 117/* A set of waiting threads. */ 118struct futex_queue { 119 STAILQ_HEAD(, futex_waiter) fq_list; 120 unsigned int fq_count; 121}; 122 --- 97 unchanged lines hidden (view full) --- 220/* 221 * futex_address operations. 222 */ 223 224static int 225futex_address_create(struct futex_address *fa, struct thread *td, 226 const void *object, cloudabi_mflags_t scope) 227{ | 103}; 104 105/* A set of waiting threads. */ 106struct futex_queue { 107 STAILQ_HEAD(, futex_waiter) fq_list; 108 unsigned int fq_count; 109}; 110 --- 97 unchanged lines hidden (view full) --- 208/* 209 * futex_address operations. 210 */ 211 212static int 213futex_address_create(struct futex_address *fa, struct thread *td, 214 const void *object, cloudabi_mflags_t scope) 215{ |
228 struct vmspace *vs; 229 struct vm_object *vo; 230 vm_map_t map; 231 vm_map_entry_t entry; 232 vm_pindex_t pindex; 233 vm_prot_t prot; 234 boolean_t wired; | |
235 | 216 |
236 /* 237 * Most of the time objects are stored in privately mapped 238 * anonymous memory. For these objects we wouldn't need to look 239 * up the corresponding VM object. The scope hint provided by 240 * userspace allows us to skip the VM map lookup for the common 241 * case. 242 * 243 * POSIX does permit enabling PTHREAD_PROCESS_SHARED on a lock 244 * stored in a private mapping, at the cost of additional 245 * performance overhead. Fall back to identifying the object by 246 * virtual memory address if the mapping isn't shared. 247 */ 248 vs = td->td_proc->p_vmspace; | 217 KASSERT(td == curthread, 218 ("Can only create umtx keys for the current thread")); |
249 switch (scope) { | 219 switch (scope) { |
250 case CLOUDABI_MAP_SHARED: 251 map = &vs->vm_map; 252 if (vm_map_lookup(&map, (vm_offset_t)object, 253 VM_PROT_COPY | VM_PROT_WRITE, &entry, &vo, &pindex, &prot, 254 &wired) != KERN_SUCCESS) 255 return (EFAULT); 256 257 if (entry->inheritance == VM_INHERIT_SHARE) { 258 /* 259 * Address corresponds to a shared mapping. 260 * Identify the address by its VM object. 261 */ 262 fa->fa_vmspace = NULL; 263 fa->fa_vmobject = vo; 264 vm_object_reference(vo); 265 fa->fa_offset = entry->offset - entry->start + 266 (vm_offset_t)object; 267 vm_map_lookup_done(map, entry); 268 return (0); 269 } 270 vm_map_lookup_done(map, entry); 271 /* FALLTHROUGH */ | |
272 case CLOUDABI_MAP_PRIVATE: | 220 case CLOUDABI_MAP_PRIVATE: |
273 /* 274 * Address corresponds to a private mapping. Never 275 * identify the address by its VM object, as shadow 276 * objects may get inserted if another thread forks. 277 * Simply use the VM space instead. 278 */ 279 fa->fa_vmspace = vs; 280 fa->fa_vmobject = NULL; 281 fa->fa_offset = (uintptr_t)object; 282 return (0); | 221 return (umtx_key_get(object, TYPE_FUTEX, THREAD_SHARE, 222 &fa->fa_key)); 223 case CLOUDABI_MAP_SHARED: 224 return (umtx_key_get(object, TYPE_FUTEX, AUTO_SHARE, 225 &fa->fa_key)); |
283 default: 284 return (EINVAL); 285 } 286} 287 288static void 289futex_address_free(struct futex_address *fa) 290{ 291 | 226 default: 227 return (EINVAL); 228 } 229} 230 231static void 232futex_address_free(struct futex_address *fa) 233{ 234 |
292 if (fa->fa_vmobject != NULL) 293 vm_object_deallocate(fa->fa_vmobject); | 235 umtx_key_release(&fa->fa_key); |
294} 295 296static bool 297futex_address_match(const struct futex_address *fa1, 298 const struct futex_address *fa2) 299{ 300 | 236} 237 238static bool 239futex_address_match(const struct futex_address *fa1, 240 const struct futex_address *fa2) 241{ 242 |
301 /* Either fa_vmspace or fa_vmobject is NULL. */ 302 return (fa1->fa_vmspace == fa2->fa_vmspace && 303 fa1->fa_vmobject == fa2->fa_vmobject && 304 fa1->fa_offset == fa2->fa_offset); | 243 return (umtx_key_match(&fa1->fa_key, &fa2->fa_key)); |
305} 306 307/* 308 * futex_condvar operations. 309 */ 310 311static void 312futex_condvar_assert(const struct futex_condvar *fc) --- 910 unchanged lines hidden --- | 244} 245 246/* 247 * futex_condvar operations. 248 */ 249 250static void 251futex_condvar_assert(const struct futex_condvar *fc) --- 910 unchanged lines hidden --- |