/*
 * $RCSfile: semaphore.c,v $
 *
 * x-kernel v3.3 - IRIX port
 *
 * Original Copyright (c) 1993,1991,1990,1996  Arizona Board of Regents
 * Modifications Copyright (c) 1993 Massachusetts Board of Regents
 *
 * $Log: semaphore.c,v $
 * Revision 1.2  1996/01/30 20:52:53  slm
 * Updated copyright and version.
 *
 * Revision 1.1  1995/07/29  02:42:45  slm
 * Initial revision
 *
 * Revision 1.2.1.1.1.2  1994/11/16  23:44:55  hkaram
 * Changed assert.h to xk_assert.h
 *
 * Revision 1.2.1.1.1.1  1994/11/12  19:13:44  hkaram
 * New branch
 *
 * Revision 1.2.1.1  1994/03/14  22:48:13  umass
 * Additional tracing information
 *
 * Revision 1.2  1993/11/13  00:45:48  menze
 * Original version from UMass
 */

#include <x_stdio.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <netinet/in.h>
#include <ulocks.h>
#include <task.h>
#include <errno.h>

#include "platform.h"
#include "event.h"
#include "event_i.h"
#include "xk_debug.h"
#include "process.h"


int	tracesemaphores;

void
semInit(s, n)
register Semaphore *s;
unsigned n;
{
  int	pid;

  xIfTrace(semaphores, TR_MAJOR_EVENTS) {
    pid = getpid();
  }
  xTrace3(semaphores, TR_MAJOR_EVENTS, "semInit on %X by pid %d to %d", 
    s, pid, n);

  s->irix_semaphore = usnewsema(xkernel_arena, n);
  if (s->irix_semaphore == NULL)
    {
      perror ( (char *)0  );
      Kabort("semInit: usnewsema returned NULL error");
    }
}


void
semWait(s)
register Semaphore *s;
{
  int	pid;
  int   return_value;

  xIfTrace(semaphores, TR_MAJOR_EVENTS) {
    pid = getpid();
  }
  xTrace2(semaphores, TR_MAJOR_EVENTS, "P on %X by pid %d", s, pid);

#ifdef XK_THREAD_TRACE
  evMarkBlocked(s);
#endif /* XK_THREAD_TRACE */

  xk_master_unlock();
  return_value = uspsema(s->irix_semaphore);
  xIfTrace(semaphores, TR_ALWAYS) {
    if(return_value < 0) {
      printf("semWait: got %d return with %d errno from P()\n", 
             return_value, errno);
      perror("semWait: ");
    }
  }
  xk_master_lock();

#ifdef XK_THREAD_TRACE
  evMarkRunning();
#endif /* XK_THREAD_TRACE */

}

void
semSignal(s)
register Semaphore *s;
{
  int	pid;
  int   return_value;

  xIfTrace(semaphores, TR_MAJOR_EVENTS) {
    pid = getpid();
  }
  xTrace2(semaphores, TR_MAJOR_EVENTS, "V on %X by pid %d", s, pid);

  return_value = usvsema(s->irix_semaphore);
  xIfTrace(semaphores, TR_ALWAYS) {
    if(return_value < 0) {
      printf("semSignal: got %d return with %d errno from V()\n", 
             return_value, errno);
      perror("semSignal: ");
    }
  }
}

#if FALSE
/*
 *  At the moment, doing this is a pain in the butt.  We have to
 *  enable metering on IRIX semaphores to provide this feature,
 *  and so far, no one uses it.  We'll add it later if necessary.
 *
 */
void
VAll(s)
register Semaphore *s;
{
  int	pid;

  xIfTrace(semaphores, TR_MAJOR_EVENTS) {
    pid = getpid();
  }
  xTrace2(semaphores, TR_MAJOR_EVENTS, "VALL on %X by pid %d", s, 
    pid);

  if (cv_broadcast(s->cv) < 0) {
    lwp_perror("cv_broadcast");
    Kabort("VAll: cv_broadcast failed");
  }
  s->count = 0;
}
#endif

/* InitSema may, and in this case, does allocate resources.  There
 * has to be a routine to release semaphores.  This is it.
 * -- Robbert van Renesse
 */
void
semFree(s)
register Semaphore *s;
{
  usfreesema(s->irix_semaphore, xkernel_arena);
}


