#include <stdarg.h>
#include <stdio.h>
#include <errno.h>
#include "internals.h"
#include "setjmp.h"
#include "signal_internals.h"
#include "mutex.h"

void kprintf(char* format, ...)

{
    va_list ap;
    int x;
    static char buf[1024];

    sigset_t savemask;
    x = errno; 

      SIGPROCMASK(SIG_SETMASK, &no_signals, &savemask);
    sprintf(buf, "(%d) ", mac_pthread_self());
#if defined(IO)
#if defined(SOLARIS)
    WRITE(2,buf,strlen(buf)); 
#else
    pthread_sys_write(2,buf,strlen(buf)); 
#endif
#else
    write(2,buf,strlen(buf));
#endif
    va_start(ap, format); 
    vsprintf(buf,format,ap);
#if defined(IO) 
#if defined(SOLARIS)
    WRITE(2,buf,strlen(buf)); 
#else
    pthread_sys_write(2,buf,strlen(buf)); 
#endif
#else
    write(2,buf,strlen(buf)); 
#endif
     SIGPROCMASK(SIG_SETMASK, &savemask, (struct sigset_t *) NULL);
    errno = x;
}

void __kassert(char* e,char* fname,int line)

{
   kprintf("Assertion failed: %s in %s at %d\r\n",e,fname,line);
   _exit(0);
}

dumpcontext(context)
#if defined (__FreeBSD__) || defined (_M_UNIX) || defined(__linux__) || defined(__dos__)
SYS_SIGJMP_BUF context;
#else
sigjmp_buf context;
#endif

{
    kprintf("{bp=%08lx sp=%08lx pc=%08lx}\n",
            context[JB_BP],
            context[JB_SP],
            context[JB_PC]);
}

dumpthread(p)
pthread_t p;

{
    kprintf("struct %08lx {\n", p); 
    kprintf("\tcontext=");
    dumpcontext(p->context);
    kprintf("\tbody=");
    dumpcontext(p->context);
    kprintf("\terrno=%d\n", p->terrno);
    kprintf("\tret=%d\n", p->ret);
    kprintf("\tstack_base=%08lx\n", p->stack_base);
    kprintf("\tstate=%08lx\n", p->state);
    kprintf("\tsig=%d\n", p->sig);
    kprintf("\tosp=%08lx\n", p->osp);
    kprintf("\topc=%08lx\n", p->opc);
    kprintf("\tobp=%08lx\n", p->obp);
    kprintf("\tcond=%08lx\n", p->cond);
    kprintf("\tqueue=%08lx\n", p->queue);
    kprintf("\n");
}

void dumpqueue(q, index)
     pthread_queue_t q;
     int index;

{
  pthread_t next = q->head;
  timer_ent_t tmr;
  struct timeval now;

  while (next != NO_PTHREAD) {
    dumpthread(next);
    next = next->next[index];
  }
}

void dumpthreads()

{
  pthread_t p;
  for(p = all.head; p; p = p->next[ALL_QUEUE]) {
    dumpthread(p);
  }
}
