Comments (7)
2 >~ 3 >> 1
That is:
2 is the clunky traditional solution to the horrors of inline here but it will "just work".
3 is more modern. Due to the past horrors though, my knee-jerk and possibly dated reaction is to just assume extern inline
isn't a "thing" in the real world. But, if tools have caught up to it such that it "just works" too nowadays, open to it.
1 feels like an option of last resort. PITA for software maintainability with a lots of nasty bug surface area.
from firedancer.
IMO this is a good solution. It removes the maintenance burden of re-implementing the C functions in Rust and gives us the flexibility to override this behaviour on a case-by-case basis for instances where performance becomes a problem.
from firedancer.
inline
has historically been a giant mess in the C/C++ language. Standard support was between non-existent to spotty. What was there had parts that were technically burdensome enough at the time (extern inline
) to make compiler conformance incomplete at best (and some of the FFI stuff has a flavor of this).
But there was lots of legit developer demand for it and, to meet this demand, language and compiler extensions (often contradictory) sprung up. Compiler's honoring whatever support they did have was dicey at best though ... excerpting a rant from the header documentation:
/* FD_FN_UNUSED indicates that it is okay if the function with static
linkage is not used. Allows working around -Winline in header only
APIs where the compiler decides not to actually inline the function.
(This belief, frequently promulgated by anti-macro cults, that "An
Inline Function is As Fast As a Macro" ... an entire section in gcc's
documentation devoted to it in fact ... remains among the biggest
lies in computer science. Yes, an inline function is as fast as a
macro ... when the compiler actually decides to treat the inline
keyword more than just for entertainment purposes only. Which, as
-Winline proves, it frequently doesn't. Sigh ... force_inline like
compiler extensions might be an alternative here but they have their
own portability issues.) */
#define FD_FN_UNUSED __attribute__((unused))
This was encouraged by C++ code doing lots of implementation in header files and overusing inline
(lots of developer blindness to the L1I instruction cache, instruction fetch and TLB implications ... which the compiler writers partially compensated in the optimizer by more or less overriding the developers intent when they felt like it ... for the record, I have a rather strong dislike of macros but dislike the compiler disregarding developer's intent even more). So, eventually C/C++ got around to making inline better linguistically supported but still a crap shoot under the hood.
With all that said, the historical practice in various spiritual predecessors to FD's development environment was to macro it up exactly as suggested. I've been trying to remove as many workarounds to historical linguistic gotchas as possible in FD since many of the idioms are compensating for issues going back decades. It'd be nice if we could just say static inline
these days and get the desired behavior. But if the languages are still decades behind where they need to be, so be it.
Also with that, #define FD_INLINE static inline
is definitely wrong as there are some very real differences between what inline
means and static inline
means. So at the least this macro should either be a function modifier like #define FD_FN_INLINE
or maybe (closer to historical practice), #define FD_STATIC_INLINE
to make it explicit that the behavior expected is like ... uh ... static inline
.
I'm also open to games with attributes like force_inline
and/or FD_FN_UNUSED
for a macro solution here. The current situation helps clue in developers that inline
is not gospel to the compiler when they compile with -Winline
. But, if we are about to conclude that inline
is still a giant pile of fail linguistically, we could go the distance and do something far more aggressive to get the language and compiler to honor behave deterministically (might have a cost if we ever wanted to run outside gcc and/or clang-ish tool chains though).
from firedancer.
The workaround is basically equivalent to #2, the build tooling parses the C headers, locates static inlines, and adds an extern wrapper for them. A little extra magic wires everything for free.
from firedancer.
cc @kbowers-jump @tpointon-jump @leoluk curious if you have any thoughts
from firedancer.
Also with that,
#define FD_INLINE static inline
is definitely wrong as there are some very real differences between whatinline
means andstatic inline
means. So at the least this macro should either be a function modifier like#define FD_FN_INLINE
or maybe (closer to historical practice),#define FD_STATIC_INLINE
to make it explicit that the behavior expected is like ... uh ...static inline
.
@kbowers-jump Great point, I like the idea of FD_STATIC_INLINE
.
The issue I'm trying to solve with this change is to create a translation unit that includes "fallback" function definitions of all exported "inline functions" but still inline those at all the C call sites (current behavior). This allows FFI code to use that fallback as real inlining is not implemented.
This sounds exactly what extern inline
combined with __attribute__((force_inline))
might be able to provide.
I appreciate the context but it sounds like both the FD_STATIC_INLINE
macro switch and the extern inline
choices are broken in C compilers. (For the record, in Rust, this is even worse)
So of the three suggested choices, what is your suggestion to proceed? (For the Tango fns specifically, like querying fields from meta)
- Reimplement inline in Rust
FD_STATIC_INLINE
toggleextern inline
and hack the build system to work around it
from firedancer.
Closing this as resolved. We didn't add an FD_INLINE macro, but @mmcgee-jump found a workaround to provide static inlines to FFI.
from firedancer.
Related Issues (20)
- Pack should respect `tx_account_lock_limit`
- Gossiped votes should route into dedup not pack
- gossip: use the same port number for the listen port in the tile as the library config value HOT 2
- QUIC spam protection vs INITIAL packet spam
- QUIC RETRY broken - the secret is entirely derived from data in the token HOT 1
- QUIC RETRY - Simplify retry token
- Resurrect builds with noarch HOT 2
- Remove fd_vector and usages
- make fdctl issue HOT 4
- Consider xdp multiprog support
- Tracking: Jumbo Ethernet frames (>2K packet size) HOT 1
- Support SOLANA_METRICS_CONFIG
- Fail to build if solana submodule is not current HOT 1
- Move `workspace` and `xdp` steps out of configure
- Return unused CUs from execution back to pack
- Use memfd_create and fexecve to run tiles with no memory overlap
- deps.sh fails on Fedora
- Build fails on Linux 6.8 (SYS_landlock)
- Build fails on GCC 14
- Build fails on Clang 18 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from firedancer.