Skip to content

core/mutex: compatibility with non-C languages#15597

Merged
benpicco merged 1 commit intoRIOT-OS:masterfrom
maribu:mutex-cxx
Dec 15, 2020
Merged

core/mutex: compatibility with non-C languages#15597
benpicco merged 1 commit intoRIOT-OS:masterfrom
maribu:mutex-cxx

Conversation

@maribu
Copy link
Copy Markdown
Member

@maribu maribu commented Dec 9, 2020

Contribution description

Due to limited compatibility with C, we cannot use the inline mutex_trylock implementation for C++. Instead, we provide a mutex_trylock_ffi() intended for foreign function interfaces. This should also benefit rust users.

Testing procedure

C++ code should compile again with recent clang++ and C code shouldn't differ.

Issues/PRs references

#15595

@maribu maribu requested a review from kaspar030 as a code owner December 9, 2020 10:07
@maribu maribu added Area: core Area: RIOT kernel. Handle PRs marked with this with care! CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) labels Dec 9, 2020
@maribu maribu requested a review from chrysn December 9, 2020 10:09
static inline int mutex_trylock(mutex_t *mutex)
{
#ifdef __cplusplus
return mutex_trylock_ffi(mutex);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The order needs to be changed:

/home/kaspar/src/riot/core/include/mutex.h:208:12: error: use of undeclared identifier 'mutex_trylock_ffi'; did you mean 'mutex_trylock'?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, mutex_trylock_ffi() is not defined at this point in the file.

Copy link
Copy Markdown
Contributor

@kaspar030 kaspar030 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK.

@chrysn
Copy link
Copy Markdown
Member

chrysn commented Dec 9, 2020

We have tons of similar static inline functions. How is this one special?

* @brief Tries to get a mutex, non-blocking.
*
* @internal
* @note This function is intended for use by languages for incompatible
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @note This function is intended for use by languages for incompatible
* @note This function is intended for use by languages incompatible

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added and squashed

@kaspar030
Copy link
Copy Markdown
Contributor

We have tons of similar static inline functions. How is this one special?

It is actually used by c++ code within RIOT, and includes vendor headers (through irq.h), which clang just recently flagged invalid: https://www.mail-archive.com/[email protected]/msg86144.html.

@maribu
Copy link
Copy Markdown
Member Author

maribu commented Dec 9, 2020

We have tons of similar static inline functions. How is this one special?

This one fails in the CI test ;-) But I personally think it would on the long term we should consider providing replacements for all non-trivial static inline functions or just make them C only. C++ simply isn't compatible with C anymore. And I was told C++ developers do prefer C++ wrappers like the C++11 mutex anyway over C APIs anyway.

Due to limited compatibility with C, we cannot use the inline mutex_trylock
implementation for C++. Instead, we provide a mutex_trylock_ffi() intended for
foreign function interfaces. This should also benefit rust users.
@kaspar030
Copy link
Copy Markdown
Contributor

But I personally think it would on the long term we should consider providing replacements for all non-trivial static inline functions or just make them C only.

Or make LTO default for non-debug builds. We even have infra for exceptions for code that really doesn't compile with LTO.

@kaspar030
Copy link
Copy Markdown
Contributor

But I personally think it would on the long term we should consider providing replacements for all non-trivial static inline functions or just make them C only.

Or make LTO default for non-debug builds. We even have infra for exceptions for code that really doesn't compile with LTO.

... and get rid of the inlines I mean. :)

@chrysn
Copy link
Copy Markdown
Member

chrysn commented Dec 9, 2020

Can't speak for developers, but during Rust porting, I built those idiomatic wrappers from the very base functions -- ie. something like try_lock still needs to be available from C++. Even if it's only used in the wrappers, they shouldn't depend on implementation details by implementing anything themselves. (And a change like the proposed and accepted one would do that).

I'm just wondering about generalization. If we establish a convention here that's generic enough (and adding an _ffi suffix to any function might already be), then we might also think of the next step of making that available for all static inlines. IMO (which is shaped by having done parts of this for the Rust port) that would entail either finding a place for a to-be-generated C file for each header, or having a big all-inline-wrappers compilation unit.

@maribu
Copy link
Copy Markdown
Member Author

maribu commented Dec 9, 2020

Or make LTO default for non-debug builds.

The problem is that sometimes LTO builds are bigger (at least for the toolchain in the RIOT docker). I locally cannot reproduce this with more recent versions of GCC. But LTO builds really should be either better or at least as good as non-LTO builds. We might want to wait for theory and reality converging here first.

@chrysn
Copy link
Copy Markdown
Member

chrysn commented Dec 9, 2020

Or make LTO default for non-debug builds. We even have infra for exceptions for code that really doesn't compile with LTO.

That would make things even easier with less infrastructure to maintain (at the cost of a very large semiautomated editing step).

@kaspar030
Copy link
Copy Markdown
Contributor

The problem is that sometimes LTO builds are bigger (at least for the toolchain in the RIOT docker).

Really? I haven't seen that in a while. What I have seen is non-working binaries though...

@maribu
Copy link
Copy Markdown
Member Author

maribu commented Dec 9, 2020

The problem is that sometimes LTO builds are bigger (at least for the toolchain in the RIOT docker).

Really? I haven't seen that in a while. What I have seen is non-working binaries though...

@benpicco was recently reporting some examples for this. But I cannot recall a single one.

@benpicco benpicco merged commit 2b110e3 into RIOT-OS:master Dec 15, 2020
@maribu
Copy link
Copy Markdown
Member Author

maribu commented Dec 15, 2020

Thanks :-)

@benpicco
Copy link
Copy Markdown
Contributor

The problem is that sometimes LTO builds are bigger (at least for the toolchain in the RIOT docker).

Really? I haven't seen that in a while. What I have seen is non-working binaries though...

@benpicco was recently reporting some examples for this. But I cannot recall a single one.

Might have been a case of still having some non-LTO object files around.
I think this happens when forgetting to make clean between a non-LTO and an LTO build.

@maribu maribu deleted the mutex-cxx branch January 25, 2021 09:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: core Area: RIOT kernel. Handle PRs marked with this with care! CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants