Return values from semaphore calls are not defined/declared

Using semaphores for a Bluepill based board project I looked at the documentation for support. The calls to use were described together with the optional return values. E.g. ETIMEDOUT, ECANCELED and EAGAIN.

I found the definitions for these defines in the file …/RIOT/cpu/avr8_common/avr_libc_extra/include/errno.h.

When it came to testing however it gave some problems. Turned out that the values that are returned by the sema calls were not that what is defined in the file mentioned above.

Via a test program the following values were found -ETIMEDOUT = -116, -ECANCELED=-140 and -EAGAIN = -11. Using these values have the expected results.

So I would like to ask to have the defines - and the correct values - in an include file and added to the RIOT-OS package. And of course an update to the documentation so that this file is also mentioned.

With kind regards, John

Hi,

errno.h is provided by the standard C library. The numeric values are implementation defined, never use them. Instead, always use the macros (e.g. EBUSY, EINVAL, .EAGAIN, …).

For debugging, you can use e.g. strerror() to translate a value into the corresponding string. Alternatively, you can check the numeric value in /usr/arm-none-eabi/include/errno.h

The header you found is a workaround that is only used for avrlibc (which is only used for AVR based boards such as the classic arduino boards and not by ARM based boards such as the bluebill). That workaround is needed as the errno.h in the avrlibc is conflicting with the POSIX standard.

Kind regards, Marian

Hello Marian,

thanks for spending some time on this issue. It's appreciated.

Okay I understand your answer. Clear. Only the remark that ‘the numeric values are implementation defined’ is of course not so convenient for us developers. It limits the possible re-usability off the code. I understand that this situation/implementation is a choice for whatever reasons. A lot of us RIOT-OS users use the code and the examples as supplied by RIOT-OS where the documentation states something and the examples show something. In this case the values were int’s which is a pretty numerical value. Hence the problem arose that triggered this issue.

I think it would be a good idea if your remark regarding the fact that these kind of things are implementation dependent would end up in the RIOT-OS documentation/technical notes somehow as to warn other users that this is something to watch out for.

With kind regards, John

I don’t fully get this. E.g. considering the following:

int retval = some_func();
switch (retval) {
case 0:
    /* success */
    break;
case -ETIMEDOUT:
    handle_timeout();
    break;
default:
    handle_other_error();
    break;

Even though the exact value of -ETIMEDOUT is not known, this would still work identical on any platform regardless of the actual value.

(There is one gotcha, though: EAGAIN and EWOULDBLOCK, as well as EDEADLK and EDEADLOCK often have the same numerical value. So they cannot be in a switch statement. But checking with if ((retvall == -EAGAIN) || (retval == -EWOULDBLOCK)) {...} is portable.)

Hello Marian,

the example you gave is about the same as my implementation. Yes you are correct in the sense that the written code is portable. Only when turning the code into binaries you need to have the actual numerical values. And that was my problem. So after writing the code the compiler said initially something like '… does not compute, don’t know ETIMEOUT, ECANCEL, … '. So I started searching for these defines … and ended up only in the errno.h file for the AVR. Since there werer no other files supplying the defines I thought ‘Okay let’s give it a try … this might work …’. Not. So an example program revealed the actual values for my target board. And these values worked okay.

After this I created this issue to clarify this.

Greetings, John