This is the mail archive of the pthreads-win32@sources.redhat.com mailing list for the pthreas-win32 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

possible erratic behavior of pthread_cond_timedwait


Hi friends,

My colleague and I are finding that under some situations, and after about 5 to 6 hours, pthread_cond_timedwait does not seem to "honour" the timeout, but seems to hang.  We are using the latest released version of the pthreadVCE.dll/lib.  

We see this on W2K (no service pack) and on NT (SP4).  We have not tried it on systems with other versions of the service packs.

We have also seen it run with no problems for a long time on a W2K machine without any service pack!!

We were wondering if any one else has run into the situation, and what the resolution was for them.

To isolate the issue, we wrote a small program called main.exe, that exercises the pthread_cond_timedwait call.

I have copied the .h and .cc files below for information.

Any help/pointers or identification of errors in the code would be greatly appreciated.

thanks
Paul and Sanjeev.

-----------------------------------
		The program is called main and can be run as follows: main 10 1000

		where 10= number of threads
		1000 = interval in milli sec. 

		The code for main is in main.cpp.  It includes pthread_wrap.h (code given below) which in turn includes pthread_win32.h ( which is actually pthread.h renamed so that it does not clash with an existing file in our unix build).

			the code hangs at 
			status = pthread_cond_timedwait(&sig, &lock, &abstime);   //note: this is below, in the function called RecvData() 

			main.cpp
			#include <stdio.h>
			#include "pthread_wrap.h"
			void*  recvReq(void *arg);
			void*  sendReq(void *arg);
			void SendData();
			void RecvData();
			int msg=0;
			int trace=1;
			int counter=0;
			int counter1=0;
			pthread_mutex_t lock;             
			pthread_cond_t  sig;     
			int timeint=5000;//5 sec  
			#define LOGERR    {if(status!=0){printf("Error at line %d\n",__LINE__);fflush(stdout);exit(0);}}
			void PR(char *s)
			{
			    long id;
			    if(trace==1)
			    {
			        id=GetCurrentThreadId ();

			        printf("TH-%x:%s\n",id,s);
			        fflush(stdout);
			    }
			}

			int main(int argc , char * argv[])
			{

			    pthread_t	  tid;

			    int noth=1;
			    
			    if(argc>1)
			    noth=atoi(argv[1]);
			    if(argc>2)
			    timeint=atoi(argv[2]);
			    if(argc>3)
			    trace=atoi(argv[3]);


			    pthread_mutex_init(&lock, NULL);
			    pthread_cond_init(&sig, NULL);

			    for(int ii=0;ii<noth;ii++)
			    {
			    pthread_create(&tid, NULL, (PTHREAD_START_ROUTINE_DECL)&recvReq, (void *)ii);
			    }
			    for(ii=0;ii<noth;ii++)
			    {
			    pthread_create(&tid, NULL, (PTHREAD_START_ROUTINE_DECL)&sendReq, (void *)ii);
			    }
			    


			    


			    while(1) //sleep forever
			    {
			        Sleep(10000);

			    }
			    return 0;
			}
			void*  recvReq(void *arg)
			{
			    printf("Receiver Thread id %d started\n",pthread_self());
			    fflush(stdout);



			    while(1)
			    {
			        RecvData();
			    }


			    return 0;


			}
			/////////////
			void*  sendReq(void *arg)
			{
			    printf("Sender Thread id %d started\n",pthread_self());
			    fflush(stdout);

			    Sleep(10000);

			    while(1)
			    {
			        SendData();
			        Sleep(timeint*2);

			    }

			    return 0;


			}
			/////////////
			void SendData()
			{


			    int status=0;

			    if(msg==0)
			    {
			        PR("before lock-01");
			        status = pthread_mutex_lock(&lock);
			        LOGERR;
			        PR("after lock-01");
			  

			        msg=1;
			        counter++;
			        if(counter>50000)
			        {
			            counter=1;
			            counter1++;
			        }
			    
			        status=pthread_mutex_unlock(&lock);
			        PR("unlock-01");
			        LOGERR;
			        pthread_cond_signal(&sig);
			    }
			}

			///////////////
			void RecvData()
			{
			        int status=0;

			        PR("before lock-11");
			        status = pthread_mutex_lock(&lock);
			        LOGERR;
			        PR("after lock -11");
			    
			        while (msg== 0 && status == 0)
			        {
							struct timespec abstime;
							memset(&abstime,0,sizeof(abstime));
							time_t tt;
							tt=time(&tt);
							abstime.tv_sec=(int)tt + timeint/1000;
							abstime.tv_nsec=0;

			                PR("unlock P");
							status = pthread_cond_timedwait(&sig, &lock, &abstime);
			                PR("lock P");
			           
							if (status == ETIMEDOUT)
							{
								status=pthread_mutex_unlock(&lock);
			                    PR("unlock -11");
			                    LOGERR;
								return ;
							}

			                LOGERR;
			        }



			        printf("count=[%d]%d\n",counter1,counter);fflush(stdout);
			        
			        msg=0;
			 
			        PR("unlock -12");
			        status=pthread_mutex_unlock(&lock);
			        LOGERR;

			        return ;

			}

			pthread_wrap.h
			#ifndef _PTHREAD_WRAP_H
			#define _PTHREAD_WRAP_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*);

			#ifdef WIN32
			#include "pthread_win32.h"//include NT's pthread library.

			#define _POSIX_THREAD_PROCESS_SHARED  1

			#define ETIMEDOUT 10060  // WSAETIMEDOUT

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

			#ifndef SEM_H  // resolved conflict with Netscape function definitions
			#if !defined(sem_init)

			/* Semaphore support */
			// share of semaphores between processes is not supported by the wrapper
			typedef HANDLE sem_t;

			int sem_init(sem_t *sem, int pshared, unsigned int value ); 
			int sem_wait(sem_t *sem);
			int sem_post(sem_t *sem);
			int sem_destroy(sem_t *sem);
			#endif

			#endif
			#else //Solaris

			#include <pthread.h> //include Solaris's pthread library.
			#if !defined(sem_init)
			#include <semaphore.h>
			#endif

			#define pthread_addr_t  void *

			#define PTHREAD_CONDATTR_INIT_ARG_TYPE &
			#define PTHREAD_MUTEXATTR_INIT_ARG_TYPE &

			#endif

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


			#ifdef  __cplusplus
			}
			#endif

			#endif // end of _PTHREAD_WRAP_H



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]