dxx-rebirth/arch/dos/comm/dzqueue.c
2006-03-20 17:12:09 +00:00

169 lines
3.6 KiB
C
Executable file

/*
* This file is part of DZComm.
* Version : 0.6
* General purpose FIFO queue functions set.
* Copyright (c) 1997 Dim Zegebart, Moscow Russia.
* zager@post.comstar.ru
* http://www.geocities.com/siliconvalley/pines/7817
* file : queue.c
*/
#include <stdlib.h> /* NULL */
#include "dzcomm.h"
#include "internal.h"
typedef unsigned int uint;
typedef unsigned short int usint;
typedef unsigned char byte;
#define QH(q) q->queue+q->head
#define QT(q) q->queue+q->tail
//------------------------- FIFO QUEUE -----------------------------
// 'first in first out' queue functions
inline void queue_reset(fifo_queue *q)
{ q->tail=0;
q->head=0;
}
END_OF_FUNCTION(queue_reset);
int queue_resize(fifo_queue *q,uint new_size)
{ int *tmp;
if ((tmp=(int*)realloc(q->queue,sizeof(int)*new_size))==NULL) return(0);
if (new_size>q->size) q->resize_counter++;
else if (new_size<=q->initial_size) q->resize_counter=0;
else q->resize_counter--;
q->queue=tmp;
q->size=new_size;
q->fill_level=3*(q->size>>2); // 3/4
return(1);
}
//-------------------- QUEUE_DELETE --------------------------
void queue_delete(fifo_queue *q)
{ if (q==NULL) return;
free(q->queue);
free(q);
}
//--------------------- QUEUE_PUT ------------------------------
inline int queue_put(fifo_queue *q,int c)
{ return(queue_put_(q,&c));
}
END_OF_FUNCTION(queue_put);
int queue_put_(fifo_queue *q,void *c)
{ int n=0;
if (!q) return(0);
DISABLE();
memcpy(QT(q),c,q->dsize);
q->tail+=q->dsize;
if (q->tail==q->head)
{ q->head+=q->dsize;
if (q->head>(q->size-q->dsize)) q->head=0;
}
if(q->tail>(q->size-q->dsize)) q->tail=0;
n=0;
if (q->head<q->tail) {if ((q->tail-q->head)>=q->fill_level) n=1;}
else
if ((q->head-q->tail)<=q->size-q->fill_level) n=1;
ENABLE();
return(n);
}
END_OF_FUNCTION(queue_put_);
//---------------------- QUEUE GET ---------------------------
inline int queue_get(fifo_queue *q)
{ int c;
queue_get_(q,&c);
return(c);
}
END_OF_FUNCTION(queue_get);
int queue_get_(fifo_queue *q,void *c)
{
int n;
DISABLE();
memcpy(c,QH(q),q->dsize);
q->head+=q->dsize;
if (q->head>(q->size-q->dsize)) q->head=0;
if (q->head==q->tail) queue_reset(q);
n=0;
if (q->head<q->tail) {if ((q->tail-q->head)>=q->fill_level) n=1;}
else
if ((q->head-q->tail)<=q->size-q->fill_level) n=1;
ENABLE();
return(n);
}
END_OF_FUNCTION(queue_get_);
//---------------------- QUEUE EMPTY ---------------------------
inline int queue_empty(fifo_queue *q)
{ if (q==NULL) return(1);
if (q->head==q->tail)
{ if (q->empty_handler!=NULL) return(-1);
return(1);
}
return(0);
}
END_OF_FUNCTION(queue_empty);
//------------------------------- QUEUE NEW --------------------------
fifo_queue* queue_new(uint size)
{
return(queue_new_(size,4));
}
//------------------------- QUEUE_NEW_ --------------------------
fifo_queue* queue_new_(uint size,uint dsize)
{ fifo_queue *q=NULL;
if (dsize<=0||dsize>4) return(NULL);
if ((q=(fifo_queue*)malloc(sizeof(fifo_queue)))==NULL) return(NULL);
if (!size) size=1024; //if illegal size, turn it to default size
if ((q->queue=malloc(sizeof(int)*size*dsize))==NULL) return(NULL);
q->dsize=dsize;
q->size=size*dsize;
q->initial_size=size*dsize;//size;
q->resize_counter=0;
q->fill_level=3*q->size/4; // 3/4
q->empty_handler=NULL;
queue_reset(q);
_go32_dpmi_lock_data(q->queue,sizeof(int)*size*dsize);
_go32_dpmi_lock_data(q,sizeof(fifo_queue));
return(q);
}
void lock_queue_functions(void)
{
LOCK_FUNCTION(queue_empty);
LOCK_FUNCTION(queue_put);
LOCK_FUNCTION(queue_get);
LOCK_FUNCTION(queue_put_);
LOCK_FUNCTION(queue_get_);
LOCK_FUNCTION(queue_reset);
}