Skip to content

Commit 236649a

Browse files
committed
revive the Windows port
The `DISPATCH_EXPORT` macro added an extraneous `extern` on the declaration. This was pointed out by a newer clang. Adjust the declaration accordingly. Add build rules to improve Windows builds. These additions help cross-compile to Windows with both clang-cl as well as the GNU clang driver. Use the newer Windows APIs to detect the windows CPU state. This allows us to collect all of the CPU configuration information to properly affinitise work to the preferred CPU. Use the FLS API to create thread local data storage for libdispatch's queues.
1 parent 698220e commit 236649a

29 files changed

+480
-94
lines changed

CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ project(dispatch
88
LANGUAGES C CXX)
99
enable_testing()
1010

11+
if("${CMAKE_C_SIMULATE_ID}" STREQUAL "MSVC")
12+
include(ClangClCompileRules)
13+
endif()
14+
1115
set(CMAKE_C_STANDARD 11)
1216
set(CMAKE_C_STANDARD_REQUIRED YES)
1317

@@ -322,6 +326,13 @@ configure_file("${CMAKE_SOURCE_DIR}/cmake/config.h.in"
322326
"${CMAKE_BINARY_DIR}/config/config_ac.h")
323327
add_definitions(-DHAVE_CONFIG_H)
324328

329+
if(CMAKE_SYSTEM_NAME STREQUAL Windows)
330+
include(DispatchWindowsSupport)
331+
dispatch_windows_arch_spelling(${CMAKE_SYSTEM_PROCESSOR} DISPATCH_MSVC_ARCH)
332+
dispatch_windows_include_for_arch(${DISPATCH_MSVC_ARCH} DISPATCH_INCLUDES)
333+
include_directories(BEFORE SYSTEM ${DISPATCH_INCLUDES})
334+
endif()
335+
325336
add_subdirectory(dispatch)
326337
add_subdirectory(man)
327338
add_subdirectory(os)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
# clang-cl interprets paths starting with /U as macro undefines, so we need to
3+
# put a -- before the input file path to force it to be treated as a path.
4+
string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_C_COMPILE_OBJECT "${CMAKE_C_COMPILE_OBJECT}")
5+
string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_CXX_COMPILE_OBJECT "${CMAKE_CXX_COMPILE_OBJECT}")
6+
7+
set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
8+
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
2+
function(dispatch_windows_arch_spelling arch var)
3+
if(${arch} STREQUAL i686)
4+
set(${var} x86 PARENT_SCOPE)
5+
elseif(${arch} STREQUAL x86_64)
6+
set(${var} x64 PARENT_SCOPE)
7+
elseif(${arch} STREQUAL armv7)
8+
set(${var} arm PARENT_SCOPE)
9+
elseif(${arch} STREQUAL aarch64)
10+
set(${var} arm64 PARENT_SCOPE)
11+
else()
12+
message(FATAL_ERROR "do not know MSVC spelling for ARCH: `${arch}`")
13+
endif()
14+
endfunction()
15+
16+
function(dispatch_verify_windows_environment_variables)
17+
set(VCToolsInstallDir $ENV{VCToolsInstallDir})
18+
set(UniversalCRTSdkDir $ENV{UniversalCRTSdkDir})
19+
set(UCRTVersion $ENV{UCRTVersion})
20+
21+
if("${VCToolsInstallDir}" STREQUAL "")
22+
message(SEND_ERROR "VCToolsInstallDir environment variable must be set")
23+
endif()
24+
if("${UniversalCRTSdkDir}" STREQUAL "")
25+
message(SEND_ERROR "UniversalCRTSdkDir environment variable must be set")
26+
endif()
27+
if("${UCRTVersion}" STREQUAL "")
28+
message(SEND_ERROR "UCRTVersion environment variable must be set")
29+
endif()
30+
endfunction()
31+
32+
function(dispatch_windows_include_for_arch arch var)
33+
dispatch_verify_windows_environment_variables()
34+
35+
set(paths
36+
"$ENV{VCToolsInstallDir}/include"
37+
"$ENV{UniversalCRTSdkDir}/Include/$ENV{UCRTVersion}/ucrt"
38+
"$ENV{UniversalCRTSdkDir}/Include/$ENV{UCRTVersion}/shared"
39+
"$ENV{UniversalCRTSdkDir}/Include/$ENV{UCRTVersion}/um")
40+
set(${var} ${paths} PARENT_SCOPE)
41+
endfunction()
42+
43+
function(dispatch_windows_lib_for_arch arch var)
44+
dispatch_verify_windows_environment_variables()
45+
dispatch_windows_arch_spelling(${arch} ARCH)
46+
47+
set(paths)
48+
if(${ARCH} STREQUAL x86)
49+
list(APPEND paths "$ENV{VCToolsInstallDir}/Lib")
50+
else()
51+
list(APPEND paths "$ENV{VCToolsInstallDir}/Lib/${ARCH}")
52+
endif()
53+
list(APPEND paths
54+
"$ENV{UniversalCRTSdkDir}/Lib/$ENV{UCRTVersion}/ucrt/${ARCH}"
55+
"$ENV{UniversalCRTSdkDir}/Lib/$ENV{UCRTVersion}/um/${ARCH}")
56+
set(${var} ${paths} PARENT_SCOPE)
57+
endfunction()
58+
59+
function(dispatch_windows_generate_sdk_vfs_overlay flags)
60+
dispatch_verify_windows_environment_variables()
61+
62+
get_filename_component(VCToolsInstallDir $ENV{VCToolsInstallDir} ABSOLUTE)
63+
get_filename_component(UniversalCRTSdkDir $ENV{UniversalCRTSdkDir} ABSOLUTE)
64+
set(UCRTVersion $ENV{UCRTVersion})
65+
66+
# TODO(compnerd) use a target to avoid re-creating this file all the time
67+
configure_file("${CMAKE_SOURCE_DIR}/utils/WindowsSDKVFSOverlay.yaml.in"
68+
"${CMAKE_BINARY_DIR}/windows-sdk-vfs-overlay.yaml"
69+
@ONLY)
70+
71+
set(${flags}
72+
-ivfsoverlay;"${CMAKE_BINARY_DIR}/windows-sdk-vfs-overlay.yaml"
73+
PARENT_SCOPE)
74+
endfunction()

dispatch/base.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,11 @@
130130

131131
#if TARGET_OS_WIN32 && defined(__DISPATCH_BUILDING_DISPATCH__) && \
132132
defined(__cplusplus)
133-
#define DISPATCH_EXPORT extern "C" extern __declspec(dllexport)
133+
#define DISPATCH_EXPORT extern "C" __declspec(dllexport)
134134
#elif TARGET_OS_WIN32 && defined(__DISPATCH_BUILDING_DISPATCH__)
135135
#define DISPATCH_EXPORT extern __declspec(dllexport)
136136
#elif TARGET_OS_WIN32 && defined(__cplusplus)
137-
#define DISPATCH_EXPORT extern "C" extern __declspec(dllimport)
137+
#define DISPATCH_EXPORT extern "C" __declspec(dllimport)
138138
#elif TARGET_OS_WIN32
139139
#define DISPATCH_EXPORT extern __declspec(dllimport)
140140
#elif __GNUC__

dispatch/data.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,10 @@ DISPATCH_EXPORT struct dispatch_data_s _dispatch_data_empty;
6262
#define DISPATCH_DATA_DESTRUCTOR_DEFAULT NULL
6363

6464
#ifdef __BLOCKS__
65-
#if !TARGET_OS_WIN32
6665
/*! @parseOnly */
6766
#define DISPATCH_DATA_DESTRUCTOR_TYPE_DECL(name) \
6867
DISPATCH_EXPORT const dispatch_block_t _dispatch_data_destructor_##name
6968
#else
70-
#define DISPATCH_DATA_DESTRUCTOR_TYPE_DECL(name) \
71-
DISPATCH_EXPORT dispatch_block_t _dispatch_data_destructor_##name
72-
#endif
73-
#else
7469
#define DISPATCH_DATA_DESTRUCTOR_TYPE_DECL(name) \
7570
DISPATCH_EXPORT const dispatch_function_t \
7671
_dispatch_data_destructor_##name

dispatch/dispatch.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
#include <os/availability.h>
2727
#include <TargetConditionals.h>
2828
#include <os/base.h>
29-
#elif defined(__linux__) || defined(__FreeBSD__)
29+
#elif defined(_WIN32)
30+
#include <os/generic_win_base.h>
31+
#elif defined(__unix__)
3032
#include <os/generic_unix_base.h>
3133
#endif
3234

dispatch/object.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ typedef union {
121121
#ifndef DISPATCH_DATA_DECL
122122
#define DISPATCH_DATA_DECL(name) OS_OBJECT_DECL_SWIFT(name)
123123
#endif // DISPATCH_DATA_DECL
124-
#elif !TARGET_OS_WIN32
124+
#else
125125
/*! @parseOnly */
126126
#define DISPATCH_SOURCE_DECL(name) \
127127
DISPATCH_DECL(name);
@@ -131,12 +131,6 @@ typedef union {
131131
#define DISPATCH_SOURCE_TYPE_DECL(name) \
132132
DISPATCH_EXPORT const struct dispatch_source_type_s \
133133
_dispatch_source_type_##name
134-
#else
135-
#define DISPATCH_SOURCE_DECL(name) \
136-
DISPATCH_DECL(name);
137-
#define DISPATCH_SOURCE_TYPE_DECL(name) \
138-
DISPATCH_EXPORT struct dispatch_source_type_s _dispatch_source_type_##name
139-
#define DISPATCH_DATA_DECL(name) DISPATCH_DECL(name)
140134
#endif
141135

142136
#ifdef __BLOCKS__

os/generic_win_base.h

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
/*
2+
* This source file is part of the Swift.org open source project
3+
*
4+
* Copyright (c) 2015 Apple Inc. and the Swift project authors
5+
*
6+
* Licensed under Apache License v2.0 with Runtime Library Exception
7+
*
8+
* See http://swift.org/LICENSE.txt for license information
9+
* See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
*
11+
*/
12+
13+
#ifndef __OS_GENERIC_WIN_BASE__
14+
#define __OS_GENERIC_WIN_BASE__
15+
16+
// Unices provide `roundup` via sys/param.h
17+
#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
18+
// Unices provide `MAX` via sys/param.h
19+
#define MAX(a,b) (((a)>(b))?(a):(b))
20+
// Unicies provide `MIN` via sys/param.h
21+
#define MIN(a,b) (((a)<(b))?(a):(b))
22+
// Unicies provide `howmany` via sys/param.h
23+
#define howmany(x, y) (((x) + ((y) - 1)) / (y))
24+
25+
#if defined(__cplusplus)
26+
#define __BEGIN_DECLS extern "C" {
27+
#define __END_DECLS }
28+
#else
29+
#define __BEGIN_DECLS
30+
#define __END_DECLS
31+
#endif
32+
33+
#ifndef API_AVAILABLE
34+
#define API_AVAILABLE(...)
35+
#endif
36+
#ifndef API_DEPRECATED
37+
#define API_DEPRECATED(...)
38+
#endif
39+
#ifndef API_UNAVAILABLE
40+
#define API_UNAVAILABLE(...)
41+
#endif
42+
#ifndef API_DEPRECATED_WITH_REPLACEMENT
43+
#define API_DEPRECATED_WITH_REPLACEMENT(...)
44+
#endif
45+
46+
#if !defined(__has_attribute)
47+
#define __has_attribute(attibute) 0
48+
#endif
49+
50+
#if !defined(__has_builtin)
51+
#define __has_builtin(builtin) 0
52+
#endif
53+
54+
#if !defined(__has_feature)
55+
#define __has_feature(feature) 0
56+
#endif
57+
58+
#if __has_builtin(__builtin_expect)
59+
#define OS_EXPECT(expression, value) __builtin_expect((expression), (value))
60+
#else
61+
#define OS_EXPECT(expression, value) (expression)
62+
#endif
63+
64+
#if __has_attribute(__unused__)
65+
#define OS_UNUSED __attribute__((__unused__))
66+
#else
67+
#define OS_UNUSED
68+
#endif
69+
70+
#ifndef os_likely
71+
#define os_likely(expression) OS_EXPECT(!!(expression), 1)
72+
#endif
73+
#ifndef os_unlikely
74+
#define os_unlikely(expression) OS_EXPECT(!!(expression), 0)
75+
#endif
76+
77+
#if __has_feature(assume_nonnull)
78+
#define OS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
79+
#define OS_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end")
80+
#else
81+
#define OS_ASSUME_NONNULL_BEGIN
82+
#define OS_ASSUME_NONNULL_END
83+
#endif
84+
85+
#if __has_builtin(__builtin_assume)
86+
#define OS_COMPILER_CAN_ASSUME(expr) __builtin_assume(expr)
87+
#else
88+
#define OS_COMPILER_CAN_ASSUME(expr) ((void)(expr))
89+
#endif
90+
91+
#if __has_feature(attribute_availability_swift)
92+
// equivalent to __SWIFT_UNAVAILABLE from Availability.h
93+
#define OS_SWIFT_UNAVAILABLE(msg) \
94+
__attribute__((__availability__(swift, unavailable, message = msg)))
95+
#else
96+
#define OS_SWIFT_UNAVAILABLE(msg)
97+
#endif
98+
99+
#define __OS_STRINGIFY(s) #s
100+
#define OS_STRINGIFY(s) __OS_STRINGIFY(s)
101+
102+
#if __has_feature(objc_fixed_enum) || __has_extension(cxx_strong_enums)
103+
#define OS_ENUM(name, type, ...) typedef enum : type { __VA_ARGS__ } name##_t
104+
#else
105+
#define OS_ENUM(name, type, ...) \
106+
enum { __VA_ARGS__ }; \
107+
typedef type name##_t
108+
#endif
109+
110+
#ifdef OS_EXPORT
111+
#undef OS_EXPORT
112+
#endif
113+
#define OS_EXPORT __declspec(dllexport)
114+
115+
#ifdef OS_WARN_RESULT_NEEDS_RELEASE
116+
#undef OS_WARN_RESULT_NEEDS_RELEASE
117+
#endif
118+
119+
#ifdef OS_WARN_RESULT
120+
#undef OS_WARN_RESULT
121+
#endif
122+
#define OS_WARN_RESULT
123+
124+
#ifdef OS_NOTHROW
125+
#undef OS_NOTHROW
126+
#endif
127+
#define OS_NOTHROW
128+
129+
#endif

os/object.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
#include <os/availability.h>
2727
#include <TargetConditionals.h>
2828
#include <os/base.h>
29-
#elif defined(__linux__) || defined(__FreeBSD__)
29+
#elif defined(_WIN32)
30+
#include <os/generic_win_base.h>
31+
#elif defined(__unix__)
3032
#include <os/generic_unix_base.h>
3133
#endif
3234

private/data_private.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -182,15 +182,9 @@ dispatch_data_make_memory_entry(dispatch_data_t data);
182182
*/
183183
typedef const struct dispatch_data_format_type_s *dispatch_data_format_type_t;
184184

185-
#if !TARGET_OS_WIN32
186185
#define DISPATCH_DATA_FORMAT_TYPE_DECL(name) \
187186
DISPATCH_EXPORT const struct dispatch_data_format_type_s \
188187
_dispatch_data_format_type_##name
189-
#else
190-
#define DISPATCH_DATA_FORMAT_TYPE_DECL(name) \
191-
DISPATCH_EXPORT struct dispatch_data_format_type_s \
192-
_dispatch_data_format_type_##name
193-
#endif
194188

195189
/*!
196190
* @const DISPATCH_DATA_FORMAT_TYPE_NONE

private/layout_private.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828

2929
__BEGIN_DECLS
3030

31-
#if !TARGET_OS_WIN32
3231
API_AVAILABLE(macos(10.6), ios(4.0))
3332
DISPATCH_EXPORT const struct dispatch_queue_offsets_s {
3433
// always add new fields at the end
@@ -51,7 +50,6 @@ DISPATCH_EXPORT const struct dispatch_queue_offsets_s {
5150
const uint16_t dqo_priority;
5251
const uint16_t dqo_priority_size;
5352
} dispatch_queue_offsets;
54-
#endif
5553

5654
#if DISPATCH_LAYOUT_SPI
5755

private/private.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232
#include <os/availability.h>
3333
#include <TargetConditionals.h>
3434
#include <os/base.h>
35-
#elif defined(__linux__) || defined(__FreeBSD__)
35+
#elif defined(_WIN32)
36+
#include <os/generic_win_base.h>
37+
#elif defined(__unix__)
3638
#include <os/generic_unix_base.h>
3739
#endif
3840

@@ -44,7 +46,9 @@
4446
#if HAVE_UNISTD_H
4547
#include <unistd.h>
4648
#endif
49+
#if !TARGET_OS_WIN32
4750
#include <pthread.h>
51+
#endif
4852
#if TARGET_OS_MAC
4953
#include <pthread/qos.h>
5054
#endif

0 commit comments

Comments
 (0)