Skip to content

Commit b55398e

Browse files
committed
fix freebsd build
1 parent 0d67182 commit b55398e

18 files changed

+182
-17
lines changed

cmake/modules/SwiftSupport.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ function(get_swift_host_arch result_var_name)
2727
set("${result_var_name}" "armv7" PARENT_SCOPE)
2828
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l")
2929
set("${result_var_name}" "armv7" PARENT_SCOPE)
30+
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "amd64")
31+
set("${result_var_name}" "x86_64" PARENT_SCOPE)
3032
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64")
3133
set("${result_var_name}" "x86_64" PARENT_SCOPE)
3234
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "IA64")

private/private.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,8 +189,10 @@ void _dispatch_prohibit_transition_to_multithreaded(bool prohibit);
189189

190190
#if TARGET_OS_MAC
191191
typedef mach_port_t dispatch_runloop_handle_t;
192-
#elif defined(__linux__) || defined(__FreeBSD__)
192+
#elif defined(__linux__)
193193
typedef int dispatch_runloop_handle_t;
194+
#elif defined(__FreeBSD__)
195+
typedef uint64_t dispatch_runloop_handle_t;
194196
#elif defined(_WIN32)
195197
typedef void *dispatch_runloop_handle_t;
196198
#else

src/event/event_kevent.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -389,15 +389,23 @@ _dispatch_kevent_print_error(dispatch_kevent_t ke)
389389
case 0:
390390
return;
391391
case ERANGE: /* A broken QoS was passed to kevent_id() */
392+
#if defined(__APPLE__)
392393
DISPATCH_INTERNAL_CRASH(ke->qos, "Invalid kevent priority");
394+
#else
395+
DISPATCH_INTERNAL_CRASH(0, "Invalid kevent priority");
396+
#endif
393397
default:
398+
#if HAVE_MACH
394399
// log the unexpected error
395400
_dispatch_bug_kevent_client("kevent", _evfiltstr(ke->filter),
396401
!ke->udata ? NULL :
397402
ke->flags & EV_DELETE ? "delete" :
398403
ke->flags & EV_ADD ? "add" :
399404
ke->flags & EV_ENABLE ? "enable" : "monitor",
400405
(int)ke->data, ke->ident, ke->udata, du);
406+
#else
407+
break;
408+
#endif
401409
}
402410
}
403411

@@ -591,7 +599,6 @@ _dispatch_kq_create(intptr_t *fd_ptr)
591599
guardid_t guard = (uintptr_t)fd_ptr;
592600
kqfd = guarded_kqueue_np(&guard, GUARD_CLOSE | GUARD_DUP);
593601
#else
594-
(void)guard_ptr;
595602
kqfd = kqueue();
596603
#endif
597604
if (kqfd == -1) {
@@ -743,7 +750,7 @@ _dispatch_kq_poll(dispatch_wlh_t wlh, dispatch_kevent_t ke, int n,
743750
switch (err) {
744751
case ENOMEM:
745752
_dispatch_temporary_resource_shortage();
746-
/* FALLTHROUGH */
753+
DISPATCH_FALLTHROUGH;
747754
case EINTR:
748755
goto retry;
749756
case EBADF:
@@ -754,7 +761,7 @@ _dispatch_kq_poll(dispatch_wlh_t wlh, dispatch_kevent_t ke, int n,
754761
(flags & KEVENT_FLAG_DYNAMIC_KQ_MUST_EXIST)) {
755762
return 0;
756763
}
757-
/* FALLTHROUGH */
764+
DISPATCH_FALLTHROUGH;
758765
#endif // DISPATCH_USE_KEVENT_WORKLOOP
759766
default:
760767
DISPATCH_CLIENT_CRASH(err, "Unexpected error from kevent");
@@ -860,7 +867,6 @@ _dispatch_kq_unote_set_kevent(dispatch_unote_t _du, dispatch_kevent_t dk,
860867
du->du_priority),
861868
#endif
862869
};
863-
(void)pp; // if DISPATCH_USE_KEVENT_QOS == 0
864870
}
865871

866872
DISPATCH_ALWAYS_INLINE
@@ -985,6 +991,7 @@ _dispatch_sync_ipc_handoff_end(dispatch_wlh_t wlh, mach_port_t port)
985991
}
986992
#endif
987993

994+
#if DISPATCH_HAVE_DIRECT_KNOTES
988995
DISPATCH_NOINLINE
989996
static bool
990997
_dispatch_kq_unote_update(dispatch_wlh_t wlh, dispatch_unote_t _du,
@@ -1055,6 +1062,7 @@ _dispatch_kq_unote_update(dispatch_wlh_t wlh, dispatch_unote_t _du,
10551062
dispatch_assume_zero(r);
10561063
return true;
10571064
}
1065+
#endif // DISPATCH_HAVE_DIRECT_KNOTES
10581066

10591067
#pragma mark dispatch_muxnote_t
10601068

@@ -1300,6 +1308,7 @@ enum {
13001308
DISPATCH_WORKLOOP_SYNC_END,
13011309
};
13021310

1311+
#if DISPATCH_USE_KEVENT_WORKLOOP
13031312
static char const * const _dispatch_workloop_actions[] = {
13041313
[DISPATCH_WORKLOOP_ASYNC] = "async",
13051314
[DISPATCH_WORKLOOP_ASYNC_FROM_SYNC] = "async (from sync)",
@@ -1316,6 +1325,7 @@ static char const * const _dispatch_workloop_actions[] = {
13161325
[DISPATCH_WORKLOOP_SYNC_WAKE] = "sync-wake",
13171326
[DISPATCH_WORKLOOP_SYNC_END] = "sync-end",
13181327
};
1328+
#endif // DISPATCH_USE_KEVENT_WORKLOOP
13191329

13201330
void
13211331
_dispatch_event_loop_atfork_child(void)

src/event/workqueue.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,51 @@ _dispatch_workq_count_runnable_workers(dispatch_workq_monitor_t mon)
247247

248248
_dispatch_unfair_lock_unlock(&mon->registered_tid_lock);
249249
}
250+
#elif defined(__FreeBSD__)
251+
#include <sys/sysctl.h>
252+
#include <sys/proc.h>
253+
#include <sys/user.h>
254+
255+
static void
256+
_dispatch_workq_count_runnable_workers(dispatch_workq_monitor_t mon)
257+
{
258+
struct kinfo_proc kp[WORKQ_MAX_TRACKED_TIDS];
259+
size_t size;
260+
int count, runners = 0;
261+
int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_INC_THREAD, (int)getpid()};
262+
263+
// get size we need
264+
if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0) {
265+
_dispatch_debug("workq: failed to get size for kinfo_proc[] from sysctll");
266+
return;
267+
}
268+
269+
// only care about up to WORKQ_MAX_TRACKED_TIDS threads
270+
size = size > sizeof(kp) ? sizeof(kp) : size;
271+
count = (int)(size / sizeof(struct kinfo_proc));
272+
273+
if (sysctl(mib, 4, kp, &size, NULL, 0) < 0) {
274+
_dispatch_debug("workq: failed to get kinfo_proc[] from sysctl");
275+
return;
276+
}
277+
278+
_dispatch_unfair_lock_lock(&mon->registered_tid_lock);
279+
280+
for (int i = 0; i < mon->num_registered_tids; ++i) {
281+
dispatch_tid tid = mon->registered_tids[i];
282+
for (int j = 0; i < count; ++i) {
283+
if ((dispatch_tid)kp[j].ki_tid != tid) { continue; }
284+
if (kp[j].ki_stat == SRUN || kp[j].ki_stat == SIDL) {
285+
++runners;
286+
break;
287+
}
288+
}
289+
}
290+
291+
mon->num_runnable = runners;
292+
293+
_dispatch_unfair_lock_unlock(&mon->registered_tid_lock);
294+
}
250295
#else
251296
#error must define _dispatch_workq_count_runnable_workers
252297
#endif

src/event/workqueue_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
void _dispatch_workq_worker_register(dispatch_queue_global_t root_q);
3131
void _dispatch_workq_worker_unregister(dispatch_queue_global_t root_q);
3232

33-
#if defined(__linux__) || defined(_WIN32)
33+
#if defined(__linux__) || defined(_WIN32) || defined(__FreeBSD__)
3434
#define HAVE_DISPATCH_WORKQ_MONITORING 1
3535
#else
3636
#define HAVE_DISPATCH_WORKQ_MONITORING 0

src/init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,7 @@ _dispatch_bug_kevent_vanished(dispatch_unote_t du)
10511051
"{ %p[%s], ident: %" PRIdPTR " / 0x%" PRIxPTR ", handler: %p }",
10521052
dux_type(du._du)->dst_kind, dou._dq,
10531053
dou._dq->dq_label ? dou._dq->dq_label : "<unknown>",
1054-
du._du->du_ident, du._du->du_ident, func);
1054+
(intptr_t)du._du->du_ident, (intptr_t)du._du->du_ident, func);
10551055
}
10561056

10571057
#endif // RDAR_49023449

src/internal.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,9 @@ upcast(dispatch_object_t dou)
277277
#include <sys/sysctl.h>
278278
#include <sys/queue.h>
279279
#endif
280+
#if defined(__FreeBSD__)
281+
#include <sys/eventfd.h>
282+
#endif // __FreeBSD__
280283
#include <sys/socket.h>
281284
#include <sys/time.h>
282285
#include <sys/mman.h>

src/io.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
#if defined(__FreeBSD__)
2424
#include <fcntl.h>
25-
#define F_RDADVISE F_RDAHEAD
2625
#endif
2726

2827
#ifndef DISPATCH_IO_DEBUG

src/queue.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6474,6 +6474,8 @@ _dispatch_runloop_handle_is_valid(dispatch_runloop_handle_t handle)
64746474
return MACH_PORT_VALID(handle);
64756475
#elif defined(__linux__)
64766476
return handle >= 0;
6477+
#elif defined(__FreeBSD__)
6478+
return handle > 0;
64776479
#elif defined(_WIN32)
64786480
return handle != NULL;
64796481
#else
@@ -6490,6 +6492,8 @@ _dispatch_runloop_queue_get_handle(dispatch_lane_t dq)
64906492
#elif defined(__linux__)
64916493
// decode: 0 is a valid fd, so offset by 1 to distinguish from NULL
64926494
return ((dispatch_runloop_handle_t)(uintptr_t)dq->do_ctxt) - 1;
6495+
#elif defined(__FreeBSD__)
6496+
return (dispatch_runloop_handle_t)(uintptr_t)dq->do_ctxt;
64936497
#elif defined(_WIN32)
64946498
return ((dispatch_runloop_handle_t)(uintptr_t)dq->do_ctxt);
64956499
#else
@@ -6507,13 +6511,21 @@ _dispatch_runloop_queue_set_handle(dispatch_lane_t dq,
65076511
#elif defined(__linux__)
65086512
// encode: 0 is a valid fd, so offset by 1 to distinguish from NULL
65096513
dq->do_ctxt = (void *)(uintptr_t)(handle + 1);
6514+
#elif defined(__FreeBSD__)
6515+
dq->do_ctxt = (void *)(uintptr_t)handle;
65106516
#elif defined(_WIN32)
65116517
dq->do_ctxt = (void *)(uintptr_t)handle;
65126518
#else
65136519
#error "runloop support not implemented on this platform"
65146520
#endif
65156521
}
65166522

6523+
#if defined(__unix__)
6524+
#define DISPATCH_RUNLOOP_HANDLE_PACK(rfd, wfd) (((uint64_t)(rfd) << 32) | (wfd))
6525+
#define DISPATCH_RUNLOOP_HANDLE_RFD(h) ((int)((h) >> 32))
6526+
#define DISPATCH_RUNLOOP_HANDLE_WFD(h) ((int)((h) & 0xffffffff))
6527+
#endif
6528+
65176529
static void
65186530
_dispatch_runloop_queue_handle_init(void *ctxt)
65196531
{
@@ -6563,6 +6575,14 @@ _dispatch_runloop_queue_handle_init(void *ctxt)
65636575
}
65646576
}
65656577
handle = fd;
6578+
#elif defined(__unix__) && !defined(__linux__)
6579+
int fds[2];
6580+
int r = pipe2(fds, O_CLOEXEC | O_NONBLOCK);
6581+
if (r == -1) {
6582+
DISPATCH_CLIENT_CRASH(errno, "pipe2 failure");
6583+
}
6584+
uint32_t rfd = (uint32_t)fds[0], wfd = (uint32_t)fds[1];
6585+
handle = DISPATCH_RUNLOOP_HANDLE_PACK(rfd, wfd);
65666586
#elif defined(_WIN32)
65676587
HANDLE hEvent;
65686588
hEvent = CreateEventW(NULL, /*bManualReset=*/FALSE,
@@ -6597,6 +6617,11 @@ _dispatch_runloop_queue_handle_dispose(dispatch_lane_t dq)
65976617
#elif defined(__linux__)
65986618
int rc = close(handle);
65996619
(void)dispatch_assume_zero(rc);
6620+
#elif defined(__unix__) && !defined(__linux__)
6621+
int rc = close(DISPATCH_RUNLOOP_HANDLE_WFD(handle));
6622+
(void)dispatch_assume_zero(rc);
6623+
rc = close(DISPATCH_RUNLOOP_HANDLE_RFD(handle));
6624+
(void)dispatch_assume_zero(rc);
66006625
#elif defined(_WIN32)
66016626
BOOL bSuccess;
66026627
bSuccess = CloseHandle(handle);
@@ -6633,6 +6658,13 @@ _dispatch_runloop_queue_class_poke(dispatch_lane_t dq)
66336658
result = eventfd_write(handle, 1);
66346659
} while (result == -1 && errno == EINTR);
66356660
(void)dispatch_assume_zero(result);
6661+
#elif defined(__unix__) && !defined(__linux__)
6662+
int wfd = DISPATCH_RUNLOOP_HANDLE_WFD(handle);
6663+
ssize_t result;
6664+
do {
6665+
result = write(wfd, "x", 1);
6666+
} while (result == -1 && errno == EINTR);
6667+
(void)dispatch_assume_zero(result - 1);
66366668
#elif defined(_WIN32)
66376669
BOOL bSuccess;
66386670
bSuccess = SetEvent(handle);

src/shims/lock.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,21 @@ _dispatch_thread_switch(dispatch_lock value, dispatch_lock_options_t flags,
5656
#endif
5757
#endif
5858

59+
#if defined(__FreeBSD__)
60+
#if !HAVE_UL_UNFAIR_LOCK
61+
DISPATCH_ALWAYS_INLINE
62+
static inline void
63+
_dispatch_thread_switch(dispatch_lock value, dispatch_lock_options_t flags,
64+
uint32_t timeout)
65+
{
66+
(void)value;
67+
(void)flags;
68+
(void)timeout;
69+
sched_yield();
70+
}
71+
#endif
72+
#endif
73+
5974
#pragma mark - semaphores
6075

6176
#if USE_MACH_SEM
@@ -516,6 +531,16 @@ _dispatch_wait_on_address(uint32_t volatile *_address, uint32_t value,
516531
? INFINITE : ((nsecs + 1000000) / 1000000);
517532
if (dwMilliseconds == 0) return ETIMEDOUT;
518533
return WaitOnAddress(address, &value, sizeof(value), dwMilliseconds) == TRUE;
534+
#elif defined(__FreeBSD__)
535+
(void)flags;
536+
if (nsecs != DISPATCH_TIME_FOREVER) {
537+
struct timespec ts = {
538+
.tv_sec = (__typeof__(ts.tv_sec))(nsecs / NSEC_PER_SEC),
539+
.tv_nsec = (__typeof__(ts.tv_nsec))(nsecs % NSEC_PER_SEC),
540+
};
541+
return _umtx_op((void*)address, UMTX_OP_WAIT_UINT, value, (void*)(uintptr_t)sizeof(struct timespec), (void*)&ts);
542+
}
543+
return _umtx_op((void*)address, UMTX_OP_WAIT_UINT, value, 0, 0);
519544
#else
520545
#error _dispatch_wait_on_address unimplemented for this platform
521546
#endif
@@ -530,6 +555,8 @@ _dispatch_wake_by_address(uint32_t volatile *address)
530555
_dispatch_futex_wake((uint32_t *)address, INT_MAX, FUTEX_PRIVATE_FLAG);
531556
#elif defined(_WIN32)
532557
WakeByAddressAll((uint32_t *)address);
558+
#elif defined(__FreeBSD__)
559+
_umtx_op((void*)address, UMTX_OP_WAKE, INT_MAX, 0, 0);
533560
#else
534561
(void)address;
535562
#endif
@@ -689,7 +716,7 @@ _dispatch_once_wait(dispatch_once_gate_t dgo)
689716
_dispatch_futex_wait(lock, (dispatch_lock)new_v, NULL,
690717
FUTEX_PRIVATE_FLAG);
691718
#else
692-
_dispatch_thread_switch(new_v, 0, timeout++);
719+
_dispatch_thread_switch((dispatch_lock)new_v, 0, timeout++);
693720
#endif
694721
(void)timeout;
695722
}

src/shims/lock.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,28 @@ _dispatch_lock_owner(dispatch_lock lock_value)
7979
return lock_value & DLOCK_OWNER_MASK;
8080
}
8181

82+
#elif defined(__FreeBSD__)
83+
84+
#include <sys/types.h>
85+
#include <sys/umtx.h>
86+
#include <sched.h>
87+
88+
typedef uint32_t dispatch_tid;
89+
typedef uint32_t dispatch_lock;
90+
91+
#define DLOCK_OWNER_NULL ((dispatch_tid)0)
92+
#define DLOCK_OWNER_MASK ((dispatch_lock)0xfffffffc)
93+
#define DLOCK_WAITERS_BIT ((dispatch_lock)0x00000001)
94+
#define DLOCK_FAILED_TRYLOCK_BIT ((dispatch_lock)0x00000002)
95+
#define _dispatch_tid_self() ((dispatch_tid)(_dispatch_get_tsd_base()->tid << 2))
96+
97+
DISPATCH_ALWAYS_INLINE
98+
static inline dispatch_tid
99+
_dispatch_lock_owner(dispatch_lock lock_value)
100+
{
101+
return lock_value & DLOCK_OWNER_MASK;
102+
}
103+
82104
#elif defined(_WIN32)
83105

84106
#include <Windows.h>

0 commit comments

Comments
 (0)