From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11118 invoked by alias); 27 Jan 2006 12:05:55 -0000 Received: (qmail 11099 invoked by uid 22791); 27 Jan 2006 12:05:53 -0000 X-Spam-Check-By: sourceware.org Received: from uproxy.gmail.com (HELO uproxy.gmail.com) (66.249.92.202) by sourceware.org (qpsmtpd/0.31) with ESMTP; Fri, 27 Jan 2006 12:05:51 +0000 Received: by uproxy.gmail.com with SMTP id o2so534504uge for ; Fri, 27 Jan 2006 04:05:48 -0800 (PST) Received: by 10.48.43.1 with SMTP id q1mr282588nfq; Fri, 27 Jan 2006 04:05:48 -0800 (PST) Received: by 10.48.144.14 with HTTP; Fri, 27 Jan 2006 04:05:48 -0800 (PST) Message-ID: Date: Fri, 27 Jan 2006 12:05:00 -0000 From: Breght Boschker To: pthreads-win32@sourceware.org Subject: Deadlock on WinCE MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline X-IsSubscribed: yes Mailing-List: contact pthreads-win32-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: pthreads-win32-owner@sourceware.org X-SW-Source: 2006/txt/msg00003.txt.bz2 Hi, taking a well-known example (the so-called 'producer-consumer' problem) with a relatively small queue, we have observed a deadlock. (See below for code) - the results we get: Pthread test request_queue_put: # of elements: 1 request_queue_put: # of elements: 2 request_queue_put: # of elements: 3 request_queue_put: # of elements: 4 request_queue_put: # of elements: 5 *********************************************** put: queue FULL. waiting for free space *********************************************** request_queue_get: # of elements: 4 request_queue_get: # of elements: 3 request_queue_get: # of elements: 2 request_queue_get: # of elements: 1 request_queue_get: # of elements: 0 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D get: queue EMPTY, waiting for data =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D request_queue_put: # of elements: 1 request_queue_put: # of elements: 2 request_queue_put: # of elements: 3 request_queue_put: # of elements: 4 request_queue_put: # of elements: 5 *********************************************** put: queue FULL. waiting for free space *********************************************** request_queue_get: # of elements: 4 request_queue_get: # of elements: 3 request_queue_get: # of elements: 2 request_queue_get: # of elements: 1 request_queue_get: # of elements: 0 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D get: queue EMPTY, waiting for data =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D ***** at this point, the program stops (the WinCE Remote Kernel Tracker reports all threads of the application to be in 'blocked' state). If the queue size is increased (say to 20 elements), the first thread (the 'producer') completely fills the queue, *then* sends a signal, the consumer thread is released from its pthread_cond_wait and consumes a number of elements. After this, the two threads alternate (put & get) and we have seen no deadlock so far. Furthermore, the Remote Kernel Tracker shows that signals ('SetEvent') are sent, but these do not result in the other thread becoming unblocked. Also, we have noticed a lot of 'CreateEvent' calls during the running period of one of either threads. Some background information on our system: Compiler: MS eMbedded Visual C++ 4.0 (SP4) Target machine: ARMv4I / WinCE 5.00 PThread-WIN32 version: 2.7.0 (we had to put some defines around e.g. in some files and in errno.c needed to put a typecast in order to satisfy the compiler). Any help/leads or ideas would be appreciated. We use the following code: #include #include "pthread.h" #define QUEUESIZE 5 typedef struct rs { int type; } REQUEST_STRUCT; typedef struct rq { int full; int empty; int head; int tail; int elt_count; pthread_mutex_t mut; pthread_cond_t not_full; pthread_cond_t not_empty; REQUEST_STRUCT buf[QUEUESIZE]; } REQUEST_QUEUE; #include "windows.h" void cenav_pthread_create(HANDLE a, HANDLE b) {} void cenav_pthread_exit() { } void *producer (void *args); void *consumer (void *args); extern REQUEST_QUEUE *request_queue_create (void); extern void request_queue_delete (REQUEST_QUEUE *q); extern void request_queue_put (REQUEST_QUEUE *q, REQUEST_STRUCT *rs); extern void request_queue_get (REQUEST_QUEUE *q, REQUEST_STRUCT *rs); int request_test () { REQUEST_QUEUE *fifo; pthread_t pro, con; fifo =3D request_queue_create (); if (fifo =3D=3D NULL) { fprintf (stderr, "main: Queue Init failed.\n"); exit (1); } pthread_create (&pro, NULL, producer, fifo); pthread_create (&con, NULL, consumer, fifo); pthread_join (pro, NULL); pthread_join (con, NULL); request_queue_delete (fifo); return 0; } void *producer (void *q) { REQUEST_QUEUE *fifo; REQUEST_STRUCT rs; int i; fifo =3D (REQUEST_QUEUE *)q; while (1) { request_queue_put (fifo, &rs); } return (NULL); } void *consumer (void *q) { REQUEST_QUEUE *fifo; REQUEST_STRUCT rs; int i; fifo =3D (REQUEST_QUEUE *)q; while(1) { request_queue_get (fifo, &rs); } return (NULL); } extern REQUEST_QUEUE *request_queue_create (void) { REQUEST_QUEUE *q; q =3D (REQUEST_QUEUE *)malloc (sizeof (REQUEST_QUEUE)); if (q =3D=3D NULL) return (NULL); q->empty =3D 1; q->full =3D 0; q->head =3D 0; q->tail =3D 0; q->mut =3D PTHREAD_MUTEX_INITIALIZER; q->not_full =3D PTHREAD_COND_INITIALIZER; q->not_empty =3D PTHREAD_COND_INITIALIZER; q->elt_count =3D 0; return (q); } extern void request_queue_delete (REQUEST_QUEUE *q) { free (q); } extern void request_queue_put (REQUEST_QUEUE *q, REQUEST_STRUCT *rs) { int result =3D 0; result =3D pthread_mutex_lock(&(q->mut)); while (q->full) { printf ("put: queue FULL. waiting for free space\n"); pthread_cond_wait(&q->not_full, &q->mut); } q->buf[q->tail] =3D *rs; q->tail++; if (q->tail =3D=3D QUEUESIZE) q->tail =3D 0; if (q->tail =3D=3D q->head) q->full =3D 1; q->empty =3D 0; q->elt_count++; printf("request_queue_put: # of elements: %d\n", q->elt_count); pthread_cond_signal(&q->not_empty); result =3D pthread_mutex_unlock(&(q->mut)); return; } extern void request_queue_get (REQUEST_QUEUE *q, REQUEST_STRUCT *rs) { int result =3D 0; result =3D pthread_mutex_lock(&q->mut); while (q->empty) { printf ("get: queue EMPTY, waiting for data\n"); pthread_cond_wait(&q->not_empty, &q->mut); } *rs =3D q->buf[q->head]; q->head++; if (q->head =3D=3D QUEUESIZE) q->head =3D 0; if (q->head =3D=3D q->tail) q->empty =3D 1; q->full =3D 0; q->elt_count--; printf("request_queue_get: # of elements: %d\n", q->elt_count); pthread_cond_signal(&q->not_full); result =3D pthread_mutex_unlock(&(q->mut)); return; } int main(int argc, char **argv) { printf("Pthread test\n"); request_test(); } Thanks in advance, Breght Boschker