Re: condvar

Philippe Houdoin <[email protected]>
Newsgroups gmane.os.openbeos.kernel.devel
Message-ID <[email protected]>
Axel asked:
> The functionality is very trivial to implement, that's why I've
> already
> done it - the question is on how we make it public.
> There are basically 3 possibilities:
> 1) keep it private for R1
> 2) (the messy version) add another flag to acquire_sem_etc() that
> reinterpretes the "count" parameter as semaphore to be released -
> this
> has the advantage that no new system call is added; it's by no means
> backwards compatible, though (the app would run incorrectly on
> systems).
> 3) (the clean version) add a new pair of system calls: switch_sem()
> and
> switch_sem_etc() (other naming suggestions are welcome). Applications
> using these functions would not run on R5 or Zeta anymore.

Cleaness was (most of the time) the BeOS way. IMHO, better to kept Haiku on the
same road. New syscalls is great. It's a > R1 feature, so it make sense to
expand the kernel API anyway... and still keep binary compatibility with R5
apps.

François added:
> Btw, there is a big issue with the current pthread implementation as
> well as yours: it doesn't handle the STATIC initializers...
> They both declare the basic pthread _t types as pointers to structs,
> for extensibility... and:
> #define PTHREAD_MUTEX_INITIALIZER	NULL
> #define PTHREAD_COND_INITIALIZER	NULL
> #define PTHREAD_RWLOCK_INITIALIZER	NULL
>
> But that prevents apps doing:
>
> pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
> and just using it, since the funcs will get a NULL, and can't use that.
> (the R5 lib actually tries to acquire a pseudo-spinlock from that
> struct to lazily initialize it... except it's still NULL, so it
> crashes.

It sounds to me like the issue I got while implementing Mesa threading API
abstraction (glapi/glthread.{c|h}) for BeOS. I choose to use benaphore, but
static initialization didn't working as expected, which was very bad
considering the global lock Mesa use at critical Mesa's init time.

I hacked in a very hugly way: init non-initialized mutex at lock time:

typedef struct {
    int32   lock;
    sem_id  sem;
} benaphore;
typedef benaphore _glthread_Mutex;

#define _glthread_DECLARE_STATIC_MUTEX(name)
  static _glthread_Mutex name = { 0, 0 }

#define _glthread_INIT_MUTEX(name)
  name.sem = create_sem(0, #name"_benaphore"), name.lock = 0

#define _glthread_DESTROY_MUTEX(name)
  delete_sem(name.sem), name.lock = 0

#define _glthread_LOCK_MUTEX(name)
  if (name.sem == 0) _glthread_INIT_MUTEX(name); \
  if (atomic_add(&(name.lock), 1) >= 1) acquire_sem(name.sem)

#define _glthread_UNLOCK_MUTEX(name)
  if (atomic_add(&(name.lock), -1) > 1) release_sem(name.sem)

It's a ticking bomb :-(, because it assert that we never destroy or unlock a
mutex without having locked *once* at least. Plus the performance hit, also.

This works with Mesa ATM, but can't be
assumed with more general purpose like pthread support...

Anyway, maybe this hack can be enhanced by you guys ;-)

- Philippe, back online (have I mentioned that I hates my ISP?)
with huge stack of pending emails...


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id396&op=click
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.