[libcxx] A few questions about external threading support

Hello libcxx developers:

I am the maintainer of the mcfgthread library (https://github.com/lhmouse/mcfgthread). At the moment I provide support for libstdc++ only, but I am also willing to add support for libcxx. Here are a few questions:

1. The prototype of `__libcpp_recursive_mutex_trylock()` was changed from RELEASE_400 to trunk. It used to return an `int` but now it returns a `bool` instead. Since the old function returns zero on success while the new function returns non-zero on success, this results in horrible incompatibility. Would you please provide some details about why you changed its return type?

2. There is no `__libcpp_recursive_mutex_timedlock()`. `std::recursive_mutex` is implemented using a non-recursive mutex plus a condition variable. Are there any reasons why you don't make use of it? I know that Windows SRW lock doesn't support timed locking but `pthread_mutex_timedlock()` is a standard function in POSIX so it should be used in favor of sort of emulation.

3. The inline assembler in Clang doesn't support Intel syntax even with `-masm=intel`. Is there a command line option to have Clang pass asm code directly to the assembler that accepts Intel syntax?

Thanks in advance.

Hello libcxx developers:

I am the maintainer of the mcfgthread library (
https://github.com/lhmouse/mcfgthread). At the moment I provide support
for libstdc++ only, but I am also willing to add support for libcxx. Here
are a few questions:

1. The prototype of `__libcpp_recursive_mutex_trylock()` was changed from
RELEASE_400 to trunk. It used to return an `int` but now it returns a
`bool` instead. Since the old function returns zero on success while the
new function returns non-zero on success, this results in horrible
incompatibility. Would you please provide some details about why you
changed its return type?

All callers of `__libcpp_foo_trylock()` functions return bool so it made
more sense to convert the return value to bool once inside the
`__threading_support` interface rather than at each callsite. I'm not sure
what incompatibility this causes since the callers should have been updated
too.

2. There is no `__libcpp_recursive_mutex_timedlock()`.
`std::recursive_mutex` is implemented using a non-recursive mutex plus a
condition variable. Are there any reasons why you don't make use of it? I
know that Windows SRW lock doesn't support timed locking but
`pthread_mutex_timedlock()` is a standard function in POSIX so it should be
used in favor of sort of emulation.

I'm not sure why. I'll have to look into it further. I suspect it might be
related to the clock used by pthread_mutex_trylock but IDK. I'll look into
the suggested implementation further.
However changing it now would require an ABI break, which is unfortunate
but not insurmountable.

All callers of `__libcpp_foo_trylock()` functions return bool so it made
more sense to convert the return value to bool once inside the
`__threading_support` interface rather than at each callsite. I'm not
sure what incompatibility this causes since the callers should have been
updated too.

Thanks for your reply.

At the moment I have no idea how many external threading implementations there are, but they will ultimately be broken once the trunk version is released.

However changing it now would require an ABI break, which is unfortunate
but not insurmountable.

Err, true, but the trylock thing is already a break isn'it?

All callers of `__libcpp_foo_trylock()` functions return bool so it made
more sense to convert the return value to bool once inside the
`__threading_support` interface rather than at each callsite. I'm not
sure what incompatibility this causes since the callers should have been
updated too.

Thanks for your reply.

At the moment I have no idea how many external threading implementations
there are, but they will ultimately be broken once the trunk version is
released.

There is one version that I know of, but the expectation of external
threading implementations is that they track trunk very closely. There is
absolutely no guarantee of API compatibility in the external threading
interface. It's not meant to be a stable interface.

However changing it now would require an ABI break, which is unfortunate

but not insurmountable.

Err, true, but the trylock thing is already a break isn'it?

Good point. Changing the try_lock() definition to use that may not be ABI
breaking, but it may be a backwards incompatible change if other methods
depend on certain invariants that try_lock() no longer maintains.

I would rather apply your suggested fix and remove the condition variable
entirely so that we get the reduced class size as well. We have mechanisms
for staging/guarding ABI breaking changes, so we might as well use them.

There is one version that I know of, but the expectation of external
threading implementations is that they track trunk very closely. There
is absolutely no guarantee of API compatibility in the external
threading interface. It's not meant to be a stable interface.

But you can change its name so if a user picks a wrong dynamic library by accident he will get an undefined reference, instead of an obscure fault because the old function doesn't return a non-zero value upon success - just the opposite.

Good point. Changing the try_lock() definition to use that may not be
ABI breaking, but it may be a backwards incompatible change if other
methods depend on certain invariants that try_lock() no longer maintains.

I would rather apply your suggested fix and remove the condition
variable entirely so that we get the reduced class size as well. We have
mechanisms for staging/guarding ABI breaking changes, so we might as
well use them.

Then there are going to be `__libcpp_mutex_timedwait()` and `__libcpp_recursive_mutex_timedwait()`, aren't there? Then would they return `bool` or `int`? The pthread equivalents return `int` anyway.