Deleted Added
full compact
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 ---