Changeset - r5967:3569c8447441
[Not reviewed]
master
0 2 0
truelight - 17 years ago 2007-02-08 23:46:25
truelight@openttd.org
(svn r8647) -Codechange: add a general way to handle platforms who can only have a limited amount of file-descripters open at any given time.
The Fios keeps track how many times a file is opened, and tries to close up files which aren't used often.
The first platform using this is PSP. Patch based on the work of Turulo.
2 files changed with 70 insertions and 3 deletions:
0 comments (0 inline, 0 general)
src/fileio.cpp
Show inline comments
 
@@ -7,19 +7,26 @@
 
#include "string.h"
 
#include "macros.h"
 
#include "variables.h"
 
#include "debug.h"
 

	
 
/*************************************************/
 
/* FILE IO ROUTINES ******************************/
 
/*************************************************/
 

	
 
#define FIO_BUFFER_SIZE 512
 
#define MAX_HANDLES 64
 

	
 
typedef struct {
 
	byte *buffer, *buffer_end;          ///< position pointer in local buffer and last valid byte of buffer
 
	uint32 pos;                         ///< current (system) position in file
 
	FILE *cur_fh;                       ///< current file handle
 
	FILE *handles[64];                  ///< array of file handles we can have open
 
	FILE *handles[MAX_HANDLES];         ///< array of file handles we can have open
 
	byte buffer_start[FIO_BUFFER_SIZE]; ///< local buffer when read from file
 
#if defined(LIMITED_FDS)
 
	uint open_handles;                  ///< current amount of open handles
 
	const char *filename[MAX_HANDLES];  ///< array of filenames we (should) have open
 
	uint usage_count[MAX_HANDLES];      ///< count how many times this file has been opened
 
#endif /* LIMITED_FDS */
 
} Fio;
 

	
 
static Fio _fio;
 
@@ -38,10 +45,27 @@ void FioSeekTo(uint32 pos, int mode)
 
	fseek(_fio.cur_fh, _fio.pos, SEEK_SET);
 
}
 

	
 
#if defined(LIMITED_FDS)
 
static void FioRestoreFile(int slot)
 
{
 
	/* Do we still have the file open, or should we reopen it? */
 
	if (_fio.handles[slot] == NULL) {
 
		DEBUG(misc, 6, "Restoring file '%s' in slot '%d' from disk", _fio.filename[slot], slot);
 
		FioOpenFile(slot, _fio.filename[slot]);
 
	}
 
	_fio.usage_count[slot]++;
 
}
 
#endif /* LIMITED_FDS */
 

	
 
// Seek to a file and a position
 
void FioSeekToFile(uint32 pos)
 
{
 
	FILE *f = _fio.handles[pos >> 24];
 
	FILE *f;
 
#if defined(LIMITED_FDS)
 
	/* Make sure we have this file open */
 
	FioRestoreFile(pos >> 24);
 
#endif /* LIMITED_FDS */
 
	f = _fio.handles[pos >> 24];
 
	assert(f != NULL);
 
	_fio.cur_fh = f;
 
	FioSeekTo(GB(pos, 0, 24), SEEK_SET);
 
@@ -92,6 +116,9 @@ static inline void FioCloseFile(int slot
 
	if (_fio.handles[slot] != NULL) {
 
		fclose(_fio.handles[slot]);
 
		_fio.handles[slot] = NULL;
 
#if defined(LIMITED_FDS)
 
		_fio.open_handles--;
 
#endif /* LIMITED_FDS */
 
	}
 
}
 

	
 
@@ -112,6 +139,30 @@ bool FioCheckFileExists(const char *file
 
	return true;
 
}
 

	
 
#if defined(LIMITED_FDS)
 
static void FioFreeHandle()
 
{
 
	/* If we are about to open a file that will exceed the limit, close a file */
 
	if (_fio.open_handles + 1 == LIMITED_FDS) {
 
		uint i, count;
 
		int slot;
 

	
 
		count = UINT_MAX;
 
		slot = -1;
 
		/* Find the file that is used the least */
 
		for (i = 0; i < lengthof(_fio.handles); i++) {
 
			if (_fio.handles[i] != NULL && _fio.usage_count[i] < count) {
 
				count = _fio.usage_count[i];
 
				slot  = i;
 
			}
 
		}
 
		assert(slot != -1);
 
		DEBUG(misc, 6, "Closing filehandler '%s' in slot '%d' because of fd-limit", _fio.filename[slot], slot);
 
		FioCloseFile(slot);
 
	}
 
}
 
#endif /* LIMITED_FDS */
 

	
 
FILE *FioFOpenFile(const char *filename)
 
{
 
	FILE *f;
 
@@ -141,11 +192,20 @@ FILE *FioFOpenFile(const char *filename)
 

	
 
void FioOpenFile(int slot, const char *filename)
 
{
 
	FILE *f = FioFOpenFile(filename);
 
	FILE *f;
 

	
 
#if defined(LIMITED_FDS)
 
	FioFreeHandle();
 
#endif /* LIMITED_FDS */
 
	f = FioFOpenFile(filename);
 
	if (f == NULL) error("Cannot open file '%s%s'", _paths.data_dir, filename);
 

	
 
	FioCloseFile(slot); // if file was opened before, close it
 
	_fio.handles[slot] = f;
 
#if defined(LIMITED_FDS)
 
	_fio.filename[slot] = filename;
 
	_fio.usage_count[slot] = 0;
 
	_fio.open_handles++;
 
#endif /* LIMITED_FDS */
 
	FioSeekToFile(slot << 24);
 
}
src/stdafx.h
Show inline comments
 
@@ -77,6 +77,13 @@
 
# define BSWAP16(x) ((x) >> 8 | (x) << 8)
 
#endif /* __APPLE__ */
 

	
 
#if defined(PSP)
 
/* PSP can only have 10 file-descriptors open at any given time, but this
 
 *  switch only limits reads via the Fio system. So keep 2 fds free for things
 
 *  like saving a game. */
 
#define LIMITED_FDS 8
 
#endif /* PSP */
 

	
 
/* by default we use [] var arrays */
 
#define VARARRAY_SIZE
 

	
0 comments (0 inline, 0 general)