Skip to content

Commit 194f7ac

Browse files
committed
Updates for 1121 release for Windows
Make the 1121 release build on Windows. This is sufficient for getting a basic Hello World dispatch program to run under swift again.
1 parent aac4452 commit 194f7ac

17 files changed

+281
-51
lines changed

src/event/event_windows.c

Lines changed: 153 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,59 +21,197 @@
2121
#include "internal.h"
2222
#if DISPATCH_EVENT_BACKEND_WINDOWS
2323

24+
static HANDLE hPort = NULL;
25+
enum _dispatch_iocp_completion_key
26+
{
27+
DISPATCH_PORT_POKE = 0,
28+
DISPATCH_PORT_TIMER_CLOCK_UPTIME,
29+
};
30+
31+
typedef struct _dispatch_windows_timeout_s {
32+
PTP_TIMER pTimer;
33+
enum _dispatch_iocp_completion_key ullIdent;
34+
BOOL bArmed;
35+
} *dispatch_windows_timeout_t;
36+
37+
#define DISPATCH_WINDOWS_TIMEOUT_INITIALIZER(clock) \
38+
[DISPATCH_CLOCK_##clock] = { \
39+
.pTimer = NULL, \
40+
.ullIdent = DISPATCH_PORT_TIMER_CLOCK_##clock, \
41+
.bArmed = FALSE, \
42+
}
43+
static struct _dispatch_windows_timeout_s _dispatch_windows_timeout[] = {
44+
// DISPATCH_WINDOWS_TIMEOUT_INITIALIZER(WALL),
45+
DISPATCH_WINDOWS_TIMEOUT_INITIALIZER(UPTIME),
46+
// DISPATCH_WINDOWS_TIMEOUT_INITIALIZER(MONOTONIC),
47+
};
48+
49+
#pragma mark Helpers
50+
2451
#pragma mark dispatch_unote_t
2552

2653
bool
27-
_dispatch_unote_register(dispatch_unote_t du DISPATCH_UNUSED,
28-
dispatch_wlh_t wlh DISPATCH_UNUSED,
29-
dispatch_priority_t pri DISPATCH_UNUSED)
54+
_dispatch_unote_register_muxed(dispatch_unote_t du DISPATCH_UNUSED)
3055
{
3156
WIN_PORT_ERROR();
3257
return false;
3358
}
3459

3560
void
36-
_dispatch_unote_resume(dispatch_unote_t du DISPATCH_UNUSED)
61+
_dispatch_unote_resume_muxed(dispatch_unote_t du DISPATCH_UNUSED)
3762
{
3863
WIN_PORT_ERROR();
3964
}
4065

4166
bool
42-
_dispatch_unote_unregister(dispatch_unote_t du DISPATCH_UNUSED,
43-
uint32_t flags DISPATCH_UNUSED)
67+
_dispatch_unote_unregister_muxed(dispatch_unote_t du DISPATCH_UNUSED)
4468
{
4569
WIN_PORT_ERROR();
4670
return false;
4771
}
4872

4973
#pragma mark timers
5074

75+
static void CALLBACK
76+
_dispatch_timer_callback(PTP_CALLBACK_INSTANCE Instance, PVOID Context,
77+
PTP_TIMER Timer)
78+
{
79+
BOOL bSuccess;
80+
81+
bSuccess = PostQueuedCompletionStatus(hPort, 0, (ULONG_PTR)Context, NULL);
82+
if (bSuccess == FALSE)
83+
DISPATCH_INTERNAL_CRASH(GetLastError(), "PostQueuedCompletionStatus");
84+
}
85+
5186
void
52-
_dispatch_event_loop_timer_arm(uint32_t tidx DISPATCH_UNUSED,
53-
dispatch_timer_delay_s range DISPATCH_UNUSED,
87+
_dispatch_event_loop_timer_arm(dispatch_timer_heap_t dth DISPATCH_UNUSED,
88+
uint32_t tidx, dispatch_timer_delay_s range,
5489
dispatch_clock_now_cache_t nows DISPATCH_UNUSED)
5590
{
56-
WIN_PORT_ERROR();
91+
dispatch_windows_timeout_t timer;
92+
FILETIME ftDueTime;
93+
LARGE_INTEGER ulTime;
94+
95+
switch (DISPATCH_TIMER_CLOCK(tidx)) {
96+
case DISPATCH_CLOCK_UPTIME:
97+
timer = &_dispatch_windows_timeout[DISPATCH_CLOCK_UPTIME];
98+
ulTime.QuadPart = -((range.delay + 99) / 100);
99+
break;
100+
default:
101+
WIN_PORT_ERROR();
102+
__assume(0);
103+
}
104+
105+
if (timer->pTimer == NULL)
106+
{
107+
timer->pTimer = CreateThreadpoolTimer(_dispatch_timer_callback,
108+
(LPVOID)timer->ullIdent, NULL);
109+
if (timer->pTimer == NULL)
110+
DISPATCH_INTERNAL_CRASH(GetLastError(), "CreateThreadpoolTimer");
111+
}
112+
113+
ftDueTime.dwHighDateTime = ulTime.HighPart;
114+
ftDueTime.dwLowDateTime = ulTime.LowPart;
115+
116+
SetThreadpoolTimer(timer->pTimer, &ftDueTime, /*msPeriod=*/0,
117+
/*msWindowLength=*/0);
118+
timer->bArmed = TRUE;
57119
}
58120

59121
void
60-
_dispatch_event_loop_timer_delete(uint32_t tidx DISPATCH_UNUSED)
122+
_dispatch_event_loop_timer_delete(dispatch_timer_heap_t dth DISPATCH_UNUSED,
123+
uint32_t tidx)
61124
{
62-
WIN_PORT_ERROR();
125+
dispatch_windows_timeout_t timer;
126+
127+
switch (DISPATCH_TIMER_CLOCK(tidx)) {
128+
case DISPATCH_CLOCK_UPTIME:
129+
timer = &_dispatch_windows_timeout[DISPATCH_PORT_TIMER_CLOCK_UPTIME];
130+
break;
131+
default:
132+
WIN_PORT_ERROR();
133+
__assume(0);
134+
}
135+
136+
SetThreadpoolTimer(timer->pTimer, NULL, /*msPeriod=*/0,
137+
/*msWindowLength=*/0);
138+
timer->bArmed = FALSE;
63139
}
64140

65141
#pragma mark dispatch_loop
66142

143+
static void
144+
_dispatch_port_init(void *context DISPATCH_UNUSED)
145+
{
146+
hPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
147+
if (hPort == NULL) {
148+
DISPATCH_INTERNAL_CRASH(GetLastError(), "CreateIoCompletionPort");
149+
}
150+
151+
#if DISPATCH_USE_MGR_THREAD
152+
_dispatch_trace_item_push(_dispatch_mgr_q.do_targetq, &_dispatch_mgr_q);
153+
dx_push(_dispatch_mgr_q.do_targetq, &_dispatch_mgr_q, 0);
154+
#endif
155+
}
156+
67157
void
68158
_dispatch_event_loop_poke(dispatch_wlh_t wlh DISPATCH_UNUSED,
69159
uint64_t dq_state DISPATCH_UNUSED, uint32_t flags DISPATCH_UNUSED)
70160
{
71-
WIN_PORT_ERROR();
161+
static dispatch_once_t _dispatch_port_pred;
162+
dispatch_once_f(&_dispatch_port_pred, NULL, _dispatch_port_init);
163+
BOOL bResult = PostQueuedCompletionStatus(hPort, 0, DISPATCH_PORT_POKE,
164+
NULL);
165+
(void)dispatch_assume(bResult);
166+
}
167+
168+
static void
169+
_dispatch_event_merge_timer(dispatch_clock_t clock)
170+
{
171+
dispatch_timer_heap_t dth = _dispatch_timers_heap;
172+
uint32_t tidx = DISPATCH_TIMER_INDEX(clock, 0);
173+
174+
_dispatch_windows_timeout[clock].bArmed = FALSE;
175+
176+
_dispatch_timers_heap_dirty(dth, tidx);
177+
dth[tidx].dth_needs_program = true;
178+
dth[tidx].dth_armed = false;
72179
}
73180

74181
DISPATCH_NOINLINE
75182
void
76-
_dispatch_event_loop_drain(uint32_t flags DISPATCH_UNUSED)
183+
_dispatch_event_loop_drain(uint32_t flags)
184+
{
185+
DWORD dwNumberOfBytesTransferred;
186+
ULONG_PTR ulCompletionKey;
187+
LPOVERLAPPED pOV;
188+
189+
pOV = (LPOVERLAPPED)&pOV;
190+
BOOL bResult = GetQueuedCompletionStatus(hPort,
191+
&dwNumberOfBytesTransferred, &ulCompletionKey, &pOV,
192+
(flags & KEVENT_FLAG_IMMEDIATE) ? 0 : INFINITE);
193+
194+
while (bResult)
195+
{
196+
switch (ulCompletionKey)
197+
{
198+
case DISPATCH_PORT_POKE:
199+
break;
200+
case DISPATCH_PORT_TIMER_CLOCK_UPTIME:
201+
_dispatch_event_merge_timer(DISPATCH_CLOCK_UPTIME);
202+
break;
203+
}
204+
205+
bResult = GetQueuedCompletionStatus(hPort,
206+
&dwNumberOfBytesTransferred, &ulCompletionKey, &pOV, 0);
207+
}
208+
209+
if (bResult == FALSE && pOV != NULL)
210+
DISPATCH_INTERNAL_CRASH(GetLastError(), "GetQueuedCompletionStatus");
211+
}
212+
213+
void
214+
_dispatch_event_loop_cancel_waiter(dispatch_sync_context_t dsc DISPATCH_UNUSED)
77215
{
78216
WIN_PORT_ERROR();
79217
}
@@ -109,9 +247,9 @@ _dispatch_event_loop_assert_not_owned(dispatch_wlh_t wlh)
109247
#endif
110248

111249
void
112-
_dispatch_event_loop_leave_immediate(dispatch_wlh_t wlh, uint64_t dq_state)
250+
_dispatch_event_loop_leave_immediate(uint64_t dq_state)
113251
{
114-
(void)wlh; (void)dq_state;
252+
(void)dq_state;
115253
}
116254

117255
#endif // DISPATCH_EVENT_BACKEND_WINDOWS

src/event/workqueue.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ _dispatch_workq_worker_register(dispatch_queue_global_t root_q)
9797
_dispatch_unfair_lock_unlock(&mon->registered_tid_lock);
9898
#else
9999
(void)root_q;
100-
(void)cls;
101100
#endif // HAVE_DISPATCH_WORKQ_MONITORING
102101
}
103102

@@ -124,7 +123,6 @@ _dispatch_workq_worker_unregister(dispatch_queue_global_t root_q)
124123
_dispatch_unfair_lock_unlock(&mon->registered_tid_lock);
125124
#else
126125
(void)root_q;
127-
(void)cls;
128126
#endif // HAVE_DISPATCH_WORKQ_MONITORING
129127
}
130128

src/init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ DISPATCH_VTABLE_SUBCLASS_INSTANCE(queue_main, lane,
739739
.dq_push = _dispatch_main_queue_push,
740740
);
741741

742-
#if DISPATCH_COCOA_COMPAT
742+
#if DISPATCH_COCOA_COMPAT || defined(_WIN32)
743743
DISPATCH_VTABLE_SUBCLASS_INSTANCE(queue_runloop, lane,
744744
.do_type = DISPATCH_QUEUE_RUNLOOP_TYPE,
745745
.do_dispose = _dispatch_runloop_queue_dispose,

src/inline_internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1294,7 +1294,7 @@ _dispatch_queue_drain_try_lock_wlh(dispatch_queue_t dq, uint64_t *dq_state)
12941294
if (unlikely(!_dq_state_is_base_wlh(old_state) ||
12951295
!_dq_state_is_enqueued_on_target(old_state) ||
12961296
_dq_state_is_enqueued_on_manager(old_state))) {
1297-
#if !__LP64__
1297+
#if DISPATCH_SIZEOF_PTR == 4
12981298
old_state >>= 32;
12991299
#endif
13001300
DISPATCH_INTERNAL_CRASH(old_state, "Invalid wlh state");

src/io.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ enum {
152152
#endif // DISPATCH_IO_DEBUG
153153

154154
#define _dispatch_fd_debug(msg, fd, ...) \
155-
_dispatch_io_log("fd[0x%x]: " msg, fd, ##__VA_ARGS__)
155+
_dispatch_io_log("fd[0x%" PRIx64 "]: " msg, fd, ##__VA_ARGS__)
156156
#define _dispatch_op_debug(msg, op, ...) \
157157
_dispatch_io_log("op[%p]: " msg, op, ##__VA_ARGS__)
158158
#define _dispatch_channel_debug(msg, channel, ...) \
@@ -1385,7 +1385,7 @@ _dispatch_fd_entry_create_with_fd(dispatch_fd_t fd, uintptr_t hash)
13851385
// On fds lock queue
13861386
dispatch_fd_entry_t fd_entry = _dispatch_fd_entry_create(
13871387
_dispatch_io_fds_lockq);
1388-
_dispatch_fd_entry_debug("create: fd %d", fd_entry, fd);
1388+
_dispatch_fd_entry_debug("create: fd %" PRId64, fd_entry, fd);
13891389
fd_entry->fd = fd;
13901390
LIST_INSERT_HEAD(&_dispatch_io_fds[hash], fd_entry, fd_list);
13911391
fd_entry->barrier_queue = dispatch_queue_create(
@@ -1399,11 +1399,11 @@ _dispatch_fd_entry_create_with_fd(dispatch_fd_t fd, uintptr_t hash)
13991399
int result = ioctlsocket((SOCKET)fd, (long)FIONBIO, &value);
14001400
(void)dispatch_assume_zero(result);
14011401
_dispatch_stream_init(fd_entry,
1402-
_dispatch_get_root_queue(DISPATCH_QOS_DEFAULT, false));
1402+
_dispatch_get_default_queue(false));
14031403
} else {
14041404
dispatch_suspend(fd_entry->barrier_queue);
1405-
dispatch_once_f(&_dispatch_io_devs_lockq_pred, NULL,
1406-
_dispatch_io_devs_lockq_init);
1405+
dispatch_once_f(&_dispatch_io_init_pred, NULL,
1406+
_dispatch_io_queues_init);
14071407
dispatch_async(_dispatch_io_devs_lockq, ^{
14081408
_dispatch_disk_init(fd_entry, 0);
14091409
dispatch_resume(fd_entry->barrier_queue);

src/object.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,9 @@ _dispatch_xref_dispose(dispatch_object_t dou)
203203
break;
204204
#endif
205205
case DISPATCH_QUEUE_RUNLOOP_TYPE:
206+
#if DISPATCH_COCOA_COMPAT
206207
_dispatch_runloop_queue_xref_dispose(dou._dl);
208+
#endif
207209
break;
208210
}
209211
return _dispatch_release_tailcall(dou._os_obj);

0 commit comments

Comments
 (0)