Skip to content

Commit 57a1f4e

Browse files
authored
Merge pull request #559 from 3405691582/build
Support OpenBSD.
2 parents 34bc77c + 04ab2a4 commit 57a1f4e

20 files changed

+318
-46
lines changed

Diff for: cmake/modules/SwiftSupport.cmake

+6-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,12 @@ 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)
30+
elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "amd64|AMD64")
31+
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
32+
set("${result_var_name}" "x86_64" PARENT_SCOPE)
33+
else()
34+
set("${result_var_name}" "amd64" PARENT_SCOPE)
35+
endif()
3236
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "IA64")
3337
set("${result_var_name}" "itanium" PARENT_SCOPE)
3438
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86")

Diff for: private/private.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ void _dispatch_prohibit_transition_to_multithreaded(bool prohibit);
177177

178178
#if TARGET_OS_MAC
179179
#define DISPATCH_COCOA_COMPAT 1
180-
#elif defined(__linux__) || defined(__FreeBSD__) || defined(_WIN32)
180+
#elif defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(_WIN32)
181181
#define DISPATCH_COCOA_COMPAT 1
182182
#else
183183
#define DISPATCH_COCOA_COMPAT 0
@@ -191,6 +191,8 @@ void _dispatch_prohibit_transition_to_multithreaded(bool prohibit);
191191
typedef mach_port_t dispatch_runloop_handle_t;
192192
#elif defined(__linux__) || defined(__FreeBSD__)
193193
typedef int dispatch_runloop_handle_t;
194+
#elif defined(__unix__) && !defined(__linux__) && !defined(__FreeBSD__)
195+
typedef uint64_t dispatch_runloop_handle_t;
194196
#elif defined(_WIN32)
195197
typedef void *dispatch_runloop_handle_t;
196198
#else

Diff for: src/event/event.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,7 @@ static void
792792
_dispatch_timer_unote_disarm(dispatch_timer_source_refs_t dt,
793793
dispatch_timer_heap_t dth)
794794
{
795-
uint32_t tidx = dt->du_ident;
795+
uint32_t tidx = (uint32_t)dt->du_ident;
796796

797797
dispatch_assert(_dispatch_unote_armed(dt));
798798
_dispatch_timer_heap_remove(&dth[tidx], dt);

Diff for: src/event/event_internal.h

+2
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ _dispatch_timer_flags_from_clock(dispatch_clock_t clock)
125125

126126
#if defined(_WIN32)
127127
typedef uintptr_t dispatch_unote_ident_t;
128+
#elif defined(__OpenBSD__)
129+
typedef uintptr_t dispatch_unote_ident_t;
128130
#else
129131
typedef uint32_t dispatch_unote_ident_t;
130132
#endif

Diff for: src/event/event_kevent.c

+61-10
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,12 @@ _evfiltstr(short filt)
101101
_evfilt2(EVFILT_MACHPORT);
102102
_evfilt2(DISPATCH_EVFILT_MACH_NOTIFICATION);
103103
#endif
104+
#ifdef EVFILT_FS
104105
_evfilt2(EVFILT_FS);
106+
#endif
107+
#ifdef EVFILT_USER
105108
_evfilt2(EVFILT_USER);
109+
#endif
106110
#ifdef EVFILT_SOCK
107111
_evfilt2(EVFILT_SOCK);
108112
#endif
@@ -236,9 +240,9 @@ dispatch_kevent_debug(const char *verb, const dispatch_kevent_s *kev,
236240

237241
#define _dispatch_du_debug(what, du) \
238242
_dispatch_debug("kevent-source[%p]: %s kevent[%p] " \
239-
"{ filter = %s, ident = 0x%x }", \
243+
"{ filter = %s, ident = 0x%llx }", \
240244
_dispatch_wref2ptr((du)->du_owner_wref), what, \
241-
(du), _evfiltstr((du)->du_filter), (du)->du_ident)
245+
(du), _evfiltstr((du)->du_filter), (unsigned long long)(du)->du_ident)
242246

243247
#if DISPATCH_MACHPORT_DEBUG
244248
#ifndef MACH_PORT_TYPE_SPREQUEST
@@ -388,16 +392,18 @@ _dispatch_kevent_print_error(dispatch_kevent_t ke)
388392
switch (ke->data) {
389393
case 0:
390394
return;
395+
#if DISPATCH_USE_KEVENT_QOS
391396
case ERANGE: /* A broken QoS was passed to kevent_id() */
392397
DISPATCH_INTERNAL_CRASH(ke->qos, "Invalid kevent priority");
398+
#endif
393399
default:
394400
// log the unexpected error
395401
_dispatch_bug_kevent_client("kevent", _evfiltstr(ke->filter),
396402
!ke->udata ? NULL :
397403
ke->flags & EV_DELETE ? "delete" :
398404
ke->flags & EV_ADD ? "add" :
399405
ke->flags & EV_ENABLE ? "enable" : "monitor",
400-
(int)ke->data, ke->ident, ke->udata, du);
406+
(int)ke->data, ke->ident, (uint64_t)ke->udata, du);
401407
}
402408
}
403409

@@ -528,11 +534,22 @@ _dispatch_kevent_merge_muxed(dispatch_kevent_t ke)
528534
}
529535
}
530536

537+
/*
538+
* If the kevent implementation doesn't support EVFILT_USER for
539+
* signaling, then we use EVFILT_TIMER with EV_ONESHOT with this ident
540+
* to make do.
541+
*/
542+
#define DISPATCH_KEVENT_ERSATZ_EVFILT_USER_IDENT (~0ull << 9)
543+
531544
DISPATCH_NOINLINE
532545
static void
533546
_dispatch_kevent_drain(dispatch_kevent_t ke)
534547
{
548+
#ifdef EVFILT_USER
535549
if (ke->filter == EVFILT_USER) {
550+
#else
551+
if (ke->filter == EVFILT_TIMER && ke->ident == DISPATCH_KEVENT_ERSATZ_EVFILT_USER_IDENT) {
552+
#endif
536553
_dispatch_kevent_mgr_debug("received", ke);
537554
return;
538555
}
@@ -579,10 +596,17 @@ static void
579596
_dispatch_kq_create(intptr_t *fd_ptr)
580597
{
581598
static const dispatch_kevent_s kev = {
599+
#ifdef EVFILT_USER
582600
.ident = 1,
583601
.filter = EVFILT_USER,
584602
.flags = EV_ADD|EV_CLEAR,
585603
.udata = (dispatch_kevent_udata_t)DISPATCH_WLH_MANAGER,
604+
#else
605+
.ident = DISPATCH_KEVENT_ERSATZ_EVFILT_USER_IDENT,
606+
.filter = EVFILT_TIMER,
607+
.flags = EV_ADD|EV_DISABLE|EV_ONESHOT,
608+
.data = 1,
609+
#endif
586610
};
587611
int kqfd;
588612

@@ -591,7 +615,6 @@ _dispatch_kq_create(intptr_t *fd_ptr)
591615
guardid_t guard = (uintptr_t)fd_ptr;
592616
kqfd = guarded_kqueue_np(&guard, GUARD_CLOSE | GUARD_DUP);
593617
#else
594-
(void)guard_ptr;
595618
kqfd = kqueue();
596619
#endif
597620
if (kqfd == -1) {
@@ -743,7 +766,7 @@ _dispatch_kq_poll(dispatch_wlh_t wlh, dispatch_kevent_t ke, int n,
743766
switch (err) {
744767
case ENOMEM:
745768
_dispatch_temporary_resource_shortage();
746-
/* FALLTHROUGH */
769+
DISPATCH_FALLTHROUGH;
747770
case EINTR:
748771
goto retry;
749772
case EBADF:
@@ -754,7 +777,7 @@ _dispatch_kq_poll(dispatch_wlh_t wlh, dispatch_kevent_t ke, int n,
754777
(flags & KEVENT_FLAG_DYNAMIC_KQ_MUST_EXIST)) {
755778
return 0;
756779
}
757-
/* FALLTHROUGH */
780+
DISPATCH_FALLTHROUGH;
758781
#endif // DISPATCH_USE_KEVENT_WORKLOOP
759782
default:
760783
DISPATCH_CLIENT_CRASH(err, "Unexpected error from kevent");
@@ -786,9 +809,15 @@ _dispatch_kq_drain(dispatch_wlh_t wlh, dispatch_kevent_t ke, int n,
786809

787810
#if DISPATCH_DEBUG
788811
for (r = 0; r < n; r++) {
812+
#ifdef EVFILT_USER
789813
if (ke[r].filter != EVFILT_USER || DISPATCH_MGR_QUEUE_DEBUG) {
790814
_dispatch_kevent_debug_n(NULL, ke + r, r, n);
791815
}
816+
#else
817+
if (DISPATCH_MGR_QUEUE_DEBUG) {
818+
_dispatch_kevent_debug_n(NULL, ke + r, r, n);
819+
}
820+
#endif
792821
}
793822
#endif
794823

@@ -860,7 +889,6 @@ _dispatch_kq_unote_set_kevent(dispatch_unote_t _du, dispatch_kevent_t dk,
860889
du->du_priority),
861890
#endif
862891
};
863-
(void)pp; // if DISPATCH_USE_KEVENT_QOS == 0
864892
}
865893

866894
DISPATCH_ALWAYS_INLINE
@@ -921,9 +949,13 @@ _dispatch_kq_deferred_update(dispatch_wlh_t wlh, dispatch_kevent_t ke)
921949
ke->udata);
922950
dispatch_kevent_t dk = _dispatch_kq_deferred_reuse_slot(wlh, ddi, slot);
923951
*dk = *ke;
952+
#ifdef EVFILT_USER
924953
if (ke->filter != EVFILT_USER) {
925954
_dispatch_kevent_mgr_debug("deferred", ke);
926955
}
956+
#else
957+
_dispatch_kevent_mgr_debug("deferred", ke);
958+
#endif
927959
} else {
928960
_dispatch_kq_update_one(wlh, ke);
929961
}
@@ -985,6 +1017,7 @@ _dispatch_sync_ipc_handoff_end(dispatch_wlh_t wlh, mach_port_t port)
9851017
}
9861018
#endif
9871019

1020+
#if DISPATCH_HAVE_DIRECT_KNOTES
9881021
DISPATCH_NOINLINE
9891022
static bool
9901023
_dispatch_kq_unote_update(dispatch_wlh_t wlh, dispatch_unote_t _du,
@@ -1055,6 +1088,7 @@ _dispatch_kq_unote_update(dispatch_wlh_t wlh, dispatch_unote_t _du,
10551088
dispatch_assume_zero(r);
10561089
return true;
10571090
}
1091+
#endif
10581092

10591093
#pragma mark dispatch_muxnote_t
10601094

@@ -1283,6 +1317,7 @@ _dispatch_unote_unregister_direct(dispatch_unote_t du, uint32_t flags)
12831317
#pragma mark -
12841318
#pragma mark dispatch_event_loop
12851319

1320+
#if DISPATCH_USE_KEVENT_WORKLOOP
12861321
enum {
12871322
DISPATCH_WORKLOOP_ASYNC,
12881323
DISPATCH_WORKLOOP_ASYNC_FROM_SYNC,
@@ -1316,6 +1351,7 @@ static char const * const _dispatch_workloop_actions[] = {
13161351
[DISPATCH_WORKLOOP_SYNC_WAKE] = "sync-wake",
13171352
[DISPATCH_WORKLOOP_SYNC_END] = "sync-end",
13181353
};
1354+
#endif
13191355

13201356
void
13211357
_dispatch_event_loop_atfork_child(void)
@@ -1410,7 +1446,7 @@ _dispatch_kq_fill_workloop_event(dispatch_kevent_t ke, int which,
14101446
switch (which) {
14111447
case DISPATCH_WORKLOOP_ASYNC_FROM_SYNC:
14121448
fflags |= NOTE_WL_END_OWNERSHIP;
1413-
/* FALLTHROUGH */
1449+
DISPATCH_FALLTHROUGH;
14141450
case DISPATCH_WORKLOOP_ASYNC:
14151451
case DISPATCH_WORKLOOP_ASYNC_DISCOVER_SYNC:
14161452
case DISPATCH_WORKLOOP_ASYNC_QOS_UPDATE:
@@ -1434,10 +1470,10 @@ _dispatch_kq_fill_workloop_event(dispatch_kevent_t ke, int which,
14341470

14351471
case DISPATCH_WORKLOOP_ASYNC_LEAVE_FROM_SYNC:
14361472
fflags |= NOTE_WL_END_OWNERSHIP;
1437-
/* FALLTHROUGH */
1473+
DISPATCH_FALLTHROUGH;
14381474
case DISPATCH_WORKLOOP_ASYNC_LEAVE_FROM_TRANSFER:
14391475
fflags |= NOTE_WL_IGNORE_ESTALE;
1440-
/* FALLTHROUGH */
1476+
DISPATCH_FALLTHROUGH;
14411477
case DISPATCH_WORKLOOP_ASYNC_LEAVE:
14421478
dispatch_assert(!_dq_state_is_enqueued_on_target(dq_state));
14431479
action = EV_ADD | EV_DELETE | EV_ENABLE;
@@ -1881,10 +1917,17 @@ _dispatch_event_loop_poke(dispatch_wlh_t wlh, uint64_t dq_state, uint32_t flags)
18811917
{
18821918
if (wlh == DISPATCH_WLH_MANAGER) {
18831919
dispatch_kevent_s ke = (dispatch_kevent_s){
1920+
#ifdef EVFILT_USER
18841921
.ident = 1,
18851922
.filter = EVFILT_USER,
18861923
.fflags = NOTE_TRIGGER,
18871924
.udata = (dispatch_kevent_udata_t)DISPATCH_WLH_MANAGER,
1925+
#else
1926+
.ident = DISPATCH_KEVENT_ERSATZ_EVFILT_USER_IDENT,
1927+
.filter = EVFILT_TIMER,
1928+
.flags = EV_ADD|EV_ENABLE|EV_ONESHOT,
1929+
.data = 1
1930+
#endif
18881931
};
18891932
return _dispatch_kq_deferred_update(DISPATCH_WLH_ANON, &ke);
18901933
} else if (wlh && wlh != DISPATCH_WLH_ANON) {
@@ -2357,6 +2400,12 @@ _dispatch_event_loop_timer_arm(dispatch_timer_heap_t dth, uint32_t tidx,
23572400
target += range.leeway;
23582401
range.leeway = 0;
23592402
}
2403+
#if !NOTE_ABSOLUTE
2404+
target = range.delay;
2405+
#if defined(__OpenBSD__)
2406+
target /= 1000000;
2407+
#endif
2408+
#endif
23602409

23612410
_dispatch_event_loop_timer_program(dth, tidx, target, range.leeway,
23622411
EV_ADD | EV_ENABLE);
@@ -2445,6 +2494,7 @@ const dispatch_source_type_s _dispatch_source_type_vnode = {
24452494
.dst_merge_evt = _dispatch_source_merge_evt,
24462495
};
24472496

2497+
#ifdef EVFILT_FS
24482498
const dispatch_source_type_s _dispatch_source_type_vfs = {
24492499
.dst_kind = "vfs",
24502500
.dst_filter = EVFILT_FS,
@@ -2477,6 +2527,7 @@ const dispatch_source_type_s _dispatch_source_type_vfs = {
24772527
.dst_create = _dispatch_unote_create_without_handle,
24782528
.dst_merge_evt = _dispatch_source_merge_evt,
24792529
};
2530+
#endif
24802531

24812532
#ifdef EVFILT_SOCK
24822533
const dispatch_source_type_s _dispatch_source_type_sock = {

Diff for: src/event/workqueue.c

+46
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,52 @@ _dispatch_workq_count_runnable_workers(dispatch_workq_monitor_t mon)
247247

248248
_dispatch_unfair_lock_unlock(&mon->registered_tid_lock);
249249
}
250+
#elif defined(__OpenBSD__)
251+
#include <sys/param.h>
252+
#include <sys/sysctl.h>
253+
#include <sys/proc.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] = {0};
259+
size_t size, len;
260+
int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)getpid(), (int)sizeof(struct kinfo_proc), 0};
261+
if (sysctl(mib, 6, NULL, &size, NULL, 0) < 0) {
262+
_dispatch_debug("workq: Failed to sysctl1");
263+
return;
264+
}
265+
266+
size = size > sizeof(kp)? sizeof(kp): size;
267+
len = size / sizeof(struct kinfo_proc);
268+
mib[5] = (int)len;
269+
if (sysctl(mib, 6, kp, &size, NULL, 0) < 0) {
270+
_dispatch_debug("workq: Failed to sysctl2");
271+
return;
272+
}
273+
274+
int running_count = 0;
275+
276+
_dispatch_unfair_lock_lock(&mon->registered_tid_lock);
277+
278+
for (int i = 0; i < mon->num_registered_tids; i++) {
279+
dispatch_tid tid = mon->registered_tids[i];
280+
for (size_t j = 0; j < len; j++) {
281+
if ((dispatch_tid)kp[j].p_tid != tid) {
282+
continue;
283+
}
284+
285+
if (kp[j].p_stat == SRUN || kp[j].p_stat == SIDL || kp[j].p_stat == SONPROC) {
286+
running_count++;
287+
break;
288+
}
289+
}
290+
}
291+
292+
mon->num_runnable = running_count;
293+
294+
_dispatch_unfair_lock_unlock(&mon->registered_tid_lock);
295+
}
250296
#else
251297
#error must define _dispatch_workq_count_runnable_workers
252298
#endif

Diff for: src/event/workqueue_internal.h

+1-1
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(__OpenBSD__)
3434
#define HAVE_DISPATCH_WORKQ_MONITORING 1
3535
#else
3636
#define HAVE_DISPATCH_WORKQ_MONITORING 0

Diff for: src/init.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -964,7 +964,6 @@ _dispatch_continuation_get_function_symbol(dispatch_continuation_t dc)
964964
return dc->dc_func;
965965
}
966966

967-
#if HAVE_MACH
968967
void
969968
_dispatch_bug_kevent_client(const char *msg, const char *filter,
970969
const char *operation, int err, uint64_t ident, uint64_t udata,
@@ -1008,7 +1007,6 @@ _dispatch_bug_kevent_client(const char *msg, const char *filter,
10081007
msg, strerror(err), err, udata, filter, ident, ident, func);
10091008
}
10101009
}
1011-
#endif // HAVE_MACH
10121010

10131011
#if RDAR_49023449
10141012

@@ -1051,7 +1049,7 @@ _dispatch_bug_kevent_vanished(dispatch_unote_t du)
10511049
"{ %p[%s], ident: %" PRIdPTR " / 0x%" PRIxPTR ", handler: %p }",
10521050
dux_type(du._du)->dst_kind, dou._dq,
10531051
dou._dq->dq_label ? dou._dq->dq_label : "<unknown>",
1054-
du._du->du_ident, du._du->du_ident, func);
1052+
(intptr_t)du._du->du_ident, (uintptr_t)du._du->du_ident, func);
10551053
}
10561054

10571055
#endif // RDAR_49023449
@@ -1157,7 +1155,7 @@ _dispatch_logv_init(void *context DISPATCH_UNUSED)
11571155
#else
11581156
dprintf(dispatch_logfile, "=== log file opened for %s[%u] at "
11591157
"%ld.%06u ===\n", getprogname() ?: "", getpid(),
1160-
tv.tv_sec, (int)tv.tv_usec);
1158+
(long)tv.tv_sec, (int)tv.tv_usec);
11611159
#endif
11621160
}
11631161
}

0 commit comments

Comments
 (0)