Yield-WaitFor: Introduce defer and update HMAC as example usage#541
Yield-WaitFor: Introduce defer and update HMAC as example usage#541
defer and update HMAC as example usage#541Conversation
|
Obviously I'm not a big fan of macros. Seems complicated compared to the goto version. It also isn't very flexible for drivers that may need more cleanup. |
I agree the macro implementation is complex (aren't they all), but I feel like the actual code is simpler and less error-prone. I messed up the incremental conversion when I'd modified just one of the allows doing just this [not that it's hard to see per se, i.e., I deleted the "top" allow call and the "top" goto label when I first tried], but it's sort of emblematic of why this goto approach is error-prone.
Yes.. that was to keep the macro simpler. Some of the other flavors of this idea have you explicitly define the "destructor" as part of the invocation of the macro; it's more flexible, but also more complex. I'd imagine if we wanted to go this way keeping the simpler "only-works-for-allow" macro, since "unallow-when-done" is such a common use case, while also providing a more generic option. |
|
Okay, I found a much cleaner implementation of this, which matches the (current) draft specification for the next release of C, i.e., in the future |
|
The latest version is nice, even if I don't understand the C code in the macros. But I'm worried about backwards compatibility. |
de8d962 to
8f79efa
Compare
|
What's the worry w.r.t. backwards compatibility? This As for the macro, the fully expanded form basically does this: defer { foo(); bar(); }
// ^^^^^^^^^^^^^^ this bit doesn't change at all
// The above expands to:
auto void __DEFER_FUNCTION0(int* __DEFER_VARIABLE0SENTINEL); // This is just a function prototype
[[ gnu::cleanup(__DEFER_FUNCTION0) ]] int __DEFER_VARIABLE0; // This declares a variable which is never used, but the compiler can see when it goes out of scope, and will call __DEFER_FUNCTION0 when it goes out of scope
auto void __DEFER_FUNCTION0(__attribute__ ((unused)) int* __DEFER_VARIABLE0SENTINEL) { foo(); bar(); }
// ^^^^^^^^^^^^^^^^^ here's our unchanged code, where it's now the body of a function that's being defined |
|
I rebased this on master so the CI can pick up a compiler newer than 2021. It's now functionally a replacement PR for #532. |
defer and update HMAC as example usage
I'm worried this won't work for users on Ubuntu 22.04 (a currently supported LTS release). |
6d45097 to
98ab671
Compare
Turns out I didn't need to do that, just needed to do 0b840d9. I added a "legacy-compilers" CI run here that runs on the default LTS compilers for both ARM and RISCV and it seems to work without issue. (Now, I acknowledge that #539 has some lingering issues that I'm working on, but they may actually be unrelated to compiler version; don't let issues over there poison the well here) |
|
Oh this does work on jammy? |
|
Seems like it, yeah. |
|
Before this change: After this change: So looks good to me. I also forced an error into the libtock-sync hmac library and the unallows worked as expected. |
brghena
left a comment
There was a problem hiding this comment.
Generally this looks good. I like the defer addition and I do think it makes the error handling cleanup nicer.
I think defer + HMAC stuff could go together. But the CI updates seem separate?
|
|
||
| # Install compiler versions from the oldest current Ubuntu LTS | ||
| ci-legacy-compilers: | ||
| strategy: | ||
| matrix: | ||
| os: [ubuntu-22.04] | ||
| # The type of runner that the job will run on | ||
| runs-on: ${{ matrix.os }} | ||
|
|
||
| # Steps represent a sequence of tasks that will be executed as part of the job | ||
| steps: | ||
| - uses: actions/checkout@v2 | ||
| with: | ||
| submodules: recursive | ||
| - uses: carlosperate/arm-none-eabi-gcc-action@v1 | ||
| with: | ||
| release: '10.3-2021.07' | ||
| - run: arm-none-eabi-gcc --version | ||
| - name: setup-riscv-toolchain | ||
| run: sudo apt-get install -y gcc-riscv64-unknown-elf | ||
| - name: riscv-toolchain-version | ||
| run: riscv64-unknown-elf-gcc --version | ||
| #- name: ci-build | ||
| # run: pushd examples; ./build_all.sh || exit; popd | ||
| - name: ci-debug-build | ||
| run: pushd examples/blink; make debug RAM_START=0x20004000 FLASH_INIT=0x30051 || exit; popd |
There was a problem hiding this comment.
(I must have forgotten to hit the button on this comment) Could we split this out to a separate PR? I think it's separate from the rest of the changes here.
There was a problem hiding this comment.
Yeah, that doesn't need to be on this PR. I added it to prove that this works with legacy compilers, but it's unrelated. Dropped it here, will add a more CI-focused PR in a sec
98ab671 to
6429781
Compare
6429781 to
8d7d488
Compare
This is a minimal example of what "cleanup attribute" like code would look like.
This probably isn't the exact best way to implement it (due to the "magic variable name" of
ret_{param}), but it gives a sense of what it would look like.