]> git.saurik.com Git - apple/libplatform.git/blame - src/atomics/x86_64/OSAtomicFifo.c
libplatform-254.40.4.tar.gz
[apple/libplatform.git] / src / atomics / x86_64 / OSAtomicFifo.c
CommitLineData
442fbc9d
A
1#include <libkern/OSAtomic.h>
2#include <System/i386/cpu_capabilities.h>
3
4#define OS_UNFAIR_LOCK_INLINE 1
5#include "os/lock_private.h"
6
7typedef volatile struct {
8 void *first;
9 void *last;
10 os_unfair_lock lock;
11} __attribute__ ((aligned (16))) UnfairFifoQueueHead;
12
13#define set_next(element, offset, new) \
14 *((void**)(((uintptr_t)element) + offset)) = new;
15#define get_next(element, offset) \
16 *((void**)(((uintptr_t)element) + offset));
17
18// This is a naive implementation using unfair locks to support translated
19// x86_64 apps only. Native x86_64 and arm64 apps will use the
20// PFZ implementations
21void OSAtomicFifoEnqueue$VARIANT$UnfairLock(UnfairFifoQueueHead *list, void *new, size_t offset) {
22 set_next(new, offset, NULL);
23
24 os_unfair_lock_lock_inline(&list->lock);
25 if (list->last == NULL) {
26 list->first = new;
27 } else {
28 set_next(list->last, offset, new);
29 }
30 list->last = new;
31 os_unfair_lock_unlock_inline(&list->lock);
32}
33
34void* OSAtomicFifoDequeue$VARIANT$UnfairLock(UnfairFifoQueueHead *list, size_t offset) {
35 os_unfair_lock_lock_inline(&list->lock);
36 void *element = list->first;
37 if (element != NULL) {
38 void *next = get_next(element, offset);
39 if (next == NULL) {
40 list->last = NULL;
41 }
42 list->first = next;
43 }
44 os_unfair_lock_unlock_inline(&list->lock);
45
46 return element;
47}
48
49#define MakeResolver(name) \
50 void * name ## Resolver(void) __asm__("_" #name); \
51 void * name ## Resolver(void) { \
52 __asm__(".symbol_resolver _" #name); \
53 uint64_t capabilities = *(uint64_t*)_COMM_PAGE_CPU_CAPABILITIES64; \
54 if (capabilities & kIsTranslated) { \
55 return name ## $VARIANT$UnfairLock; \
56 } else { \
57 return name ## $VARIANT$PFZ; \
58 } \
59 }
60
61void OSAtomicFifoEnqueue$VARIANT$PFZ(OSFifoQueueHead *, void *, size_t);
62void* OSAtomicFifoDequeue$VARIANT$PFZ(OSFifoQueueHead *, size_t);
63
64MakeResolver(OSAtomicFifoEnqueue)
65MakeResolver(OSAtomicFifoDequeue)