Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add declaration to expose enable_* functions from SerialBase #14175

Merged
merged 3 commits into from
Jan 25, 2021

Conversation

harmut01
Copy link
Contributor

@harmut01 harmut01 commented Jan 19, 2021

Summary of changes

Fixes #14052

UnBufferedSerial is missing a declaration to expose enable_input and enable_output, which are inherited from the private base class SerialBase. Add the using-declaration to the class definition to expose these functions.

Impact of changes

None

Migration actions required

None

Documentation

None


Pull request type

[x] Patch update (Bug fix / Target update / Docs update / Test update / Refactor)
[] Feature update (New feature / Functionality change / New API)
[] Major update (Breaking change E.g. Return code change / API behaviour change)

Test results

[] No Tests required for this change (E.g docs only update)
[x] Covered by existing mbed-os tests (Greentea or Unittest)
[] Tests / results supplied as part of this PR

Reviewers


@kjbracey-arm @ithinuel @hugueskamba

UnBufferedSerial is missing a declaration to expose enable_input and
enable_output, which are inherited from the private base class Serial
Base. Add the using-declaration to the class definition.
@ciarmcom ciarmcom added the release-type: patch Indentifies a PR as containing just a patch label Jan 19, 2021
@ciarmcom ciarmcom requested review from a team January 19, 2021 15:00
@ciarmcom
Copy link
Member

@harmut01, thank you for your changes.
@ARMmbed/mbed-os-core @ARMmbed/mbed-os-hal @ARMmbed/mbed-os-maintainers please review.

@kjbracey
Copy link
Contributor

This exposes the member functions for UnbufferedSerial, but does it actually override the virtual members from FileHandle as required?

If I was reading the Compiler Explorer output from @ithinuel's example (https://godbolt.org/z/aoE78x) correctly, it looked like the using wasn't sufficient.

@ithinuel
Copy link
Member

ithinuel commented Jan 20, 2021

@kjbracey-arm I did explore a bit more using armv7-a clang with -Os https://godbolt.org/z/T9EG83
It looks to me like it does what we want.

@pan- Is that a valid solution ?

@kjbracey
Copy link
Contributor

kjbracey commented Jan 20, 2021

I don't see how you conclude that from your example. You don't have an actual Child object, so you can't see a generated vtable. After adding one, I'm not convinced I'm reading it correctly...

I'd suggest actually running a real test rather than inspecting disassembly.

@0xc0170
Copy link
Contributor

0xc0170 commented Jan 20, 2021

@harmut01 have you run it on the target or can you? Is there a test case (if not we should add it) ?

@harmut01
Copy link
Contributor Author

Yes I have Martin, the build compiles for the targets listed in the issue, and I have also run the code Peter provided on a Nucleo board with the following results:
image

@kjbracey
Copy link
Contributor

If that's the original code in the issue, it doesn't test the FileHandle virtual method though.

My later code using mbed_file_handle would exercise it, but you'd need to add something to see if the calls reached the right place. Check return codes, or actually test output being disabled.

@pan-
Copy link
Member

pan- commented Jan 20, 2021

I amended the Godbolt snippet to reflect more closely the problem: https://godbolt.org/z/r5vPe9 .

As we can see, if the using declaration is used, Parent::f will be called if the object is accessed through a Child pointer but Interface::f is called if the object is accessed through an Interface pointer.

If a proper override is provided, the function become consistent regardless of the pointer type accessing it.

I think this PR should provide proper overrides for functions marked as virtual in SerialBase or FileHandle and let using to members that are not virtual in any of these classes.

@kjbracey
Copy link
Contributor

I think this PR should provide proper overrides for functions marked as virtual in SerialBase or FileHandle

I believe that only applies to these 2 functions.

It does appear then that there's no way to have Child's vtable point directly to Parent::f. You'd kind of want there to be a using fill-in there for that case, but we have to invent Child::f. Bit less efficient. Oh well.

kjbracey
kjbracey previously approved these changes Jan 21, 2021
@mergify mergify bot added needs: CI and removed needs: review labels Jan 21, 2021
@mergify mergify bot added needs: work and removed needs: CI labels Jan 21, 2021
@mergify mergify bot dismissed stale reviews from kjbracey and hugueskamba January 21, 2021 13:45

Pull request has been modified.

@kjbracey
Copy link
Contributor

To be more explicit - this is following the FileHandle API.

Either you document explicitly that UnbufferedSerial enable_input calls can never and will never fail as part of API, preventing us from changing that in future, or you restate the standard API - negative error codes on failure.

I see no hugely strong reason to lock this in to "can never fail" as part of the API, even if that's true of the current implementation.

(Is it even true? Or is it the case that SerialBase just fails to report failure?)

@ithinuel
Copy link
Member

Or is it the case that SerialBase just fails to report failure?

I don't know if the introduction of that feature is related to the time I had to hack in the serial HAL that ability to disable individually rx and/or tx. So for what it's worth, I the time only 2 device where of interest to me and that operation couldn't fail.

Now, If we consider the likely possibility of convergence of USBCDC/USBSerial and SerialBase through mbed::Stream, what would we expect from enable_input/enable_output ?

  • to fail
  • to accept but ignore the request (i.e. still be able to send/receive)
  • to accept and ignore what ever is received over USB when input is disabled / discard write operation when output is disabled ?

It may feel like we're diverging from the point here but this is what needs to be considered now if we lock into will never fail.
On the other hand, we can keep this API as may fail and adjust the under lying implementation if ever need be.

Remember that compilers are really smart. If it sees that it always return 0, it'll eliminate unnecessary code on it's own.

@kjbracey
Copy link
Contributor

mbed::Stream

Still think that should be deprecated, as per #5655. Guess it still hasn't happened yet. Did kill Serial at least.

Anyway, this is implementing the FileHandle API (as does Stream). The FileHandle API already permits failure, which is why the return code is there. Indeed, failure is the default implementation in FileHandle.

This API is slightly unusual though in that it was not intended to actually be a "mute" - the device wasn't /required/ to actually block all input/output, it was just for power saving purposes. Something a bit like the "deep sleep lock", which is what it originally was just an abstraction for. This isn't actually clear in the current Doxygen though. So actually looking for "success"/"failure" isn't really that useful anyway. It's not an API that does something for you, it's an API that tells the system what you're up to.

I can't honestly think of any case an application would want to look at the return code. It's really there just for consistency with other FileHandle API calls. So discussing it this much is probably pointless :)

If it sees that it always return 0, it'll eliminate unnecessary code on it's own.

It could only do that if the definition was in the header or if you had Link-Time Optimisation on. That would be an argument for moving the definition to the header.

@mergify mergify bot added needs: CI and removed needs: work labels Jan 21, 2021
@harmut01
Copy link
Contributor Author

This force push reverts the function header comment. We can leave the API as is for now and if the behavior is ever needed we will at least have the option to implement it.

@0xc0170
Copy link
Contributor

0xc0170 commented Jan 22, 2021

CI started

@mbed-ci
Copy link

mbed-ci commented Jan 22, 2021

Jenkins CI Test : ✔️ SUCCESS

Build Number: 1 | 🔒 Jenkins CI Job | 🌐 Logs & Artifacts

CLICK for Detailed Summary

jobs Status
jenkins-ci/mbed-os-ci_unittests ✔️
jenkins-ci/mbed-os-ci_cmake-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_cmake-example-ARM ✔️
jenkins-ci/mbed-os-ci_build-greentea-ARM ✔️
jenkins-ci/mbed-os-ci_build-example-ARM ✔️
jenkins-ci/mbed-os-ci_build-cloud-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_build-example-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_build-greentea-GCC_ARM ✔️
jenkins-ci/mbed-os-ci_build-cloud-example-ARM ✔️
jenkins-ci/mbed-os-ci_cmake-example-test ✔️
jenkins-ci/mbed-os-ci_greentea-test ✔️

@0xc0170 0xc0170 merged commit 1b7b620 into ARMmbed:master Jan 25, 2021
@mergify mergify bot removed the ready for merge label Jan 25, 2021
@mbedmain mbedmain added release-version: 6.7.0 Release-pending and removed release-type: patch Indentifies a PR as containing just a patch Release-pending labels Jan 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

UnbufferedSerial does not expose enable_* functions from SerialBase; behavior not predictable when exposed
10 participants