int main ( void )
{
    int r;
    pthread_t my_rescuer, grabber;

    r= pthread_mutex_init(&mx[0], NULL);
    assert(!r);
    r= pthread_mutex_init(&mx[1], NULL);
    assert(!r);
    r= pthread_mutex_init(&mx[2], NULL);
    assert(!r);
    r= pthread_mutex_init(&mx[3], NULL);
    assert(!r);

    r= pthread_cond_init(&cv, NULL);
    assert(!r);
    r= pthread_rwlock_init(&rwl, NULL);
    assert(!r);

    quit_now = my_sem_init( "quit_now", 0,0 );
    assert(quit_now);

    r= pthread_create( &grabber, NULL, grab_the_lock, NULL );
    assert(!r);
    sleep(1); /* let the grabber get there first */

    r= pthread_create( &my_rescuer, NULL, rescue_me, NULL );
    assert(!r);
    /* Do stupid things and hope that rescue_me gets us out of
       trouble */

    /* mx is bogus */
    r= pthread_cond_wait(&cv, (pthread_mutex_t*)(1 + (char*)&mx[0]) );

    /* mx is not locked */
    r= pthread_cond_wait(&cv, &mx[0]);

    /* wrong flavour of lock */
    r= pthread_cond_wait(&cv, (pthread_mutex_t*)&rwl );

    /* mx is held by someone else. */
    r= pthread_cond_wait(&cv, &mx[2] );

    r= my_sem_post( quit_now );
    assert(!r);
    r= my_sem_post( quit_now );
    assert(!r);

    r= pthread_join( my_rescuer, NULL );
    assert(!r);
    r= pthread_join( grabber, NULL );
    assert(!r);

    r= my_sem_destroy( quit_now );
    assert(!r);
    return 0;
}
int main ( void )
{
   int r, i;
   sem_t* sem;
   pthread_t child[N_THREADS];

   sem= my_sem_init("sem1", 0, N_THREADS); assert(sem);

   for (i = 0; i < N_THREADS; i++) {
      r= pthread_create( &child[i], NULL, child_fn, sem );
      assert(!r);
   }

   for (i = 0; i < N_THREADS; i++) {
      r= pthread_join( child[i], NULL );
      assert(!r);
   }

   r= my_sem_destroy(sem); assert(!r);
   return 0;
}