public inbox for pthreads-win32@sourceware.org
 help / color / mirror / Atom feed
* Problem with pthread_cond_timedwait()
@ 2005-09-27 11:13 Fu Limin
  2005-09-27 13:16 ` Dmitrii Sernii
  0 siblings, 1 reply; 7+ messages in thread
From: Fu Limin @ 2005-09-27 11:13 UTC (permalink / raw)
  To: pthreads-win32

Hello,

There is a strange problem with pthread_cond_timedwait() in my program
using pthread-win32, I found it doesn't
wait at all. Here is part of the codes,

    struct timespec timeout;
    timeout.tv_sec = time(NULL) + 10;
    timeout.tv_nsec = 0;

    pthread_cond_timedwait( & myCondVar, & mutex->myMutex, &timeout );

This part works as expected under linux. The compiler I used is gcc3.4.2,
and I used the pre-built pthread-win32, v2.7.
Am I using pthread_cond_timedwait() properly?

Another question, I saw in pthread documentations that the "timeout" is
prepare in the following way,

struct timeval now;
struct timespec timeout;

gettimeofday(&now);
timeout.tv_sec = now.tv_sec + 5;
timeout.tv_nsec = now.tv_usec * 1000;

But I found it won't work without modification, in Linux, it complain
gettimeofday() needs another parameter
(something like timezone, if I remember well), and in Windows the compiler
complain gettimeofday() is not
defined. So what is the "most" standard or correct way to prepare "timeout"?

Thanks a lot,

Limin

PS, I was trying to send this email by my gmail account,
but it didn't work with this mailling list.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Problem with pthread_cond_timedwait()
  2005-09-27 11:13 Problem with pthread_cond_timedwait() Fu Limin
@ 2005-09-27 13:16 ` Dmitrii Sernii
       [not found]   ` <1130.130.192.136.198.1127830895.squirrel@130.192.136.198>
  0 siblings, 1 reply; 7+ messages in thread
From: Dmitrii Sernii @ 2005-09-27 13:16 UTC (permalink / raw)
  To: pthreads-win32

Hello,

The problem here is that pthread_cond_timedwait takes absolute time,
but you passed relative timeout.

to make pthread_cond_timedwait waike up after you called it, you need
to get current time, and then add timeout you need.
In the sampe you provide your pthread_cond_timedwait waikes up before
it actually starts.

Under win32 you can use GetLocalTime to retieve current time.

Tuesday, September 27, 2005, 2:12:58 PM, you wrote:

FL> Hello,

FL> There is a strange problem with pthread_cond_timedwait() in my program
FL> using pthread-win32, I found it doesn't
FL> wait at all. Here is part of the codes,

FL>     struct timespec timeout;
FL>     timeout.tv_sec = time(NULL) + 10;
FL>     timeout.tv_nsec = 0;

FL>     pthread_cond_timedwait( & myCondVar, & mutex->myMutex, &timeout );

FL> This part works as expected under linux. The compiler I used is gcc3.4.2,
FL> and I used the pre-built pthread-win32, v2.7.
FL> Am I using pthread_cond_timedwait() properly?

FL> Another question, I saw in pthread documentations that the "timeout" is
FL> prepare in the following way,

FL> struct timeval now;
FL> struct timespec timeout;

FL> gettimeofday(&now);
FL> timeout.tv_sec = now.tv_sec + 5;
FL> timeout.tv_nsec = now.tv_usec * 1000;

FL> But I found it won't work without modification, in Linux, it complain
FL> gettimeofday() needs another parameter
FL> (something like timezone, if I remember well), and in Windows the compiler
FL> complain gettimeofday() is not
FL> defined. So what is the "most" standard or correct way to prepare "timeout"?
FL> Thanks a lot,

FL> Limin

FL> PS, I was trying to send this email by my gmail account,
FL> but it didn't work with this mailling list.



-- 
Best regards,
 Dmitrii Sernii

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Problem with pthread_cond_timedwait()
       [not found]   ` <1130.130.192.136.198.1127830895.squirrel@130.192.136.198>
@ 2005-09-27 15:49     ` Dmitrii Sernii
  2005-09-28  8:38       ` Fu Limin
  0 siblings, 1 reply; 7+ messages in thread
From: Dmitrii Sernii @ 2005-09-27 15:49 UTC (permalink / raw)
  To: pthreads-win32

Hello,

for me this timeout makes cond_timedwait wait for 10 seconds:
        timespec timeout;
        timeout.tv_sec = time(0)+10;
        timeout.tv_nsec = 0;

Try to check return code of the pthread_cond_timedwait. Probably you
forgot to initialize mutex, or lock it before calling this function.

FL> SYSTEMTIME now;
FL> GetLocalTime( &now );
FL> timeout.tv_sec = now.wSecond + sec;
FL> timeout.tv_nsec = now.wMilliseconds*1E6 + nsec;
this code will not work, because wSeconds - maximum value is 59. To
use GetLocalTime you'll need to use all values starting from wYear..
multiply them on number of seconds they have and add to each other.


-- 
Best regards,
 Dmitrii Sernii

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Problem with pthread_cond_timedwait()
  2005-09-27 15:49     ` Dmitrii Sernii
@ 2005-09-28  8:38       ` Fu Limin
  0 siblings, 0 replies; 7+ messages in thread
From: Fu Limin @ 2005-09-28  8:38 UTC (permalink / raw)
  To: Dmitrii Sernii; +Cc: pthreads-win32

Hi Dmitrii,

Thank you very much!
The problem is solved after locking the mutex before calling the function.
I was trying to implement a sleep() function using pthread_cond_timedwait(),
so the thread calling this function will never be signaled. I thought the
using mutex is necessary only if pthread_cond_timedwait() is used together
with pthread_cond_signal/broadcast(). In fact, it works in Linux without
locking the mutex, so I thought it must be a problem of something else.

Best regards,

Limin

> Hello,
>
> for me this timeout makes cond_timedwait wait for 10 seconds:
>         timespec timeout;
>         timeout.tv_sec = time(0)+10;
>         timeout.tv_nsec = 0;
>
> Try to check return code of the pthread_cond_timedwait. Probably you
> forgot to initialize mutex, or lock it before calling this function.
>
> FL> SYSTEMTIME now;
> FL> GetLocalTime( &now );
> FL> timeout.tv_sec = now.wSecond + sec;
> FL> timeout.tv_nsec = now.wMilliseconds*1E6 + nsec;
> this code will not work, because wSeconds - maximum value is 59. To
> use GetLocalTime you'll need to use all values starting from wYear..
> multiply them on number of seconds they have and add to each other.
>
>
> --
> Best regards,
>  Dmitrii Sernii
>
>


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Problem with pthread_cond_timedwait().
  2002-07-22 21:19 Nir Nizry
  2002-07-24  0:31 ` Ross Johnson
@ 2002-07-31  0:13 ` Ross Johnson
  1 sibling, 0 replies; 7+ messages in thread
From: Ross Johnson @ 2002-07-31  0:13 UTC (permalink / raw)
  To: pthreads-win32

Hi all,

This is to let people know that Alexander Terekhov has located the 
problem, with a suspicion of possibly a deeper problem elsewhere 
(which will be investigated), and provided a fix which is now in the 
CVS repository.

The latest CVS tree has passed both the test suite and the test 
program used to illustrate the bug.

A new snapshot will be produced soon.

Regards.
Ross

Nir Nizry wrote:
> Hello All,
> 
> I have a problem with pthread_cond_timedwait().
> I have a system with 5 threads that in their main loop wait with a timeout
> (timedwait) on a condition variable to be set.
> what I get is, that sometimes a thread enters the pthread_cond_timedwait()
> function, and doesn't come out, even if the timeout time arrives. after this
> happens, the other threads get stuck in the mutex lock before entering the
> pthread_cond_timedwait() as if the mutex is already locked.
> 
> I suspect that somehow either the pthread_cond_timedwait() function does not
> release the mutex or does not return when the timeout occurs.
> 
> does someone have an idea' or know of such an incident (or maybe a bug in
> pthread)??
> 
> Thanks.
> 
> Nir.
> 
> I added the code fraction where it get stucked (this is the ONLY place in
> the code where the messageMutex is locked):
> 
> 
> pthread_mutex_lock(messageMutex);
> 
> waitResult = 0;
> while( m_theGeneralQueue->isEmpty() && !shouldStopThreadGlobalLoop &&
> (waitResult != ETIMEDOUT))
> 	waitResult = pthread_cond_timedwait(newMessageEvent, messageMutex,
> &timeout);
> 
> pthread_mutex_unlock(messageMutex);
> 
> 
> -----------------------------------------
> 
> mailto:nir.nizry@bluesoft-inc.com
> 
> -----------------------------------------


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Problem with pthread_cond_timedwait().
  2002-07-22 21:19 Nir Nizry
@ 2002-07-24  0:31 ` Ross Johnson
  2002-07-31  0:13 ` Ross Johnson
  1 sibling, 0 replies; 7+ messages in thread
From: Ross Johnson @ 2002-07-24  0:31 UTC (permalink / raw)
  To: pthreads-win32, nir.nizry

[-- Attachment #1: Type: text/plain, Size: 3198 bytes --]

This is the same problem as reported several months ago by
Paul Joseph - see

http://sources.redhat.com/ml/pthreads-win32/2002/msg00038.html

Nir's description is pretty accurate.

This is a fairly critical bug now, so any help would really be 
appreciated.

At the time, I attempted to locate the problem but failed and 
haven't looked at it since. Here's what I found at the time by 
modifying and running Paul's test code:

	... running on a single CPU machine under Windows 98.

	- it hasn't hung when there are only one send and
	  receive thread;
	
	- there is no mutex deadlock occuring (i.e. same
	  thread attempting to lock the mutex twice). That
	  can be seen by looking at the code, but it was
	  confirmed by using errorcheck mutexes;
	
	- it's not compiler dependent. Both MSVC and GNU C
	  versions hang;
	
	- it's random;
	
	- the process doesn't hang, but all threads appear
	  to block;
	
	- all send threads stop when they block on the
	  mutex lock. Thus one receive thread hanging
	  will effectively stop all send threads, which
	  in turn will stop all remaining receive threads;
	
	It appears that something is causing the mutex
	not to be unlocked at some point, and all threads
	consequently block on the mutex lock.

I've attached the modified test code in case someone has time to 
look at it. 99% of the code is just execution tracing. You'll have 
to see the code to interpret the log output though (unfortunately).

Ross

Nir Nizry wrote:
 > Hello All,
 >
 > I have a problem with pthread_cond_timedwait().
 > I have a system with 5 threads that in their main loop wait with 
a timeout
 > (timedwait) on a condition variable to be set.
 > what I get is, that sometimes a thread enters the 
pthread_cond_timedwait()
 > function, and doesn't come out, even if the timeout time arrives. 
after this
 > happens, the other threads get stuck in the mutex lock before 
entering the
 > pthread_cond_timedwait() as if the mutex is already locked.
 >
 > I suspect that somehow either the pthread_cond_timedwait() 
function does not
 > release the mutex or does not return when the timeout occurs.
 >
 > does someone have an idea' or know of such an incident (or maybe 
a bug in
 > pthread)??
 >
 > Thanks.
 >
 > Nir.
 >
 > I added the code fraction where it get stucked (this is the ONLY 
place in
 > the code where the messageMutex is locked):
 >
 >
 > pthread_mutex_lock(messageMutex);
 >
 > waitResult = 0;
 > while( m_theGeneralQueue->isEmpty() && !shouldStopThreadGlobalLoop &&
 > (waitResult != ETIMEDOUT))
 > 	waitResult = pthread_cond_timedwait(newMessageEvent, messageMutex,
 > &timeout);
 >
 > pthread_mutex_unlock(messageMutex);
 >
 >
 > -----------------------------------------
 >
 > mailto:nir.nizry@bluesoft-inc.com
 >
 > -----------------------------------------


-- 
+-------------------------+---+
| Ross Johnson            |   | "Come down off the cross
| Management & Technology |___|  We can use the wood" - Tom Waits
| Building 11                 |
| University of Canberra      | eMail: rpj@ise.canberra.edu.au
| ACT    2601                 | WWW:
http://public.ise.canberra.edu.au/~rpj/
| AUSTRALIA                   |
+-----------------------------+

[-- Attachment #2: condvar10.c --]
[-- Type: text/plain, Size: 14498 bytes --]

/*
Command line options are (in this order):
  Number of Sender threads
  Number of Receiver threads
  CV wait time (microsecs)
  Trace level
  Sender sleeps (bool)
  Receiver sleeps (bool)
  Monitor rate (per second)

  E.g.
	condvar10.exe 8 8 1000000 -10 1 0 10

  Log info is to 'condvar10.log'.

 */

#include <stdio.h>
#include <sys/timeb.h>
#include <stdlib.h>
#include <signal.h>
#include "condvar10.h"

char * logFile = "condvar10.log";

const DWORD MILLISEC_PER_SEC	 = 1000L;
const DWORD MICROSEC_PER_NANOSEC = 1000L;
const DWORD NANOSEC_PER_MILLISEC = 1000000L;
const DWORD MICROSEC_PER_SEC	 = 1000000L;
const DWORD NANOSEC_PER_SEC	 = 1000000000L;

enum {
  Receiver = 0,
  Sender,
  MaxThreads = 100
};

pthread_t	 tid[2][MaxThreads];

typedef struct thrState_t_ {
  int		   op;
  int		   watchdog;
  int		   signalled;
  pthread_mutex_t  opLock;
} thrState_t;

thrState_t	 thrState[2][MaxThreads];

void*		 recvReq(void *arg);
void*		 sendReq(void *arg);
void		 SendData();
void		 RecvData();
int		 msg=0;
int		 trace=1;
int		 sendSleep=0;
int		 recvSleep=0;
int		 monitorRate=10;

DWORD		 monitorInterval;
DWORD		 counter=0;
DWORD		 lastCount=0;
DWORD		 received=0;
DWORD		 TOs=0;

pthread_mutex_t  lock;
pthread_cond_t	 sig;
int		 noSthr = 1;
int		 noRthr = 1;
DWORD		 timeint = 5*MICROSEC_PER_SEC; // 5 sec
int		 ThreadRecvCount[MaxThreads];
int		 ThreadTOCount[MaxThreads];
int		 ThreadSentCount[MaxThreads];

enum Operations {
  SLock 	 = 0x00000001,
  ELock 	 = 0x00000002,
  SUnlock	 = 0x00000010,
  EUnlock	 = 0x00000020,
  SWait 	 = 0x00000100,
  EWait 	 = 0x00000200,
  WaitTimeout	 = 0x00000400,
  SSignal	 = 0x00001000,
  ESignal	 = 0x00002000,
  MsgFalse	 = 0x40000000,
  MsgTrue	 = 0x80000000,
};

void RecvData(int threadNum);
void SendData(int threadNum);
void * recvReq(void *arg);
void * sendReq(void *arg);

pthread_mutex_t LOGX;

#define OPENLOG(_openMode) \
  { \
    FILE * LOGFP; \
    (void)pthread_mutex_lock(&LOGX); \
    if ((LOGFP=fopen(logFile, _openMode)) == NULL) \
      { \
	fprintf(stdout, "Line %d: Log open error\n", __LINE__); \
	fflush(stdout); \
      } \
    else \
      {

#define CLOSELOG(_exitAfterClose) \
	fclose(LOGFP); \
	if(_exitAfterClose) exit(1); \
      } \
    (void)pthread_mutex_unlock(&LOGX); \
  }

#define LOGERR \
  { \
    if(status!=0) \
      { \
	OPENLOG("a"); \
	fprintf(LOGFP,"Error at line %d, status %d\n",__LINE__, status); \
	CLOSELOG(1); \
      } \
  }

void PR (char *s)
{
  long id;

  if(trace>0)
    {
      id=GetCurrentThreadId ();

      OPENLOG("a");
      fprintf(LOGFP,"TH-%lx:%s\n",id,s);
      CLOSELOG(0);
    }
}

void SetOp(int SR, int threadNum, int op)
{
  int status = pthread_mutex_lock(&thrState[SR][threadNum].opLock);
  LOGERR;
  thrState[SR][threadNum].op = op;
  status = pthread_mutex_unlock(&thrState[SR][threadNum].opLock);
  LOGERR;
}

void OrOp(int SR, int threadNum, int op)
{
  int status = pthread_mutex_lock(&thrState[SR][threadNum].opLock);
  LOGERR;
  thrState[SR][threadNum].op |= op;
  status = pthread_mutex_unlock(&thrState[SR][threadNum].opLock);
  LOGERR;
}

void SetWatchdog(int SR, int threadNum, int woof)
{
  int status = pthread_mutex_lock(&thrState[SR][threadNum].opLock);
  LOGERR;
  thrState[SR][threadNum].watchdog = woof;
  status = pthread_mutex_unlock(&thrState[SR][threadNum].opLock);
  LOGERR;
}

BOOL logPoint(long increment)
{
  if (counter >= lastCount + increment)
    {
      lastCount = counter;
      return TRUE;
    }

  return FALSE;
}

void PrintOptions (FILE * fp)
{
  fprintf(fp, "Options are (in this order):\n");
  fprintf(fp, "  %-30s: %8ld\n", "Number of Sender threads", noSthr);
  fprintf(fp, "  %-30s: %8ld\n", "Number of Receiver threads", noRthr);
  fprintf(fp, "  %-30s: %8ld\n", "CV wait time (microsecs)", timeint);
  fprintf(fp, "  %-30s: %8ld\n", "Trace level", trace);
  fprintf(fp, "  %-30s: %8ld\n", "Sender sleeps (bool)", sendSleep);
  fprintf(fp, "  %-30s: %8ld\n", "Receiver sleeps (bool)", recvSleep);
  fprintf(fp, "  %-30s: %8ld\n", "Monitor rate (per second)", monitorRate);
  putc('\n',fp);
}

int
main(int argc , char * argv[])
{
  pthread_mutexattr_t la;
  int		      status;
  int		      ii;
  DWORD 	      milliseconds = 0;
  DWORD 	      lastSendWatch = 0;
  DWORD 	      lastRecvWatch = 0;
  int		      r = 0;
  DWORD 	      seconds = 0;
  DWORD 	      lastLogSeconds = 0;
  char *	      rotor = "/-\\|";

  if(argc>1)
    {
      noSthr=atoi(argv[1]);
      if (noSthr >= MaxThreads)
	{
	  printf("Requested too many Secnder threads = %d. Max is %d\n", noSthr, MaxThreads);
	  exit(1);
	}
    }
  if(argc>2)
    {
      noRthr=atoi(argv[2]);
      if (noRthr >= MaxThreads)
	{
	  printf("Requested too many Receiver threads = %d. Max is %d\n", noRthr, MaxThreads);
	  exit(1);
	}
    }
  if(argc>3)
    {
      timeint=atoi(argv[3]);
    }
  if(argc>4)
    {
      trace=atoi(argv[4]);
    }
  if(argc>5)
    {
      sendSleep=atoi(argv[5]);
    }
  if(argc>6)
    {
      recvSleep=atoi(argv[6]);
    }
  if(argc>7)
    {
      monitorRate=atoi(argv[7]);
      // Round to nearest 10 so that 1000ms (1 sec) is a multiple of the interval
      monitorRate=((monitorRate+5)/10)*10;
    }

  monitorInterval = MILLISEC_PER_SEC/monitorRate;

  if (pthread_mutexattr_init(&la) != 0
      || pthread_mutexattr_settype(&la, PTHREAD_MUTEX_ERRORCHECK) != 0
      || pthread_mutex_init(&LOGX, &la) != 0)
    {
      printf("Line %d: Error initialising log mutex.\n", __LINE__);
      exit(1);
    }

  status = pthread_mutex_init(&lock, &la);
  LOGERR;
  status = pthread_cond_init(&sig, NULL);
  LOGERR;

  PrintOptions(stdout);
  fflush(stdout);
  OPENLOG("w");
  PrintOptions(LOGFP);
  CLOSELOG(0);

  for(ii = 0; ii < noRthr; ii++)
    {
      status = pthread_mutex_init(&thrState[Receiver][ii].opLock, &la);
      LOGERR;
      status = pthread_create(&tid[Receiver][ii], NULL, (PTHREAD_START_ROUTINE_DECL)&recvReq, (void *)ii);
      LOGERR;
    }
  for(ii = 0; ii < noSthr; ii++)
    {
      status = pthread_mutex_init(&thrState[Sender][ii].opLock, &la);
      LOGERR;
      status = pthread_create(&tid[Sender][ii], NULL, (PTHREAD_START_ROUTINE_DECL)&sendReq, (void *)ii);
      LOGERR;
    }

  status = pthread_mutexattr_destroy(&la);
  LOGERR;

  while(1) //Monitor threads until they hang
    {
      int stillRunning;
      BOOL newSecond;

      Sleep(monitorInterval);
      milliseconds+=monitorInterval;
      newSecond = (milliseconds >= MILLISEC_PER_SEC);

      putchar(rotor[r=((r++)&0x3)]);
      putchar('\b');

      // Log Sends and Receives/Timeouts
      if (trace > 0
	  || (trace < 0 && trace >= -5000
	      && (logPoint(-trace) || seconds > lastLogSeconds + 1 /* At least 1 second */)))
	{
	  int ii;

	  lastLogSeconds = seconds;

	  OPENLOG("a");
	  fprintf(LOGFP,"count=%010ld, Thr/Recvd/TOs",
			counter);

	  for (ii=0;ii<noRthr;ii++)
	    {
	      fprintf(LOGFP, " %d/%04d/%04d",
			     ii,
			     ThreadRecvCount[ii],
			     ThreadTOCount[ii]);

	      ThreadRecvCount[ii]=0;
	      ThreadTOCount[ii]=0;
	    }
	  fprintf(LOGFP," : Thr/Sent");
	  for (ii=0;ii<noSthr;ii++)
	    {
	      fprintf(LOGFP, " %d/%04d",
			     ii,
			     ThreadSentCount[ii]);

	      ThreadSentCount[ii]=0;
	    }
	  putc('\n',LOGFP);
	  CLOSELOG(0);
	}

      // Check for hung threads.
      stillRunning=noSthr;
      if (!sendSleep
	  || seconds > (lastSendWatch + (2*timeint/MICROSEC_PER_SEC)))
	{
	  for (ii=0;ii<noSthr;ii++)
	    {
	      status = pthread_mutex_lock(&thrState[Sender][ii].opLock);
	      LOGERR;
	      if (thrState[Sender][ii].signalled == 0)
		{
		  OPENLOG("a");
		  fprintf(LOGFP, "Thread %2d: didn't emit signal.\n",
				 ii);
		  CLOSELOG(0);
		}

	      thrState[Sender][ii].signalled = 0;

	      if (thrState[Sender][ii].watchdog == 0)
		{
		  stillRunning--;
		  OPENLOG("a");
		  fprintf(LOGFP, "Thread %d: Sender operation trace: 0x%x\n",
				 ii,
				 thrState[Sender][ii].op);
		  CLOSELOG(0);
		}
	      status = pthread_mutex_unlock(&thrState[Sender][ii].opLock);
	      LOGERR;
	    }
	  if (stillRunning==0)
	    {
	      OPENLOG("a");
	      fprintf(LOGFP,"Line %d: exit.\n", __LINE__);
	      CLOSELOG(0);
	      exit(1);
	    }
	}

      if (!(recvSleep || sendSleep)
	  || (recvSleep && seconds > (lastRecvWatch + (2*timeint/MICROSEC_PER_SEC)))
	  || (sendSleep && seconds > (lastSendWatch + (2*timeint/MICROSEC_PER_SEC))))
	{
	  stillRunning=noRthr;
	  for (ii=0;ii<noRthr;ii++)
	    {
	      status = pthread_mutex_lock(&thrState[Receiver][ii].opLock);
	      LOGERR;
	      if (thrState[Receiver][ii].watchdog == 0)
		{
		  stillRunning--;
		  OPENLOG("a");
		  fprintf(LOGFP, "Thread %d: Receiver operation trace: 0x%x\n",
				 ii,
				 thrState[Receiver][ii].op);
		  CLOSELOG(0);
		}
	      status = pthread_mutex_unlock(&thrState[Receiver][ii].opLock);
	      LOGERR;
	    }
	  if (stillRunning==0)
	    {
	      OPENLOG("a");
	      fprintf(LOGFP,"Line %d: exit.\n", __LINE__);
	      CLOSELOG(0);
	      exit(1);
	    }
	}

      if (newSecond)
	{
	  milliseconds = 0;
	  seconds++;
	  OPENLOG("a");
	  fprintf(LOGFP, "==Seconds=[%ld]==Msg=[%d]==Count=[%ld]==Received=[%ld]==TOs=[%ld]====\n", \
			 seconds,
			 msg,
			 counter,
			 received,
			 TOs);

	  for (ii=0;ii<noRthr;ii++)
	    {
	      fprintf(LOGFP, " %d/%04d/%04d",
			     ii,
			     ThreadRecvCount[ii],
			     ThreadTOCount[ii]);

	      ThreadRecvCount[ii]=0;
	      ThreadTOCount[ii]=0;
	    }
	  fprintf(LOGFP," : Thr/Sent");
	  for (ii=0;ii<noSthr;ii++)
	    {
	      fprintf(LOGFP, " %d/%04d",
			     ii,
			     ThreadSentCount[ii]);

	      ThreadSentCount[ii]=0;
	    }
	  putc('\n',LOGFP);

	  for (ii=0;ii<noSthr;ii++)
	   {
	      status = pthread_mutex_lock(&thrState[Sender][ii].opLock);
	      LOGERR;
	      fprintf(LOGFP, "S%d/0x%x ",
			     ii,
			     thrState[Sender][ii].op);
	      status = pthread_mutex_unlock(&thrState[Sender][ii].opLock);
	      LOGERR;
	    }
	  putc('\n',LOGFP);
	  for (ii=0;ii<noRthr;ii++)
	    {
	      status = pthread_mutex_lock(&thrState[Receiver][ii].opLock);
	      LOGERR;
	      fprintf(LOGFP, "R%d/0x%x ",
			     ii,
			     thrState[Receiver][ii].op);
	      status = pthread_mutex_unlock(&thrState[Receiver][ii].opLock);
	      LOGERR;
	    }
	  putc('\n',LOGFP);

	  CLOSELOG(0);

	  // Reset watchdogs
#if 1
	  if (!sendSleep
	      || (sendSleep && seconds > (lastSendWatch + (2*timeint/MICROSEC_PER_SEC))))
	    {
	      lastSendWatch = seconds;
	      for (ii=0;ii<noSthr;ii++)
		{
		  SetWatchdog(Sender,ii,0);
		}
	    }
	  if (!(recvSleep || sendSleep)
	      || (recvSleep && seconds > (lastRecvWatch + (2*timeint/MICROSEC_PER_SEC)))
	      || (sendSleep && seconds > (lastSendWatch + (2*timeint/MICROSEC_PER_SEC))))
	    {
	      lastRecvWatch = seconds;
	      for (ii=0;ii<noRthr;ii++)
		{
		  SetWatchdog(Receiver,ii,0);
		}
	    }
#endif
	}
    }
  return 0;
}

/////////////
void *
sendReq(void *arg)
{
  int thr = (int)arg;
  DWORD sleepTime_ms = (2*timeint*MILLISEC_PER_SEC)/MICROSEC_PER_SEC;

  OPENLOG("a");
  fprintf(LOGFP, "Sender Thread %2d id %lx started:", thr, GetCurrentThreadId());
  if (sendSleep)
    {
      fprintf(LOGFP, " sleep time %ld ms", sleepTime_ms);
    }
  putc('\n', LOGFP);
  CLOSELOG(0);

  thrState[Sender][thr].watchdog = 1;
  thrState[Sender][thr].signalled = 0;

  while(1)
    {
      SetWatchdog(Sender,thr,1);
      SendData(thr);
      // Note: If timeint < 500 microseconds we just yield the CPU
      // with Sleep(0).
      if (sendSleep)
	{
	  Sleep(sleepTime_ms);
	}
    }

  return 0;
}

/////////////
void
SendData(int threadNum)
{
  int status;

  SetOp(Sender,threadNum,SLock);
  status = pthread_mutex_lock(&lock);
  OrOp(Sender,threadNum,ELock);
  LOGERR;
  PR("lock -01");

  if(msg==0)
    {
      OrOp(Sender,threadNum,MsgFalse);
      msg=1;
      counter++;
      ThreadSentCount[threadNum]++;

      PR("unlock -01");
      OrOp(Sender,threadNum,SUnlock);
      status=pthread_mutex_unlock(&lock);
      OrOp(Sender,threadNum,EUnlock);
      LOGERR;
      PR("signal -01");
      OrOp(Sender,threadNum,SSignal);
      status = pthread_cond_signal(&sig);
      OrOp(Sender,threadNum,ESignal);
      LOGERR;
      thrState[Sender][threadNum].signalled++;
    }
  else
    {
      OrOp(Sender,threadNum,MsgTrue);
      PR("unlock -01");
      OrOp(Sender,threadNum,SUnlock);
      status=pthread_mutex_unlock(&lock);
      OrOp(Sender,threadNum,EUnlock);
      LOGERR;
    }
}

///////////////
void *
recvReq(void *arg)
{
  int thr = (int)arg;
  OPENLOG("a");
  fprintf(LOGFP, "Receiver Thread %2d id %lx started\n", thr, GetCurrentThreadId());
  CLOSELOG(0);

  thrState[Receiver][thr].watchdog = 1;
  ThreadRecvCount[thr]=0;
  ThreadTOCount[thr]=0;

  while(1)
    {
      SetWatchdog(Receiver,thr,1);
      RecvData(thr);
      if (recvSleep)
	{
	  Sleep(0);
	}
    }

  return 0;
}

///////////////
void
RecvData(int threadNum)
{
  int status;

  SetOp(Receiver,threadNum,SLock);
  status = pthread_mutex_lock(&lock);
  OrOp(Receiver,threadNum,ELock);
  LOGERR;
  PR("lock -11");

  while (msg == 0)
    {
      struct timespec abstime;
      struct _timeb currSysTime;

      OrOp(Receiver,threadNum,MsgFalse);
      _ftime(&currSysTime);

      abstime.tv_sec = currSysTime.time;
      abstime.tv_nsec = NANOSEC_PER_MILLISEC * currSysTime.millitm;

//	printf("Now: %ld.%ld\n", abstime.tv_sec, abstime.tv_nsec);
//	fflush(stdout);

      abstime.tv_nsec += (timeint%MICROSEC_PER_SEC)*MICROSEC_PER_NANOSEC;
      if (abstime.tv_nsec >= NANOSEC_PER_SEC)
	{
	  abstime.tv_nsec -= NANOSEC_PER_SEC;
	  abstime.tv_sec++;
	}
      abstime.tv_sec += timeint/MICROSEC_PER_SEC;

//	printf("TO : %ld.%ld\n", abstime.tv_sec, abstime.tv_nsec);
//	fflush(stdout);

      PR("wait/unlock -11");
      OrOp(Receiver,threadNum,SWait);
      status = pthread_cond_timedwait(&sig, &lock, &abstime);
      OrOp(Receiver,threadNum,EWait);
      PR("lock/awake -11");

      if (status == ETIMEDOUT)
	{
	  ThreadTOCount[threadNum]++;
	  TOs++;
	  PR("timeout -11");
	  PR("unlock -11");
	  OrOp(Receiver,threadNum,WaitTimeout);
	  OrOp(Receiver,threadNum,SUnlock);
	  status=pthread_mutex_unlock(&lock);
	  OrOp(Receiver,threadNum,EUnlock);
	  LOGERR;
	  return ;
	}

      LOGERR;
    }

  if (msg==1)
    {
      OrOp(Receiver,threadNum,MsgTrue);
    }
  ThreadRecvCount[threadNum]++;
  msg=0;
  received++;

  PR("unlock -11");
  OrOp(Receiver,threadNum,SUnlock);
  status=pthread_mutex_unlock(&lock);
  OrOp(Receiver,threadNum,EUnlock);
  LOGERR;

  return ;
}


[-- Attachment #3: condvar10.h --]
[-- Type: type=text/plain, Size: 767 bytes --]

#ifndef _CONDVAR10_H
#define _CONDVAR10_H

#ifdef  __cplusplus
extern "C" {
#endif

#define pthread_attr_default (pthread_attr_t *) NULL
#define pthread_mutexattr_default (pthread_mutexattr_t *) NULL
#define pthread_condattr_default (pthread_condattr_t *) NULL

typedef void*(*PTHREAD_START_ROUTINE_DECL)(void*);

#include <semaphore.h>
#include <pthread.h>
#include <windows.h>

typedef struct
{
  long    tv_sec;
  long    tv_nsec;
} timestruc_t;

//The following macro is used take care of catch(...) present in
//thread code, as required by pthread library for NT when compiling
// with MSVC++.
#ifdef PtW32CatchAll
#define psCatch PtW32CatchAll
#else
#define psCatch catch(...)
#endif

#ifdef  __cplusplus
}
#endif

#endif


[-- Attachment #4: Makefile --]
[-- Type: text/plain, Size: 1637 bytes --]

CP	= copy
RM	= erase
MKDIR	= mkdir
TOUCH	= echo Passed >
ECHO	= @echo

CPHDR	= pthread.h semaphore.h sched.h

#OPTIM	= /O2 /Ob2
OPTIM		=

# C++ Exceptions
VCEFLAGS	= /GX /TP /DPtW32NoCatchWarn /D__CLEANUP_CXX
VCELIB	= ../lib/pthreadVCE.lib
VCEDLL	= pthreadVCE.dll
# Structured Exceptions
VSEFLAGS	= /D__CLEANUP_SEH
VSELIB	= ../lib/pthreadVSE.lib
VSEDLL	= pthreadVSE.dll
# C cleanup code
VCFLAGS	= /D__CLEANUP_C
VCLIB		= ../lib/pthreadVC.lib
VCDLL		= pthreadVC.dll
# C++ Exceptions in application - using VC version of pthreads dll
VCXFLAGS	= /GX /TP /D__CLEANUP_C

CFLAGS= $(OPTIM) /W3 /WX /MD /nologo /Yd /Zi -D_WIN32_WINNT=0x400
LFLAGS= /INCREMENTAL:NO
INCLUDES=-I. -I../include

COPYFILES	= $(CPHDR) $(CPLIB) $(CPDLL)

TEST		= condvar10.exe
EHFLAGS	=

default: VC

VCE:
	@ nmake CPLIB="$(VCELIB)" CPDLL="$(VCEDLL)" EHFLAGS="$(VCEFLAGS)" $(TEST)

VSE:
	@ nmake CPLIB="$(VSELIB)" CPDLL="$(VSEDLL)" EHFLAGS="$(VSEFLAGS)" $(TEST)

VC:
	@ nmake CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCFLAGS)" $(TEST)

VCX:
	@ nmake CPLIB="$(VCLIB)" CPDLL="$(VCDLL)" EHFLAGS="$(VCXFLAGS)" $(TEST)



.c.exe:
	@ $(ECHO) $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< /Fe$@ /link $(LFLAGS) $(CPLIB)
	@ $(CC) $(EHFLAGS) $(CFLAGS) $(INCLUDES) $< /Fe$@ /link $(LFLAGS) $(CPLIB)

.c.i:
	@ $(CC) /P $(VCEFLAGS) $(CFLAGS) $(INCLUDES) $<

$(COPYFILES):
	@ $(ECHO) Copying $@
	@ $(CP) $(BUILD_DIR)\$@ .

pthread.dll:
	@ $(CP) $(CPDLL) $*.dll
	@ $(CP) $(CPLIB) $*.lib

clean:
	- $(RM) *.e
	- $(RM) *.i
	- $(RM) *.obj
	- $(RM) *.pdb
	- $(RM) *.o
	- $(RM) *.asm
	- $(RM) *.exe
	- $(RM) *.log

[-- Attachment #5: GNUmakefile --]
[-- Type: text/plain, Size: 1142 bytes --]

CP	= copy
MV	= rename
RM	= erase
MKDIR	= mkdir
TOUCH	= echo Passed >
ECHO	= @echo
MAKE	= make

#
# Mingw32
#
GLANG	= c++
CC	= gcc
XXCFLAGS	= 
CFLAGS	= -O3 -g -UNDEBUG -Wall $(XXCFLAGS)
#CFLAGS	= -g -O0 -UNDEBUG -Wall $(XXCFLAGS)
INCLUDES	= -I. -I../include
LIBDIRS	= -L. -L../lib

GCX	= DUMMY
HDR	= pthread.h semaphore.h sched.h
LIB	= ../lib/libpthread$(GCX).a
DLL	= pthread$(GCX).dll

# If a test case returns a non-zero exit code to the shell, make will
# stop.

TEST	= condvar10.exe

GC:
	$(MAKE) GCX=GC XXCFLAGS="-x c -D__CLEANUP_C" $(TEST)

GCE:
	$(MAKE) GCX=GCE XXCFLAGS="-mthreads -x c++ -D__CLEANUP_CXX" $(TEST)

GCX:
	$(MAKE) GCX=GC XXCFLAGS="-mthreads -x c++ -D__CLEANUP_C" $(TEST)

%.exe: %.c
	@ $(ECHO) Compiling $@
	@ $(ECHO) $(CC) $(CFLAGS) -o $@ $^ $(INCLUDES) $(LIBDIRS) -lpthread$(GCX)
	@ $(CC) $(CFLAGS) -o $@ $^ $(INCLUDES) $(LIBDIRS) -lpthread$(GCX)

%.pre: %.c
	@ $(CC) -E $(CFLAGS) -o $@ $^ $(INCLUDES)

%.s: %.c
	@ $(CC) -S $(CFLAGS) -o $@ $^ $(INCLUDES)

clean:
	- $(RM) *.a
	- $(RM) *.e
	- $(RM) *.i
	- $(RM) *.obj
	- $(RM) *.pdb
	- $(RM) *.exe
	- $(RM) *.log

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Problem with pthread_cond_timedwait().
@ 2002-07-22 21:19 Nir Nizry
  2002-07-24  0:31 ` Ross Johnson
  2002-07-31  0:13 ` Ross Johnson
  0 siblings, 2 replies; 7+ messages in thread
From: Nir Nizry @ 2002-07-22 21:19 UTC (permalink / raw)
  To: pthreads-win32


Hello All,

I have a problem with pthread_cond_timedwait().
I have a system with 5 threads that in their main loop wait with a timeout
(timedwait) on a condition variable to be set.
what I get is, that sometimes a thread enters the pthread_cond_timedwait()
function, and doesn't come out, even if the timeout time arrives. after this
happens, the other threads get stuck in the mutex lock before entering the
pthread_cond_timedwait() as if the mutex is already locked.

I suspect that somehow either the pthread_cond_timedwait() function does not
release the mutex or does not return when the timeout occurs.

does someone have an idea' or know of such an incident (or maybe a bug in
pthread)??

Thanks.

Nir.

I added the code fraction where it get stucked (this is the ONLY place in
the code where the messageMutex is locked):


pthread_mutex_lock(messageMutex);

waitResult = 0;
while( m_theGeneralQueue->isEmpty() && !shouldStopThreadGlobalLoop &&
(waitResult != ETIMEDOUT))
	waitResult = pthread_cond_timedwait(newMessageEvent, messageMutex,
&timeout);

pthread_mutex_unlock(messageMutex);


-----------------------------------------

mailto:nir.nizry@bluesoft-inc.com

-----------------------------------------

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2005-09-28  8:38 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-09-27 11:13 Problem with pthread_cond_timedwait() Fu Limin
2005-09-27 13:16 ` Dmitrii Sernii
     [not found]   ` <1130.130.192.136.198.1127830895.squirrel@130.192.136.198>
2005-09-27 15:49     ` Dmitrii Sernii
2005-09-28  8:38       ` Fu Limin
  -- strict thread matches above, loose matches on Subject: below --
2002-07-22 21:19 Nir Nizry
2002-07-24  0:31 ` Ross Johnson
2002-07-31  0:13 ` Ross Johnson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).