It doesn't matter what `errno' really is if it is shared between threads because of how it is used.
I'll leave these examples here for you to examine.
Code:
// This is not sufficient to protect `errno' use
// patterns because atomicity only guarantees
// reads and writes will be complete within the
// context of one thread of execution.
__attribute__((__atomic__)) int errno;
bool DoSomething1()
{
// ...
if(/* ??? */)
{
// This is guaranteed to set `errno' to the value 1
// completely and truly even if another thread
// tries to set a different value at the same time.
errno = 1;
return(false);
}
// ...
}
void DoSomething2()
{
// ...
errno = 0;
if(!DoSomething1())
{
// The `errno' is only atomic with respect to reads and
// writes. The value `errno' has is going to be the
// complete and true value any thread set.
// However, it is not guaranteed to be the value
// `DoSomething1' set because another thread may
// have changed the value after `DoSomething1' set the
// value but before we were able to examine it here.
printf("%d", errno);
}
// ...
}
Code:
__attribute__((__tls__)) int errno;
bool DoSomething1()
{
// ...
if(/* ??? */)
{
errno = 1;
return(false);
}
// ...
}
void DoSomething2()
{
// ...
errno = 0;
if(!DoSomething1())
{
// Because we have implemented `errno' in terms of
// thread local storage no other threads can
// have modified `errno'. We have the exact `errno'
// value `DoSomething1' set.
printf("%d", errno);
}
// ...
}
Soma