#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>


void *
thread(void *arg)
{
   int i;
   TID self;

   printf("In thread 0x%8.8x:\n\n", _TLS);
   self = _TLS; //pthread_self();
   printf("    tid: 0x%8.8x\n", self); 
   printf("    pid: %d\n", self->pid); 
   printf("    stack pointer: 0x%8.8x\n", PTHREAD_STACK(self).ss_sp); 
   printf("    stack size: %d\n", PTHREAD_STACK(self).ss_size); 
   printf("    state: %d\n", self->state); 
   printf("    prio: %d\n", self->prio); 
   printf("    curprio: %d\n", self->curprio); 
   sleep(1);
   return NULL;
}

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cv = PTHREAD_COND_INITIALIZER;
int pred = 0;

main()
{
   int args[2];
   int status;
   pthread_t child;
   int i;
   void *result;
   TID self;
   struct timespec when = { 1, 0 };

   args[0] = 0;
   args[1] = 0;

   if (pthread_create(&child, NULL, &thread, NULL) != EOK) {
	printf("Couldn't create child\n");
   }
   status = (int)pthread_join(child, &result);

   printf("In main() (0x%8.8x):\n\n", _TLS);
   self = _TLS; //pthread_self();
   printf("    tid: 0x%8.8x\n", self); 
   printf("    pid: %d\n", self->pid); 
   printf("    stack pointer: 0x%8.8x\n", PTHREAD_STACK(self).ss_sp); 
   printf("    stack size: %d\n", PTHREAD_STACK(self).ss_size); 
   printf("    state: %d\n", self->state); 
   printf("    prio: %d\n", self->prio); 
   printf("    curprio: %d\n", self->curprio); 

   /* Time out in 1 sec. */
   pthread_mutex_lock(&mutex);
   clock_gettime(CLOCK_REALTIME, &when);
   when.tv_sec += 1;
   while (!pred) {
      int status = pthread_cond_timedwait(&cv, &mutex, &when);
      if (status == ETIMEDOUT) break;
   }
   pthread_mutex_unlock(&mutex);

   /* Time out immediately. */
   pthread_mutex_lock(&mutex);
   clock_gettime(CLOCK_REALTIME, &when);
   while (!pred) {
      int status = pthread_cond_timedwait(&cv, &mutex, &when);
      if (status == ETIMEDOUT) break;
   }
   pthread_mutex_unlock(&mutex);

#if 0
   /* Poll. */
   pthread_mutex_lock(&mutex);
   clock_gettime(CLOCK_REALTIME, &when);
   while (!pred) {
      int status = pthread_cond_timedwait(&cv, &mutex, &when);
      if (status == ETIMEDOUT) break;
   }
   pthread_mutex_unlock(&mutex);
#endif

   sleep(1);
   pthread_exit(0);
}
