On Thu, 2005-04-21 at 16:07 +0200, Uenal Mutlu wrote:
I've tried the latest 2 pthreads releases with MS compilers.
VC++6 passes all tests, but VC++2005 fails with about 26 of the
test programs (tested only in beta 1, beta 2 is out since last monday
or so but I don't have it yet).
The first one of the failing test programs is semaphore1.c, line 89:
nmake clean VC
...
... Running VC test: mutex1r.exe
...... Passed
cl /D__CLEANUP_C /O2 /Ob0 /W3 /WX /MD /nologo /Yd /Zi -I. semaphore1.c /Fesemaphore1.exe /link /INCREMENTAL:NO pthreadVC2.lib
ws2_32.lib
cl : Command line warning D9035 : option 'Yd' has been deprecated and will be removed in a future release
semaphore1.c
... Running VC test: semaphore1.exe
thread: sem_trywait 1: expected error: No error
Assertion failed: (errno == EAGAIN), file semaphore1.c, line 89
NMAKE : fatal error U1077: '.\semaphore1.exe' : return code '0x1'
Stop.
NMAKE : fatal error U1077: 'nmake' : return code '0x2'
Stop.
Strange. It was previously reported that all tests passed with VC++ 2005
beta:
http://sources.redhat.com/ml/pthreads-win32/2005/msg00035.html
Also reported as passing using VC++ 8.0 and VS .NET 2003.
Below is the function from semaphore1.c where the error occurs.
It is the line
assert(errno == EAGAIN);
I wonder where errno gets set to this value.
Is it done in sem_trywait() or maybe in perror()?
And frankly I don't understand how the below code works at all
because that branch is entered only if result is -1. The funny
thing here (for me) is that then the program should stop in the
previous assert(), but this isn't happening! Then I wonder how
and why the if condition becomes true...
[See my comments later re perror.]
The test is expecting EAGAIN to be set by sem_trywait(). Since the
semaphore was initialised to 0, sem_trywait should return EAGAIN to
indicate that it would have had to wait.
But the output is saying that after sem_trywait returns -1, errno is 0
('no error'). So it seems as if errno may not be correctly defined in
pthread.h and is conflicting with how it's supposed to work with VC+
+2005 - and is not thread-safe as a result.
Usually errno is defined as:
#define errno *errno()
where errno() is a function that returns a pointer to a thread-specific
errno location.
I don't have access to VC++2005 so won't be able to fix this and test
that it works afterwards. If you (or anyone else can) it would sure
help. I have a similar problem with the Borland and Watcom compilers,
and I just can't figure out what I need to do to fix it.
void *
thr(void * arg)
{
sem_t s;
int result;
assert(sem_init(&s, PTHREAD_PROCESS_PRIVATE, 0) == 0);
assert((result = sem_trywait(&s)) == -1);
if ( result == -1 )
{
perror("thread: sem_trywait 1: expected error"); // No error
assert(errno == EAGAIN);
}
...
I have posted this issue also in
news://news.microsoft.com/microsoft.public.dotnet.languages.vc
under the subject "VC++ 2005 beta1 fails with pthreads benchmark tests"
but the MS guys say the code is broken. Maybe someone could clarify this.
Hmmm, my Googling just now hit on this discussion between UM (you?) and
someone else. Is this the same discussion as the news link you gave:
http://www.codecomments.com/forum292/message465116-2.html
Apart from the unhelpful and highly defensive/diversionary comments from
the other guy about assert abuse etc., I agree that errno should
probably not be read again after the perror call. The standard doesn't
say that perror should preserve errno - only that perror doesn't return
a value and that no errors are defined for it. I'll change the tests.
By the way, here's some code from the MSDN perror web page:
http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/vclib/html/_crt_perror.2c_._wperror.asp
Note that it expects errno to be preserved through the perror() call
too.
// crt_perror.c
/* This program attempts to open a file named
* NOSUCHF.ILE. Because this file probably doesn't exist,
* an error message is displayed. The same message is
* created using perror, strerror, and _strerror.
*/
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main( void )
{
int fh;
if( (fh = _open( "NOSUCHF.ILE", _O_RDONLY )) == -1 )
{
/* Three ways to create error message: */
perror( "perror says open failed" );
printf( "strerror says open failed: %s\n", strerror( errno ) );
printf( _strerror( "_strerror says open failed" ) );
}
else
{
printf( "open succeeded on input file\n" );
_close( fh );
}
}
Ross