Skip to content

Commit 92021e1

Browse files
committed
try to fix weak linking on Windows
1 parent e7a71e0 commit 92021e1

File tree

3 files changed

+55
-38
lines changed

3 files changed

+55
-38
lines changed

include/stdexec/__detail/__parallel_scheduler_backend.hpp

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
#include "__execution_fwd.hpp"
2121

2222
// include these after __execution_fwd.hpp
23-
// #include "any_allocator.cuh"
2423
#include "../functional.hpp" // IWYU pragma: keep for __with_default
2524
#include "../stop_token.hpp" // IWYU pragma: keep for get_stop_token_t
2625
#include "__any_allocator.hpp"
@@ -83,28 +82,47 @@ namespace STDEXEC {
8382
virtual void execute(size_t, size_t) noexcept = 0;
8483
};
8584

86-
/// Interface for the parallel scheduler backend.
87-
struct parallel_scheduler_backend {
88-
virtual ~parallel_scheduler_backend() = 0;
89-
90-
/// Schedule work on parallel scheduler, calling `__r` when done and using `__s` for preallocated
91-
/// memory.
92-
virtual void schedule(receiver_proxy&, std::span<std::byte>) noexcept = 0;
93-
94-
/// Schedule bulk work of size `__n` on parallel scheduler, calling `__r` for different
95-
/// subranges of [0, __n), and using `__s` for preallocated memory.
96-
virtual void
97-
schedule_bulk_chunked(size_t, bulk_item_receiver_proxy&, std::span<std::byte>) noexcept = 0;
98-
99-
/// Schedule bulk work of size `__n` on parallel scheduler, calling `__r` for each item, and
100-
/// using `__s` for preallocated memory.
101-
virtual void schedule_bulk_unchunked(
102-
size_t,
103-
bulk_item_receiver_proxy&,
104-
std::span<std::byte>) noexcept = 0;
85+
// This base class associates the STDEXEC::system_context_replaceability namespace
86+
// with the parallel_scheduler_backend for the purposes of ADL.
87+
struct __parallel_scheduler_backend_base {
88+
virtual ~__parallel_scheduler_backend_base() = 0;
10589
};
10690

107-
inline parallel_scheduler_backend::~parallel_scheduler_backend() = default;
91+
inline __parallel_scheduler_backend_base::~__parallel_scheduler_backend_base() = default;
92+
} // namespace system_context_replaceability
93+
} // namespace STDEXEC
94+
95+
// Give parallel_scheduler_backend a mangled name that does not depend on the value of the
96+
// STDEXEC macro. This is so that we can use weak linking to make
97+
// query_parallel_scheduler_backend replaceable.
98+
namespace __system_context_replaceability {
99+
using namespace STDEXEC::system_context_replaceability;
100+
101+
/// Interface for the parallel scheduler backend.
102+
struct parallel_scheduler_backend : __parallel_scheduler_backend_base {
103+
/// Schedule work on parallel scheduler, calling `__r` when done and using `__s` for preallocated
104+
/// memory.
105+
virtual void schedule(receiver_proxy&, std::span<std::byte>) noexcept = 0;
106+
107+
/// Schedule bulk work of size `__n` on parallel scheduler, calling `__r` for different
108+
/// subranges of [0, __n), and using `__s` for preallocated memory.
109+
virtual void schedule_bulk_chunked(
110+
std::size_t,
111+
bulk_item_receiver_proxy&,
112+
std::span<std::byte>) noexcept = 0;
113+
114+
/// Schedule bulk work of size `__n` on parallel scheduler, calling `__r` for each item, and
115+
/// using `__s` for preallocated memory.
116+
virtual void schedule_bulk_unchunked(
117+
std::size_t,
118+
bulk_item_receiver_proxy&,
119+
std::span<std::byte>) noexcept = 0;
120+
};
121+
} // namespace __system_context_replaceability
122+
123+
namespace STDEXEC {
124+
namespace system_context_replaceability {
125+
using namespace ::__system_context_replaceability;
108126
} // namespace system_context_replaceability
109127

110128
namespace __detail {

include/stdexec/__detail/__system_context_default_impl_entry.hpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,30 +29,31 @@
2929

3030
#include "__system_context_default_impl.hpp" // IWYU pragma: keep
3131

32-
namespace STDEXEC::system_context_replaceability {
32+
namespace __system_context_replaceability {
3333

3434
#if STDEXEC_MSVC()
3535
/// Get the backend for the parallel scheduler.
3636
/// Users might replace this function.
37-
extern "C" STDEXEC_SYSTEM_CONTEXT_INLINE //
38-
auto __default_query_parallel_scheduler_backend() -> std::shared_ptr<parallel_scheduler_backend> {
37+
STDEXEC_SYSTEM_CONTEXT_INLINE auto __default_query_parallel_scheduler_backend() //
38+
-> std::shared_ptr<parallel_scheduler_backend> {
3939
return __system_context_default_impl::__parallel_scheduler_backend_singleton
4040
.__get_current_instance();
4141
}
4242

4343
// If query_parallel_scheduler_backend is defined by the user, it will override the
4444
// default implementation. If not, the linker will resolve to the default implementation.
45-
# pragma comment( \
46-
linker, \
47-
"/alternatename:_query_parallel_scheduler_backend=___default_query_parallel_scheduler_backend")
45+
#pragma comment(linker, "/alternatename:"
46+
"?query_parallel_scheduler_backend@__system_context_replaceability@@YA?AV?$shared_ptr@Uparallel_scheduler_backend@__system_context_replaceability@@@std@@XZ"
47+
"="
48+
"?__default_query_parallel_scheduler_backend@__system_context_replaceability@@YA?AV?$shared_ptr@Uparallel_scheduler_backend@__system_context_replaceability@@@std@@XZ")
4849

4950
#else // ^^^ MSVC ^^^ / vvv non-MSVC vvv
5051

5152
/// Get the backend for the parallel scheduler.
5253
/// Users might replace this function.
5354
extern STDEXEC_SYSTEM_CONTEXT_INLINE STDEXEC_ATTRIBUTE(weak) //
5455
auto query_parallel_scheduler_backend() -> std::shared_ptr<parallel_scheduler_backend> {
55-
return __system_context_default_impl::__parallel_scheduler_backend_singleton
56+
return STDEXEC::__system_context_default_impl::__parallel_scheduler_backend_singleton
5657
.__get_current_instance();
5758
}
5859
#endif
@@ -63,8 +64,7 @@ namespace STDEXEC::system_context_replaceability {
6364
extern STDEXEC_SYSTEM_CONTEXT_INLINE //
6465
auto set_parallel_scheduler_backend(__parallel_scheduler_backend_factory_t __new_factory)
6566
-> __parallel_scheduler_backend_factory_t {
66-
return __system_context_default_impl::__parallel_scheduler_backend_singleton
67+
return STDEXEC::__system_context_default_impl::__parallel_scheduler_backend_singleton
6768
.__set_backend_factory(__new_factory);
6869
}
69-
70-
} // namespace STDEXEC::system_context_replaceability
70+
} // namespace __system_context_replaceability

include/stdexec/__detail/__system_context_replaceability_api.hpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,16 @@
2121

2222
#include <memory>
2323

24-
namespace STDEXEC::system_context_replaceability {
25-
/// The type of a factory that can create `parallel_scheduler_backend` instances.
26-
/// TODO(ericniebler): NOT TO SPEC.
27-
using __parallel_scheduler_backend_factory_t = std::shared_ptr<parallel_scheduler_backend> (*)();
28-
24+
namespace __system_context_replaceability {
2925
/// Get the backend for the parallel scheduler.
3026
/// Users might replace this function.
31-
STDEXEC_PP_WHEN(STDEXEC_MSVC(), extern "C")
3227
STDEXEC_ATTRIBUTE(weak) auto query_parallel_scheduler_backend()
3328
-> std::shared_ptr<parallel_scheduler_backend>;
3429

30+
/// The type of a factory that can create `parallel_scheduler_backend` instances.
31+
/// NOT TO SPEC
32+
using __parallel_scheduler_backend_factory_t = std::shared_ptr<parallel_scheduler_backend> (*)();
33+
3534
/// Set a factory for the parallel scheduler backend.
3635
/// Can be used to replace the parallel scheduler at runtime.
3736
/// NOT TO SPEC
@@ -41,4 +40,4 @@ namespace STDEXEC::system_context_replaceability {
4140
"instead.")]]
4241
auto set_parallel_scheduler_backend(__parallel_scheduler_backend_factory_t __new_factory)
4342
-> __parallel_scheduler_backend_factory_t;
44-
} // namespace STDEXEC::system_context_replaceability
43+
} // namespace __system_context_replaceability

0 commit comments

Comments
 (0)