lhmouse / mcfgthread

Cornerstone of the MOST efficient std::thread on Windows for mingw-w64
https://gcc-mcf.lhmouse.com/
Other
269 stars 28 forks source link

Implement inline aliases in a more 'proper' way #73

Closed lhmouse closed 1 year ago

lhmouse commented 1 year ago

Alternative 0 (current): static function pointers

This is what we have at the moment:

https://github.com/lhmouse/mcfgthread/blob/e8fb31d55883268d5dedfe38684d56a89ee6c017/src/fwd.h#L114

Alternative 1: static inline wrapper functions

inline int my_add(int a, int b) { return a + b;  }
static inline int my_add_alias(int a, int b) { return my_add(a, b);  }

Alternative 2: ASM aliases

inline int my_add(int a, int b) { return a + b;  }
extern int my_add_alias(int a, int b) __MINGW_ASM_CALL(my_add);

Alternative 3: static inline wrapper functions with ASM aliases

inline int my_add(int a, int b) { return a + b;  }
__MCF_GNU_INLINE int my_add_alias(int a, int b) __MINGW_ASM_CALL(my_add);
__MCF_GNU_INLINE int my_add_alias(int a, int b) { return my_add(a, b);  }

Alternative 4: weak aliases

inline int my_add(int a, int b) { return a + b;  }
static __typeof__(my_add) my_add_alias __attribute__((__copy__(my_add), __weakref__("my_add")));
FrankHB commented 1 year ago

I prefer alternative 2 for ontologically correctness (as similar to the rules behind the standard ODR).

Or you can have alternative 1 with __attribute__((__always_inline__)) on the alias declaration and avoid to get the value of the alias totally by convention. But this does not make any big improvement over alternative 0.

lhmouse commented 1 year ago

I prefer alternative 2 for ontologically correctness (as similar to the rules behind the standard ODR).

That would nullify the purpose of inline functions.

Or you can have alternative 1 with __attribute__((__always_inline__)) on the alias declaration and avoid to get the value of the alias totally by convention. But this does not make any big improvement over alternative 0.

Theoretically it's on a par with alternative 0; no better, no worse.

lhmouse commented 1 year ago

Those interfaces with reserved names, such as __gthread_* and __libcpp_*, can be defined macros. So this issue has been narrowed down to the scope of C11 functions.

In order to prevent DLL hells, C11 functions are not exported as their standard names, but with a __MCF_c11_ prefix. If a user declares a C11 function themselves and calls it, they will get undefined references anyway. The long-term plan is that these C11 functions should be provided as thunks, linked statically in the CRT.

lhmouse commented 1 year ago

Clang doesn't like this:

ld.lld: error: test/c11_mtx_recursive_timeout.o: call_once should not refer to special section 0
clang: error: linker command failed with exit code 1 (use -v to see invocation)