mirror of
https://github.com/antoinevignau/source.git
synced 2024-08-11 15:28:58 +00:00
1 line
6.2 KiB
C++
1 line
6.2 KiB
C++
|
/***********************************************************************\
Filename: memory.c
\***********************************************************************/
#include <memory.h>
#include "proxlib.h"
#include "proxio.h"
#include "spmemory.h"
#include "scdef.h"
#include "sp.h"
#include "spdef.h"
#ifndef MM_NBLKS
#define MM_NBLKS 4 /* Default number of blocks to use */
#endif
/* Control structure for each buffer. */
typedef struct mb_struct {
HANDLE mb_file; /* file the block came from */
UCHAR *mb_blk; /* block-sized buffer (actual data) */
int mb_blknum; /* block's block number in the file */
UCHAR mb_flags; /* priority and usage requested */
UCHAR mb_age; /* how long block has been in list */
struct mb_struct *mb_newer;/* pointer to newer block */
struct mb_struct *mb_older;/* pointer to older block */
} MEMBLK;
int Memup[] = { 0 }; /* Memory is initialized */
static MEMBLK Memlist[MM_NBLKS];/* Memory headers */
static MEMBLK *Memnewest[1]; /* Newest memory block */
/* Initialize the block buffering system. */
meminit()
{
register MEMBLK *mp;
/* If this has already been done, return. */
if (Memup[0])
return(1);
/* Allocate space for each memory block; initialize each control
structure. */
for (mp = Memlist + MM_NBLKS; --mp >= Memlist; )
{
if (!(mp->mb_blk = (char *) zalloc(_SPTHID[0], MM_BLKSIZE)))
return(0);
mp->mb_file = H_ERROR;
mp->mb_flags = 0;
mp->mb_newer = mp - 1;
mp->mb_older = mp + 1;
}
/* Make the linked list into a circular queue. */
Memlist[0].mb_newer = &Memlist[MM_NBLKS - 1];
Memlist[MM_NBLKS - 1].mb_older = Memlist;
/* Initialize the top of memory pointer. */
Memnewest[0] = Memlist;
/* Memory has been initialized */
Memup[0] = 1;
return(1);
}
/* See if a block for a given file is in memory. */
MEMBLK *memcheck(file, blknum)
HANDLE file; /* The file the block is in. */
int blknum; /* The block number. */
{
register MEMBLK *mp;
mp = Memnewest[0];
while (mp->mb_file != file || mp->mb_blknum != blknum)
{
mp = mp->mb_older;
if (mp == Memnewest[0])
return (NULL);
}
return (mp);
}
/* Put a buffer at the top of the list. This is the only routine that
changes the memory control links. */
void
memlink(mp)
register MEMBLK *mp;
{
register MEMBLK *new;
/* Do nothing if the buffer is already at the top of the list. */
new = Memnewest[0];
if (new == mp)
return;
/* Unlink the buffer from the list. */
mp->mb_newer->mb_older = mp->mb_older;
mp->mb_older->mb_newer = mp->mb_newer;
/* Add it to the top of the list. */
Memnewest[0] = mp;
mp->mb_newer = new->mb_newer;
mp->mb_older = new;
new->mb_newer->mb_older = mp;
new->mb_newer = mp;
}
/* Make a buffer unused. If the buffer contained modified data, write that
data to disk. */
memdel(mp)
register MEMBLK *mp;
{
/* Write the block, if it was modified. */
if (!memwrite(mp))
return (FALSE);
/* make the buffer unused. */
mp->mb_file = H_ERROR;
mp->mb_flags = 0;
/* Make this buffer the newest; since the list is circular, moving
the newest pointer down to the next oldest will make this block
the oldest. */
memlink(mp);
Memnewest[0] = (Memnewest[0])->mb_older;
return (TRUE);
}
/* Write a block to disk. */
memwrite(mp)
register MEMBLK *mp;
{
/* Do not write it if it was not modified. */
if (!(mp->mb_flags & MM_WRITE))
return (TRUE);
/* Seek to the proper place and then write the buffer. */
if (stdseek((long)mp->mb_blknum * MM_BLKSIZE, mp->mb_file)
|| stdwrite((char *)mp->mb_blk, MM_BLKSIZE, mp->mb_file)
!= MM_BLKSIZE)
return (FALSE);
/* Mark the buffer as no longer modified. */
mp->mb_flags &= ~MM_WRITE;
return (TRUE);
}
/* Get a buffer for a block. */
UCHAR *
memread(blknum, file, flags)
|