/*******************************************************************************
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);
}