Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hi!
It’s spring, so I thought it’s time for some gardening in
native/cpu
.I’ve got a few PRs lined up, including one enabling the native board on arm64 and one resurrecting macOS support.
While writing these I’ve found myself unable to really understand what’s going on in the
native/cpu
code. So I thought if I were to add documentation and name a few things more descriptively, this might help anyone reading it in the future.Below, I’ll give a brief overview of the motivation behind certain changes.
As a matter of ensuring resilience against future modifications to system headers, I set_GNU_SOURCE
/_XOPEN_SOURCE
_GNU_SOURCE
(or_XOPEN_SOURCE
for BSD/Darwin, respectively) for all code in cpu/native.Previously, these were set inconsistently, potentially leading to redefinitions, especially if you try to set them globally. This technique also proved to be quite dangerous on macOS – take
<ucontext.h>
as an example:If
_XOPEN_SOURCE
isn’t set, then the context struct will lack a storage buffer.[make|swap|set|get]context
however will assume there is indeed a storage buffer and write happily to memory far off earth. And said bug is not easy to find if some other system header importsucontext.h
before and you forgot to set_GNU../_XOPEN…
. Then your precious_GNU…/_XOPEN…
definitions around<ucontext.h>
become worthless. 💥Context switches
Previously, code manipulatingucontext
s was duplicated; same goes for retrieving theucontext_t
from the stack buffer. I wrapped them in zero-runtime-cost static inline’s (_context_set_fptr
,_context_get_fptr
). Note that these aren’t calledset_pc
intentionally. There are platforms where you cannot set PC, i.e., they require another technique of transferring control back to userspace. Stay tuned for arm64 ;)makecontext madness
Pointers passed as thread arguments were previously truncated to 32 bits. This should crash, don’t really know why it didn’t already.So on 64-bit platforms, I do not use
makecontext
’s mechanism of supplying thread arguments. Instead, we first go to_start_task_func64
and pass the 64-bit argument in a register. I made sure that register isn’t mutated in glibc/libplatform.Then in
_start_task_func64
, we invoke the real thread function and move the 64-bit argument into the proper register according to the arch’s ABI. No more castingvoid*
toint
.Documentation
The doxygen markup added *encloses* symbols in *named sections*. Everytime you see an@name
followed by@{
, that’s a section. To make finding sections easier, I added corresponding marks (MARK: -
) which show up in editors in the minimap (e.g., VS Code, Xcode). Also fixed incorrect uses of@ingroup
.Logging
While (trying) to debug native/cpu, it became apparent that understanding logs without knowing where they come from is hard. Prefixing logs with the enclosing function’s name does not help, unless you already know what said function *does*. So, for each *component*— say CPU, IRQ implementation, startup code — I prefixed logs with the rough equivalent of the filename.