Skip to content

Conversation

kjbracey
Copy link
Contributor

Description

Semaphore had a historical 16-bit maximum count limit - this was odd, as the initial count was 32-bit.

Remove the limitation - change constructors to take uint32_t, and make the default limit 0xffffffff rather than 0xffff.

Limits of overload resolution prevent adding new constructors while retaining the old ones.

Addresses issue raised in #10216.

Pull request type

[ ] Fix
[ ] Refactor
[ ] Target update
[ ] Functionality change
[ ] Docs update
[ ] Test update
[X] Breaking change

Release Notes

  • Semaphore now permits the full 32-bit maximum count available in CMSIS RTOS 2. The change to its available constructors breaks binary compatibility, but there should be no source compatibility issues.
  • The default maximum count for a Semaphore is now 0xffffffff rather than 0xffff.

Semaphore had a historical 16-bit maximum count limit - this was odd, as
the initial count was 32-bit.

Remove the limitation - change constructors to take uint32_t, and make
the default limit 0xffffffff rather than 0xffff.

Limits of overload resolution prevent adding new constructors while
retaining the old ones.

Addresses issue raised in ARMmbed#10216.
@note You cannot call this function from ISR context.
*/
Semaphore(int32_t count = 0);
Semaphore(uint32_t count = 0);
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe the reason why count was int32_t is due to the fact that wait() returns the number of available tokens or -1 on invalid parameters. With count being uint32_t you cannot differentiate between the invalid parameters and (very unlikely) case where you have (2^32)-1 tokens available (on U2 complement systems).

Copy link
Contributor Author

@kjbracey kjbracey Mar 26, 2019

Choose a reason for hiding this comment

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

Well spotted. That particular wait API is pretty horrible, and I'm intending to deprecate it anyway in favour of a more rational set of try_acquire, acquire, acquire_for and acquire_until (aligning with the current state of Mutex::lock).

Maybe we could fudge wait so it just clamps to 0x7FFFFFFF? You can't really distinguish different positive return values usefully in a non-racey way anyway.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think clamping wait() output to 0x7FFFFFFF is really nasty. I'd just go with int32_t for the count and maximum count instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What's nasty is returning a count at all - you can't really distinguish between any return values in the range 1 to 0x7FFFFFFF, as the instantaneous read is not atomic or synchronised in any way. All you know for certain is that you acquired 1.

wait and its count returning is on the chopping block for deprecation - acquire will not return a count. So I'm minded to ignore the current flaws of wait, rather than work around them.

@ciarmcom
Copy link
Member

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

@ciarmcom ciarmcom requested review from a team March 26, 2019 10:00
If a Semaphore has a huge count, it could overflow the int32_t return of
Semaphore::wait().
@bulislaw
Copy link
Member

bulislaw commented Apr 4, 2019

I'm afraid that may break binaries in our sources, some of them would use semaphores. Can you confirm they are ok?

@kjbracey
Copy link
Contributor Author

kjbracey commented Apr 5, 2019

Yes, binary breakage is likely. That may be strong enough reason to avoid making the change. I don't think we have any compelling need to up the limits.

Another possibility might be to provide access via a class Semaphore32 : public Semaphore. Only difference would be a widened constructor.

@deepikabhavnani
Copy link

deepikabhavnani commented Apr 9, 2019

@kjbracey-arm - Issue in #10216 is addressed by #10225 by you. Do we still need this breaking change?

@kjbracey
Copy link
Contributor Author

kjbracey commented Apr 10, 2019

I don't think there's a pressing requirement for this. I don't think it merits a breaking change, and I think my Semaphore32 alternative is rather clunky.

It's just an anomaly versus the underlying CMSIS-RTOS, really. I don't see any real use case for a semphore with >65535 count.

Any thoughts from @desowin?

@desowin
Copy link
Contributor

desowin commented Apr 10, 2019

Any thoughts from @desowin?

The only reason why I mentioned this Semaphore 16-bit limit in #10216 was that I thought about stuffing Semaphore instance inside the Mail class. I had no idea that the underlying CMSIS-RTOS API can achieve timed and/or blocking allocation.

Pull Request #10225 fully resolves my issue (lack of blocking alloc in Mail).

I don't find any practical use for semaphores (nor even Mail boxes) with more than 16-bit count/items in embedded applications that I work on (tbh. even 8-bit would suffice for my uses).

@kjbracey
Copy link
Contributor Author

Closed due to general pointlessness.

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.

7 participants