/*******************************************************************************

            Buffer Pool Management

            IPC Using FIFOs

 

            Author : K. Erciyes

            September 1999

******************************************************************************/

 

// buffer.h

 

#include <stdio.h>
#include <thread.h>
#include <synch.h>


typedef struct buffer_t{
    char data[10];
     struct buffer_t  *next;
} buf_t, *bufptr;
 

 

// bufpool.h

 

#include "buffer.h"

#define     POOL_SIZE   20   /* size of allocated space */
#define     ERR_POOLEMPTY     -1
#define     ERR_POOLFULL      -2



typedef struct pool *poolptr;

typedef struct pool{    int state ;
            int pool_size;
            sema_t poolsem;
            mutex_t poolmut;                   
            bufptr front;
            bufptr rear;
            buf_t bufs[POOL_SIZE];
            } pool_t;


 

// bufpool.c

 

#include "bufpool.h"

/*****************************************************************************

                  initialize a pool

******************************************************************************/
int    init_pool (poolptr pp, int pool_length)

{     int i ;
      pp->pool_size=pool_length;
      sema_init(&pp->poolsem,pp->pool_size,USYNC_THREAD,0);
      mutex_init(&pp->poolmut,USYNC_THREAD,0);
      pp->front=&(pp->bufs[0]);
            for (i=0; i<pp->pool_size - 1; i ++)
            pp->bufs[i].next = &(pp->bufs[i+1]);
      pp->rear=&(pp->bufs[pp->pool_size-1]);
}

bufptr check_pool(poolptr pp)

{     bufptr bp;
      bp=pp->front;
      return(bp);
}


/*****************************************************************************

                  get a buffer from a pool

******************************************************************************/
bufptr get_buf(poolptr pp)

{     bufptr bp;
      sema_wait(&pp->poolsem);
      mutex_lock(&pp->poolmut);
      bp= pp->front;
      pp->front=bp->next;
      mutex_unlock(&pp->poolmut);  
      return(bp);
}
/*****************************************************************************

                  put a buffer to a pool

******************************************************************************/

int put_buf(poolptr pp, bufptr bp)

{     bp->next=NULL;
      mutex_lock(&pp->poolmut);
      pp->rear->next=bp;
      pp->rear=bp;
      if (pp->front==NULL) pp->front=bp;
      mutex_unlock(&pp->poolmut);
      sema_post(&pp->poolsem);
}


================================================================================
 

//fifo.h

#include "bufpool.h"

#define     FIFO_SIZE       10
#define     N_FIFOS           10   
#define     ALLOCATED   1
#define     ERR_FIFOEMPTY     -1
#define     ERR_FIFOFULL      -2

typedef struct fifo *fifoptr;

typedef struct fifo{    int state ;
                  int fifo_size;
                  int read_idx;
                  int write_idx;
                  sema_t  fullsem;
                  sema_t emptysem;
                  mutex_t fifomut;
                        bufptr bufs[FIFO_SIZE];
                  } fifo_t;

typedef struct fifotable *fifotabptr;

typedef struct fifotable{     int state ;
                        int curridx;
                        fifoptr fifos[N_FIFOS];
                  } fifotab_t;


==============================================================

// fifo.c

 

#include "fifo.h"

// extern fifotab_t sys_fifot;
 

/*****************************************************************************

                  initialize a fifo

******************************************************************************/

int init_fifo(fifoptr fp)

{     int fifoid;
      //sys_fifot.curridx++;
//    fifoid=sys_fifot.curridx;
//    sys_fifot.fifos[fifoid]=fp;
      fp->state=ALLOCATED;
      fp->fifo_size=FIFO_SIZE;
      sema_init(&fp->fullsem,0,USYNC_THREAD,0);
      sema_init(&fp->emptysem,fp->fifo_size,USYNC_THREAD,0);
      mutex_init(&fp->fifomut,USYNC_THREAD,0);
      fp->read_idx=0;
      fp->write_idx=0;
      return(fifoid);
}

/*****************************************************************************

                  read a buffer from a fifo

******************************************************************************/
 

bufptr read_fifo(fifoptr fp)

{     bufptr bp;
      sema_wait(&fp->fullsem);
      mutex_lock(&fp->fifomut);
      bp=fp->bufs[fp->read_idx++];
      fp->read_idx %= fp->fifo_size; 
      mutex_unlock(&fp->fifomut);
      sema_post(&fp->emptysem);
            return(bp);
}


/*****************************************************************************

                  write a buffer to a fifo

******************************************************************************/

int write_fifo(fifoptr fp, bufptr bp)

{    
      sema_wait(&fp->emptysem);
      mutex_lock(&fp->fifomut);
      fp->bufs[fp->write_idx++]=bp;
      fp->write_idx %= fp->fifo_size;  
      mutex_unlock(&fp->fifomut);
      sema_post(&fp->fullsem);
 }