Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 28 Dec 1998 17:31:12 -0500
From:      Kelly Yancey <kbyanc@freedomnet.com>
To:        freebsd-hackers@FreeBSD.ORG
Subject:   pthreads question/problem...
Message-ID:  <368806B0.721938BF@freedomnet.com>

next in thread | raw e-mail | index | archive | help

  I have a system running FreeBSD 2.2-980711-SNAP (2.2.7) and have been
working on developing a small multithreaded test program (just to make
sure I've got the semantics and whatnot right). The basic idea is that I
start a small pool of "worker" threads that wait to service requests. In
this little test program, requests are randomly generated by the main
thread (ie. original thread of execution). To pass the request to a free
worker thread, the main thread scans the pool of worker threads using
pthread_mutex_trylock() until it finds one that has it's in-use mutex
unlocked. As I understand, trylock is supposed to lock the mutex if it
is unlocked. At which point, I fill in the data structures for that
worker thread and call pthread_cond_signal() to unblock it.
  All of that works like a charm. The problem is that when the worker
thread is done processing it calls pthread_mutex_unlock() on the in-use
mutex to make the thread available to service a new request. However,
the unlock call always returns EINVAL (invalid argument).
  Now, I'm not asking for anyone to debug my code...that's my own
headache, but here is the thread pool definition (pardon the long
comments):

struct threadinfo {
  pthread_t              threadid;      /* thread ID of thread servicing
this structure */
  pthread_cond_t         waitcondition; /* condition variable used while
waiting for data */
  pthread_mutex_t        waitmutex;     /* mutex used to protect data
from simultanious access */
  pthread_mutex_t        inuse;         /* mutex used to indicate the
TCB is currently active */
  long                   data;          /* data given to thread to
process */
};

struct threadinfo TCB[NUMTHREADS];      /* array of thread control
blocks (TCBs)...each TCB is used to pass data to a single executi
ng thread */

  The point being that the mutexes are global data and each thread is
passed a pointer to the structure that it is supposed to watch when the
thread is started. (When I say "watch" I mean which structure's
conditional variable it will block awaiting a signal).
  The main thread sets the mutex, the worker thread unlocks the
mutex...or I should say tries to. What I end up seeing is that the mutex
stays locked and I eventually run out of worker threads as they all
remain "in-use". And before anyone asks...yes, I have verified that the
parameter I mass to unlock is indeed the same as the one I passed to
lock (by using printf() with %p to verify the pointer addresses).
  Is there something wrong with the pthreads implementation of mutexes
as of this snap that may be fixed in 2.2.8 (I'm not quite ready to go to
3.0 yet)? Or am I missing some fundamental aspect of multithreaded
programming? It seems to me that being able to manipulate mutexes from
separate threads is a must for threads to be of any use.

  I greately appreciate any pointers anyone can give me...perhaps I can
keep my sanity yet :)

  Kelly

-- 
Kelly Yancey                "Bill Gates is only a white Persian cat and
~kbyanc@freedomnet.com~      a monocle away from being the villain in a
                             James Bond movie" - comedian Dennis Miller

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?368806B0.721938BF>