ftp.nice.ch/pub/next/unix/music/cm.sd.tar.gz#/midi/sgi/act_stack.c

This is act_stack.c in view mode; [Download] [Up]

#include "ipc_buffer.h"
#include <stdio.h>

IPC_MESSAGE_list IPCcdr(IPC_MESSAGE_list list)
{
  if (list)
    return list->next;
}

IPC_MESSAGE *IPCcar(IPC_MESSAGE_list list)
{
  if (list)
    return list->event;
  else {
    perror("Attempt to take the CAR of NIL\n");
    exit(-1);
  }
}

IPC_MESSAGE *IPCcons(IPC_MESSAGE *msg,IPC_MESSAGE_list list)
{
  IPC_MESSAGE_list  result;

  result = IPClist_alloc();
  result->event = msg;
  result->next  = list;
  return result;
}


IPC_MESSAGE *IPCQhead(IPC_MESSAGE_queue *q)
{
  if (q->first_event) {
#ifdef DEBUG0
   fprintf(stderr,"IPCQhead: %ld\n", q->first_event->event);
#endif    
   return q->first_event->event;
 }
}

void IPCfree (IPC_MESSAGE *event)
{
  free(event);
}

IPC_MESSAGE *IPCQpop(IPC_MESSAGE_queue *q)
{
  IPC_MESSAGE_list  fe,next,last;
  IPC_MESSAGE       *recycle;
  
#ifdef DEBUG0
   fprintf(stderr,"IN IPCQpop - length: %d\n",IPCQlength(q));
#endif
  fe = q->first_event;
  if (fe) {
    if (fe == q->last_event) {
      q->first_event = (IPC_MESSAGE_list) NULL;
      q->last_event  = (IPC_MESSAGE_list) NULL;
    } else 
      q->first_event = fe->next;
    fe->next = q->first_recyclable;
    q->first_recyclable = fe;
    return fe->event;
  }
#ifdef DEBUG0
   fprintf(stderr,"OUT IPCQpop - length: %d\n",IPCQlength(q));
#endif
}

IPC_MESSAGE *IPCQpopkeep(IPC_MESSAGE_queue *q)
{
  IPC_MESSAGE_list  fe,next,last;
  IPC_MESSAGE       *recycle;
  
#ifdef DEBUG0
   fprintf(stderr,"IN IPCQpop - length: %d\n",IPCQlength(q));
#endif
  fe = q->first_event;
  if (fe) {
    if (fe == q->last_event) {
      q->first_event = (IPC_MESSAGE_list) NULL;
      q->last_event  = (IPC_MESSAGE_list) NULL;
    } else 
      q->first_event = fe->next;
    fe->next = q->first_free;
    q->first_free = fe;
    return fe->event;
  }
#ifdef DEBUG0
   fprintf(stderr,"OUT IPCQpop - length: %d\n",IPCQlength(q));
#endif
}

IPC_MESSAGE_list IPClist_alloc()
{
   IPC_MESSAGE_list  result;

   result = (IPC_MESSAGE_list) malloc(sizeof(IPC_MESSAGE_cell));
   /*result->event = (IPC_MESSAGE *) malloc(MSGBUFFERSIZE); */
   /*result->next = (IPC_MESSAGE_list) NULL;*/
}

IPC_MESSAGE_list IPCQextend(IPC_MESSAGE_queue *q)
{ 
  IPC_MESSAGE_list  next;

  next = IPClist_alloc();
  next->next = q->first_free;
  q->first_free = next;
  /*q->last_event->next = next for moebius */
  return next;
} 

IPC_MESSAGE_list IPCQrecycle(IPC_MESSAGE_queue *q, IPC_MESSAGE* event)
{
  IPC_MESSAGE_list  recycle_cell;
    
  recycle_cell = q->first_free;
  if (recycle_cell) {
    recycle_cell->event = event;
    q->first_free = recycle_cell->next;
    recycle_cell->next = q->first_recyclable;
    q->first_recyclable = recycle_cell;
  } else
    free(event);
  return recycle_cell;
}

IPC_MESSAGE *IPCQreserve(IPC_MESSAGE_queue *q)
{
  IPC_MESSAGE       *recycle;
  IPC_MESSAGE_list  recycle_cell;
  
#ifdef DEBUG
   fprintf(stderr,"IN IPCQreserve - length: %d\n",IPCQlength(q));
#endif
  recycle_cell = q->first_recyclable;
  if (recycle_cell) {
    recycle = recycle_cell->event;
    q->first_recyclable = recycle_cell->next;
    recycle_cell->next = q->first_free;
    q->first_free = recycle_cell;
  } else
    recycle = (IPC_MESSAGE *) malloc(MSGBUFFERSIZE);
#ifdef DEBUG_BUFFER
  fprintf(stderr,"OUT IPCQreserve - length: %d buffer: %ld\n",IPCQlength(q), recycle);
#endif    
  return recycle;
}

int IPCQlength(IPC_MESSAGE_queue *q) 
{
  int i = 0;
  IPC_MESSAGE_list  cell;

  for(cell = q->first_event;cell; cell= cell->next)
    i++;
  return i;
}
  

IPC_MESSAGE_list IPCQpush(IPC_MESSAGE_queue *q, IPC_MESSAGE* event)
{
   IPC_MESSAGE_list  fe,newfirst,oldlast;

#ifdef DEBUG
   fprintf(stderr,"IN IPCQpush - length: %d\n",IPCQlength(q));
#endif
   fe = q->first_free;
   if (fe)
      q->first_free = fe->next;
   else
     fe = IPClist_alloc();
/*   fe->next = (IPC_MESSAGE_list) NULL;*/
   fe->event = event;
   oldlast = q->last_event;
   if (oldlast)
     oldlast->next = fe;
   else 
     q->first_event = fe;
   q->last_event = fe;
#ifdef DEBUG
   fprintf(stderr,"OUT IPCQpush - length: %d\n",IPCQlength(q));
#endif
   return fe;
 }
/*
IPC_MESSAGE_list IPCQalloc(IPC_MESSAGE_queue *q)
{
  IPC_MESSAGE_list  fe;
  
  fe = q->first_event;
  if (fe) {
    if (fe->next == q->first_free) 
      q->first_event = (IPC_MESSAGE_list) NULL;
    else
       q->first_event = fe->next;
    return q->first_event->event;
  }
}
*/

void IPCQrelease(IPC_MESSAGE_queue  *q)
{
  IPC_MESSAGE_list nextcell,cell;

  for(cell=q->first_free;cell;cell=nextcell) {
    nextcell = cell->next;
    free(cell);
  }
  for(cell=q->first_recyclable;cell;cell=nextcell) {
    nextcell = cell->next;
    free(cell->event);
    free(cell);
  }
  q->first_free = (IPC_MESSAGE_list) NULL;
  q->first_recyclable = (IPC_MESSAGE_list) NULL;
}

static struct sembuf lock_op   = { 0, -1, 0};
static struct sembuf unlock_op = { 0,  1, 0};

IPC_MESSAGE_queue *IPCQnew(int size, BOOL shared)
{
  IPC_MESSAGE_list prevcell,nextcell = (IPC_MESSAGE_list) NULL;
  IPC_MESSAGE_queue *result;
  int i;
  static short lock_initial_state = 1;

  result = (IPC_MESSAGE_queue *) malloc(sizeof(IPC_MESSAGE_queue));
  result->first_event = (IPC_MESSAGE_list) NULL;
  result->last_event = (IPC_MESSAGE_list) NULL;
  result->first_recyclable = (IPC_MESSAGE_list) NULL;
  prevcell =  IPClist_alloc();
  result->first_free =  prevcell;
/*  result->last_free =  prevcell;*/
  
  for(i=1;i<size;i++) {
    nextcell = IPClist_alloc();
    prevcell->next = nextcell;
    prevcell = nextcell;
  }
  prevcell->next = (IPC_MESSAGE_list) NULL;

  if (shared) {
    if ((result->lock = semget (IPC_PRIVATE, 1, (SEM_A | SEM_R))) == -1) {
      perror ("Could not create a lock for an IPC_Queue ");
      IPCQrelease(result);
      free(result);
      return (IPC_MESSAGE_queue *) 0;
    }
    if (semctl (result->lock, 0, SETALL, (ushort *) &lock_initial_state) == -1) {
      perror ("Could not set the initial value of an IPC_Queue lock ");
      IPCQrelease(result);
      free(result);
      return (IPC_MESSAGE_queue *) 0;
    } 
  }
  return result;
}

BOOL           IPCQlock(IPC_MESSAGE_queue *q)
{
#ifdef DEBUG
  int opresult;
  fprintf(stderr,"Locking IPCQueue %ld\n", q);
  if ((opresult = semop (q->lock, &lock_op, 1)) == -1) {
#else
  if (semop (q->lock, &lock_op, 1) == -1) {
#endif
    fprintf(stderr,"Could not lock IPCQueue %ld\n", q);
    return -1;
  }
#ifdef DEBUG_WAIT
  else
    fprintf(stderr,"Lock of IPCQueue %ld suceeded\n",q);
#endif
  return KERN_SUCCESS;
}

BOOL           IPCQunlock(IPC_MESSAGE_queue *q)
{
  #ifdef DEBUG
  int opresult;
  fprintf(stderr,"Unlocking IPCQueue %ld\n", q);
  if ((opresult = semop (q->lock, &unlock_op, 1)) == -1) {
#else
  if (semop (q->lock, &unlock_op, 1) == -1) {
#endif
    fprintf(stderr,"Could not unlock IPCQueue %ld\n", q);
    return -1;
  }
#ifdef DEBUG_WAIT
  else
    fprintf(stderr,"Unlock of IPCQueue %ld suceeded\n",q);
#endif
  return KERN_SUCCESS;
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.