Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions rtos/Semaphore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@

namespace rtos {

Semaphore::Semaphore(int32_t count)
Semaphore::Semaphore(uint32_t count)
{
constructor(count, 0xffff);
constructor(count, 0xffffffff);
}

Semaphore::Semaphore(int32_t count, uint16_t max_count)
Semaphore::Semaphore(uint32_t count, uint32_t max_count)
{
constructor(count, max_count);
}

void Semaphore::constructor(int32_t count, uint16_t max_count)
void Semaphore::constructor(uint32_t count, uint32_t max_count)
{
memset(&_obj_mem, 0, sizeof(_obj_mem));
osSemaphoreAttr_t attr = { 0 };
Expand All @@ -51,8 +51,11 @@ int32_t Semaphore::wait(uint32_t millisec)
{
osStatus_t stat = osSemaphoreAcquire(_id, millisec);
switch (stat) {
case osOK:
return osSemaphoreGetCount(_id) + 1;
case osOK: {
// Need to ensure return remains positive if count is huge.
uint32_t count = osSemaphoreGetCount(_id);
return count < 0x7FFFFFFFu ? (int32_t)count + 1 : 0x7FFFFFFF;
}
case osErrorTimeout:
case osErrorResource:
return 0;
Expand Down
6 changes: 3 additions & 3 deletions rtos/Semaphore.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ class Semaphore : private mbed::NonCopyable<Semaphore> {

@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.


/** Create and Initialize a Semaphore object used for managing resources.
@param count number of available resources
@param max_count maximum number of available resources

@note You cannot call this function from ISR context.
*/
Semaphore(int32_t count, uint16_t max_count);
Semaphore(uint32_t count, uint32_t max_count);

/** Wait until a Semaphore resource becomes available.
@param millisec timeout value. (default: osWaitForever).
Expand Down Expand Up @@ -96,7 +96,7 @@ class Semaphore : private mbed::NonCopyable<Semaphore> {
~Semaphore();

private:
void constructor(int32_t count, uint16_t max_count);
void constructor(uint32_t count, uint32_t max_count);

osSemaphoreId_t _id;
mbed_rtos_storage_semaphore_t _obj_mem;
Expand Down