bug report: pthread_delay_np provided library compilation provides only 1 second actual resolution??

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

bug report: pthread_delay_np provided library compilation provides only 1 second actual resolution??

David Taylor
Unlikely as this sounds, I found what would appear to be a
pthreads-win32 provided library original compiler error.
Using gdb, I traced into pthread_delay_np() (in assembly mode). The
WaitForSingleObject is getting passed a millisecond parameter floored to
the second.


//BROKEN (STOCK mingw pthread DLL) - any delay less than a second is
rounded to 0
// cmd.exe
// \MinGW\bin\gcc -g -o pthread3 pthread3.c -lwinmm -lpthread

//WORKS (STATIC debug build library from sourceforge sourcecode) good to
millisecond accuracy
// cmd.exe
// cd ptw32\pthreads-w32-2-9-1-release\pthreads.2
// set HOME=.
// \mingw\msys\1.0\msys.bat
// make clean GC-static-debug
// exit
// copy pthreads3.c .
// \MinGW\bin\gcc -g -o pthread3 -DPTW32_STATIC_LIB pthread3.c pthread.o
-lwinmm
//(gdb) directory ptw32\pthreads-w32-2-9-1-release\pthreads.3


#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include "pthread.h"
#include <stdio.h>

struct timespec tim1   = { 0,   10000000 /*ns*/};    //10ms or 900ms, it
doesn't matter...
//struct timespec tim1   = { 1,   0 /*ns*/};

void * __attribute__((__cdecl__)) hello(void *id)
{    int i, rc=0;
     DWORD startime, endtime, lapsetime;

     startime=endtime = timeGetTime() ;
     for (i=0; i<=5; ++i) {
         printf("%d: Hello world! %d %d t%d\n", *((int*)
id),rc,i,endtime-startime);    //after the first pass, the last number
printed SHOULD match tim1(in milliseconds)
         startime=endtime;
         rc=pthread_delay_np(&tim1);    //const struct timespec
*deltatime    //only seconds working
         endtime = timeGetTime() ;
     }
     return;
}

int main(int argc, char* argv[])
{
     const int COUNT = 5;
     int i, retval,rc;
     pthread_attr_t attr;
     pthread_t thread[COUNT];
     int ids[COUNT];

     rc = pthread_attr_init(&attr);
     rc = pthread_attr_setschedpolicy(&attr, SCHED_RR);
     printf("attr_setdetachedstate: %d\n",rc);

     for (i = 0; i < COUNT; i++) {
         ids[i] = i;
         retval = pthread_create(&thread[i], &attr, hello, &ids[i]);
         if (retval) {
             perror("pthread_create failed");
             return 1;
         }
     }
     for (i = 0; i < COUNT; i++)
         pthread_join(thread[i], NULL);

     return 0;
}


pthread_delay_np.c source with commentary edits marked DTAYLOR follows:
int
pthread_delay_np (struct timespec *interval)
{
   DWORD wait_time;
   DWORD secs_in_millisecs;
   DWORD millisecs;
   DWORD status;
   pthread_t self;
   ptw32_thread_t * sp;

   if (interval == NULL)
     {
       return EINVAL;
     }

   if (interval->tv_sec == 0L && interval->tv_nsec == 0L)
     {
       pthread_testcancel ();
       Sleep (0);
       pthread_testcancel ();
       return (0);
     }

   /* convert secs to millisecs */
   secs_in_millisecs = (DWORD)interval->tv_sec * 1000L; //DTAYLOR the
assembly sequence performing the next two lines is rather opaque and
apparently wrong

   /* convert nanosecs to millisecs (rounding up) */
   millisecs = (interval->tv_nsec + 999999L) / 1000000L;

#if defined(__WATCOMC__)
#pragma disable_message (124)
#endif

   /*
    * Most compilers will issue a warning 'comparison always 0'
    * because the variable type is unsigned, but we need to keep this
    * for some reason I can't recall now.
    */
   if (0 > (wait_time = secs_in_millisecs + millisecs))
     {
       return EINVAL;
     }

#if defined(__WATCOMC__)
#pragma enable_message (124)
#endif

   if (NULL == (self = pthread_self ()).p)
     {
       return ENOMEM;
     }

   sp = (ptw32_thread_t *) self.p;

   if (sp->cancelState == PTHREAD_CANCEL_ENABLE)
     {
       /*
        * Async cancelation won't catch us until wait_time is up.
        * Deferred cancelation will cancel us immediately.
        */
       if (WAIT_OBJECT_0 ==
       (status = WaitForSingleObject (sp->cancelEvent, wait_time)))    
//DTAYLOR WaitForSingleObject is actually being called with wait_time=0
     {
           ptw32_mcs_local_node_t stateLock;
       /*
        * Canceling!
        */
       ptw32_mcs_lock_acquire (&sp->stateLock, &stateLock);
       if (sp->state < PThreadStateCanceling)
         {
           sp->state = PThreadStateCanceling;
           sp->cancelState = PTHREAD_CANCEL_DISABLE;
           ptw32_mcs_lock_release (&stateLock);

           ptw32_throw (PTW32_EPS_CANCEL);
         }

       ptw32_mcs_lock_release (&stateLock);
       return ESRCH;
     }
       else if (status != WAIT_TIMEOUT)
     {
       return EINVAL;
     }
     }
   else
     {
       Sleep (wait_time);
     }

   return (0);
}




mingw installed from GUI installation manager sometime in the last six
months.

using cmd.exe under win8

gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/4.8.1/lto-wrapper.exe
Target: mingw32
Configured with: ../gcc-4.8.1/configure --prefix=/mingw --host=mingw32
--build=m
ingw32 --without-pic --enable-shared --enable-static --with-gnu-ld
--enable-lto
--enable-libssp --disable-multilib
--enable-languages=c,c++,fortran,objc,obj-c++
,ada --disable-sjlj-exceptions --with-dwarf2 --disable-win32-registry
--enable-l
ibstdcxx-debug --enable-version-specific-runtime-libs
--with-gmp=/usr/src/pkg/gm
p-5.1.2-1-mingw32-src/bld
--with-mpc=/usr/src/pkg/mpc-1.0.1-1-mingw32-src/bld --
with-mpfr= --with-system-zlib --with-gnu-as --enable-decimal-float=yes
--enable-
libgomp --enable-threads --with-libiconv-prefix=/mingw32
--with-libintl-prefix=/
mingw --disable-bootstrap LDFLAGS=-s CFLAGS=-D_USE_32BIT_TIME_T
Thread model: win32
gcc version 4.8.1 (GCC)

d -v
GNU ld (GNU Binutils) 2.24

_mingw.h
#define __MINGW32_VERSION           3.20

GUI installation manager reports the following installed:
mingw-pthreads-w32    2.9.1-1
mingw-pthreads-w32api  3.17-2


------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
_______________________________________________
MinGW-users mailing list
[hidden email]

This list observes the Etiquette found at
http://www.mingw.org/Mailing_Lists.
We ask that you be polite and do the same.  Disregard for the list etiquette may cause your account to be moderated.

_______________________________________________
You may change your MinGW Account Options or unsubscribe at:
https://lists.sourceforge.net/lists/listinfo/mingw-users
Also: mailto:[hidden email]?subject=unsubscribe