Commit b703fad1 authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

file library update to 1.9.0.

parent 2784bed9
......@@ -22,7 +22,6 @@
#include <sys/time.h> // gettimeofday()
#endif
#include "dmemory.h"
#include "error.h"
#include "file.h"
......@@ -39,12 +38,10 @@ char *strdup(const char *s);
#endif
#ifdef HAVE_MMAP
#include <sys/mman.h> /* mmap() is defined in this header */
#include <sys/mman.h> // mmap() is defined in this header
#endif
/* #define MAX_FILES FOPEN_MAX */
#define MAX_FILES 8192
#define MAX_FILES 8192
static int _file_max = MAX_FILES;
static void file_initialize(void);
......@@ -54,92 +51,81 @@ static bool _file_init = false;
#ifdef HAVE_LIBPTHREAD
#include <pthread.h>
static pthread_once_t _file_init_thread = PTHREAD_ONCE_INIT;
static pthread_once_t _file_init_thread = PTHREAD_ONCE_INIT;
static pthread_mutex_t _file_mutex;
#define FILE_LOCK() pthread_mutex_lock(&_file_mutex)
#define FILE_UNLOCK() pthread_mutex_unlock(&_file_mutex)
#define FILE_INIT() \
if ( _file_init == false ) pthread_once(&_file_init_thread, file_initialize)
#define FILE_LOCK() pthread_mutex_lock(&_file_mutex)
#define FILE_UNLOCK() pthread_mutex_unlock(&_file_mutex)
#define FILE_INIT() \
if (_file_init == false) pthread_once(&_file_init_thread, file_initialize)
#else
#define FILE_LOCK()
#define FILE_UNLOCK()
#define FILE_INIT() \
if ( _file_init == false ) file_initialize()
#define FILE_INIT() \
if (_file_init == false) file_initialize()
#endif
typedef struct
{
int self;
int flag; /* access and error flag */
int eof; /* end of file flag */
int fd; /* file descriptor used for read */
FILE *fp; /* FILE pointer used for write */
char *name; /* file name */
off_t size; /* file size */
off_t position; /* file position */
long access; /* file access */
off_t byteTrans; /* */
size_t blockSize; /* file block size */
int mode; /* file access mode */
short type; /* file type ( 1:open 2:fopen ) */
short bufferType; /* buffer type ( 1:std 2:mmap ) */
size_t bufferSize; /* file buffer size */
size_t mappedSize; /* mmap buffer size */
char *buffer; /* file buffer */
long bufferNumFill; /* number of buffer fill */
char *bufferPtr; /* file buffer pointer */
off_t bufferPos;
off_t bufferStart;
off_t bufferEnd;
size_t bufferCnt;
double time_in_sec;
}
bfile_t;
enum F_I_L_E_Flags
{
FILE_READ = 01,
FILE_WRITE = 02,
FILE_UNBUF = 04,
FILE_EOF = 010,
FILE_ERROR = 020
};
static bool FileInfo = false;
int self;
int flag; // access and error flag
int eof; // end of file flag
int fd; // file descriptor used for read
FILE *fp; // FILE pointer used for write
char *name; // file name
off_t size; // file size
off_t position; // file position
long access; // file access
off_t byteTrans; //
size_t blockSize; // file block size
int mode; // file access mode
int type; // file type [1:open 2:fopen]
int bufferType; // buffer type [1:std 2:mmap]
size_t bufferSize; // file buffer size
size_t mappedSize; // mmap buffer size
char *buffer; // file buffer
long bufferNumFill; // number of buffer fill
char *bufferPtr; // file buffer pointer
off_t bufferPos;
off_t bufferStart;
off_t bufferEnd;
size_t bufferCnt;
double time_in_sec;
} bfile_t;
enum FILE_Flags
{
FILE_EOF = 010,
FILE_ERROR = 020
};
#ifndef MIN_BUF_SIZE
#define MIN_BUF_SIZE 131072L
#define MIN_BUF_SIZE 131072L
#endif
static const char *fbtname[] = { "unknown", "standard", "mmap" };
static const char *ftname[] = { "unknown", "open", "fopen" };
static size_t FileBufferSizeMin = MIN_BUF_SIZE;
static long FileBufferSizeEnv = -1;
static short FileBufferTypeEnv = 0;
static short FileTypeRead = FILE_TYPE_OPEN;
static short FileTypeWrite = FILE_TYPE_FOPEN;
static int FileFlagWrite = 0;
static long FileBufferSizeEnv = -1;
static int FileBufferTypeEnv = 0;
static int FILE_Debug = 0; /* If set to 1, debugging */
static int FileTypeRead = FILE_TYPE_OPEN;
static int FileTypeWrite = FILE_TYPE_FOPEN;
static int FileFlagWrite = 0;
static int FileDebug = 0; // If set to 1, debugging
static bool FileInfo = false;
static void file_table_print(void);
/*
* A version string.
*/
#undef LIBVERSION
#define LIBVERSION 1.9.0
#define XSTRING(x) #x
#define STRING(x) XSTRING(x)
// A version string.
#undef LIBVERSION
#define LIBVERSION 1.9.1
#define XSTRING(x) #x
#define STRING(x) XSTRING(x)
static const char file_libvers[] = STRING(LIBVERSION);
/*
......@@ -159,65 +145,64 @@ static const char file_libvers[] = STRING(LIBVERSION);
02/02/2012 1.8.0 cleanup
16/11/2012 1.8.1 added support for unbuffered write
27/06/2013 1.8.2 added env. var. FILE_TYPE_WRITE (1:open; 2:fopen)
29/04/2020 1.9.0 fileSetPos(): refactored
30/04/2020 1.9.1 fileSetPos(): not initialized correctly (bug fix)
*/
typedef struct _filePtrToIdx {
typedef struct _filePtrToIdx
{
int idx;
bfile_t *ptr;
struct _filePtrToIdx *next;
} filePtrToIdx;
static filePtrToIdx *_fileList = NULL;
static filePtrToIdx *_fileList = NULL;
static filePtrToIdx *_fileAvail = NULL;
static
void file_list_new(void)
static void
file_list_new(void)
{
assert(_fileList == NULL);
_fileList = (filePtrToIdx *) Malloc((size_t)_file_max*sizeof(filePtrToIdx));
_fileList = (filePtrToIdx *) malloc((size_t) _file_max * sizeof(filePtrToIdx));
}
static
void file_list_delete(void)
static void
file_list_delete(void)
{
if ( _fileList )
if (_fileList)
{
Free(_fileList);
free(_fileList);
_fileList = NULL;
}
}
static
void file_init_pointer(void)
static void
file_init_pointer(void)
{
for ( int i = 0; i < _file_max; i++ )
for (int i = 0; i < _file_max; i++)
{
_fileList[i].next = _fileList + i + 1;
_fileList[i].idx = i;
_fileList[i].ptr = 0;
_fileList[i].idx = i;
_fileList[i].ptr = 0;
}
_fileList[_file_max-1].next = 0;
_fileList[_file_max - 1].next = 0;
_fileAvail = _fileList;
}
static
bfile_t *file_to_pointer(int idx)
static bfile_t *
file_to_pointer(int idx)
{
bfile_t *fileptr = NULL;
FILE_INIT();
if ( idx >= 0 && idx < _file_max )
if (idx >= 0 && idx < _file_max)
{
FILE_LOCK();
fileptr = _fileList[idx].ptr;
FILE_UNLOCK();
}
else
......@@ -226,28 +211,26 @@ bfile_t *file_to_pointer(int idx)
return fileptr;
}
/* Create an index from a pointer */
static
int file_from_pointer(bfile_t *ptr)
// Create an index from a pointer
static int
file_from_pointer(bfile_t *ptr)
{
int idx = -1;
filePtrToIdx *newptr;
if ( ptr )
if (ptr)
{
FILE_LOCK();
if ( _fileAvail )
{
newptr = _fileAvail;
_fileAvail = _fileAvail->next;
newptr->next = 0;
idx = newptr->idx;
newptr->ptr = ptr;
if ( FILE_Debug )
Message("Pointer %p has idx %d from file list", ptr, idx);
}
if (_fileAvail)
{
filePtrToIdx *newptr = _fileAvail;
_fileAvail = _fileAvail->next;
newptr->next = 0;
idx = newptr->idx;
newptr->ptr = ptr;
if (FileDebug) Message("Pointer %p has idx %d from file list", ptr, idx);
}
else
{
Warning("Too many open files (limit is %d)!", _file_max);
......@@ -262,100 +245,69 @@ int file_from_pointer(bfile_t *ptr)
return idx;
}
static
void file_init_entry(bfile_t *fileptr)
static void
file_init_entry(bfile_t *fileptr)
{
fileptr->self = file_from_pointer(fileptr);
fileptr->flag = 0;
fileptr->fd = -1;
fileptr->fp = NULL;
fileptr->mode = 0;
fileptr->size = 0;
fileptr->name = NULL;
fileptr->access = 0;
fileptr->position = 0;
fileptr->byteTrans = 0;
fileptr->type = 0;
fileptr->bufferType = 0;
fileptr->bufferSize = 0;
fileptr->mappedSize = 0;
fileptr->buffer = NULL;
fileptr->self = file_from_pointer(fileptr);
fileptr->flag = 0;
fileptr->fd = -1;
fileptr->fp = NULL;
fileptr->mode = 0;
fileptr->size = 0;
fileptr->name = NULL;
fileptr->access = 0;
fileptr->position = 0;
fileptr->byteTrans = 0;
fileptr->type = 0;
fileptr->bufferType = 0;
fileptr->bufferSize = 0;
fileptr->mappedSize = 0;
fileptr->buffer = NULL;
fileptr->bufferNumFill = 0;
fileptr->bufferStart = 0;
fileptr->bufferEnd = -1;
fileptr->bufferPos = 0;
fileptr->bufferCnt = 0;
fileptr->bufferPtr = NULL;
fileptr->time_in_sec = 0.0;
fileptr->bufferStart = 0;
fileptr->bufferEnd = -1;
fileptr->bufferPos = 0;
fileptr->bufferCnt = 0;
fileptr->bufferPtr = NULL;
fileptr->time_in_sec = 0.0;
}
static
bfile_t *file_new_entry(void)
static bfile_t *
file_new_entry(void)
{
bfile_t *fileptr = (bfile_t *) Malloc(sizeof(bfile_t));
if ( fileptr ) file_init_entry(fileptr);
bfile_t *fileptr = (bfile_t *) malloc(sizeof(bfile_t));
if (fileptr) file_init_entry(fileptr);
return fileptr;
}
static
void file_delete_entry(bfile_t *fileptr)
static void
file_delete_entry(bfile_t *fileptr)
{
int idx = fileptr->self;
const int idx = fileptr->self;
FILE_LOCK();
Free(fileptr);
free(fileptr);
_fileList[idx].next = _fileAvail;
_fileList[idx].ptr = 0;
_fileAvail = &_fileList[idx];
_fileList[idx].ptr = 0;
_fileAvail = &_fileList[idx];
FILE_UNLOCK();
if ( FILE_Debug )
Message("Removed idx %d from file list", idx);
if (FileDebug) Message("Removed idx %d from file list", idx);
}
const char *fileLibraryVersion(void)
const char *
fileLibraryVersion(void)
{
return file_libvers;
}
static
int pagesize(void)
static int
file_pagesize(void)
{
static int my_pagesize = -1;
static bool _pagesize_init = false;
if (! _pagesize_init)
{
_pagesize_init = true;
char *envSize = getenv ("PBIO_PAGESIZE");
if (envSize != NULL)
{
int loop;
for (loop = 0; loop < (int) strlen(envSize) ; loop++)
{
if ( ! isdigit((int) envSize[loop]) )
{
printf("Invalid character in PBIO_PAGESIZE: %s\n", envSize);
printf("PBIO_PAGESIZE must comprise only digits [0-9].\n");
exit(EXIT_FAILURE);
}
}
my_pagesize = atol(envSize);
if (my_pagesize <= 0 || (my_pagesize & (my_pagesize-1)) != 0)
{
printf("Invalid value in PBIO_PAGESIZE: %s\n", envSize);
printf("Pagesize defined by PBIO_PAGESIZE must be power of 2.\n");
exit(EXIT_FAILURE);
}
}
}
if (my_pagesize > 0) return my_pagesize;
#ifdef _SC_PAGESIZE
return (int) sysconf(_SC_PAGESIZE);
#else
......@@ -366,34 +318,35 @@ int pagesize(void)
#endif
}
static
double file_time()
static double
file_time()
{
#ifdef HAVE_SYS_TIME_H
struct timeval mytime;
gettimeofday(&mytime, NULL);
return (double) mytime.tv_sec + (double) mytime.tv_usec*1.0e-6;
return (double) mytime.tv_sec + (double) mytime.tv_usec * 1.0e-6;
#else
return 0;
#endif
}
void fileDebug(int debug)
void
fileDebug(int debug)
{
FILE_Debug = debug;
if ( FILE_Debug ) Message("Debug level %d", debug);
FileDebug = debug;
if (FileDebug) Message("Debug level %d", debug);
}
void *filePtr(int fileID)
void *
filePtr(int fileID)
{
return (void*)file_to_pointer(fileID);
return (void *) file_to_pointer(fileID);
}
static
void file_pointer_info(const char *caller, int fileID)
static void
file_pointer_info(const char *caller, int fileID)
{
if ( FILE_Debug )
if (FileDebug)
{
fprintf(stdout, "%-18s : ", caller);
fprintf(stdout, "The fileID %d underlying pointer is not valid!", fileID);
......@@ -401,533 +354,487 @@ void file_pointer_info(const char *caller, int fileID)
}
}
int fileSetBufferType(int fileID, int type)
int
fileSetBufferType(int fileID, int type)
{
int ret = 0;
bfile_t *fileptr = file_to_pointer(fileID);
if ( fileptr )
bfile_t *fileptr = file_to_pointer(fileID);
if (fileptr)
{
switch (type)
{
case FILE_BUFTYPE_STD:
case FILE_BUFTYPE_MMAP:
fileptr->bufferType = (short)type;
break;
default:
Error("File type %d not implemented!", type);
}
{
case FILE_BUFTYPE_STD:
case FILE_BUFTYPE_MMAP: fileptr->bufferType = type; break;
default: Error("File type %d not implemented!", type);
}
}
#ifndef HAVE_MMAP
if ( type == FILE_BUFTYPE_MMAP ) ret = 1;
if (type == FILE_BUFTYPE_MMAP) ret = 1;
#endif
return ret;
}
int fileFlush(int fileID)
int
fileFlush(int fileID)
{
int retval = 0;
bfile_t *fileptr = file_to_pointer(fileID);
if ( fileptr ) retval = fflush(fileptr->fp);
return retval;
return fileptr ? fflush(fileptr->fp) : 0;
}
void fileClearerr(int fileID)
void
fileClearerr(int fileID)
{
bfile_t *fileptr = file_to_pointer(fileID);
if ( fileptr )
if (fileptr)
{
if ( fileptr->mode != 'r' )
clearerr(fileptr->fp);
if (fileptr->mode != 'r') clearerr(fileptr->fp);
}
}
int filePtrEOF(void *vfileptr)
int
filePtrEOF(void *vfileptr)
{
int retval = 0;
bfile_t *fileptr = (bfile_t *) vfileptr;
if ( fileptr ) retval = (fileptr->flag & FILE_EOF) != 0;
return retval;
return fileptr ? (fileptr->flag & FILE_EOF) != 0 : 0;
}
int fileEOF(int fileID)
int
fileEOF(int fileID)
{
int retval = 0;
bfile_t *fileptr = file_to_pointer(fileID);
if ( fileptr ) retval = (fileptr->flag & FILE_EOF) != 0;
return retval;
return fileptr ? (fileptr->flag & FILE_EOF) != 0 : 0;
}
void fileRewind(int fileID)
void
fileRewind(int fileID)
{
fileSetPos(fileID, (off_t) 0, SEEK_SET);
fileClearerr(fileID);
}
off_t fileGetPos(int fileID)
off_t
fileGetPos(int fileID)
{
off_t filepos = 0;
bfile_t *fileptr = file_to_pointer(fileID);
if ( fileptr )
bfile_t *fileptr = file_to_pointer(fileID);
if (fileptr)
{
if ( fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN )
filepos = fileptr->position;
if (fileptr->mode == 'r' && fileptr->type == FILE_TYPE_OPEN)
filepos = fileptr->position;
else
filepos = ftell(fileptr->fp);
filepos = ftell(fileptr->fp);
}
if ( FILE_Debug ) Message("Position %ld", filepos);
if (FileDebug) Message("Position %ld", filepos);
return filepos;
}
static int
file_set_buffer_pos(bfile_t *fileptr)
{
const off_t position = fileptr->position;
if (position < fileptr->bufferStart || position > fileptr->bufferEnd)
{
if (fileptr->bufferType == FILE_BUFTYPE_STD)
fileptr->bufferPos = position;
else
fileptr->bufferPos = position - position % file_pagesize();
int fileSetPos(int fileID, off_t offset, int whence)
fileptr->bufferCnt = 0;
fileptr->bufferPtr = NULL;
return 1;
}
return 0;
}
static void
file_check_buffer_pos(bfile_t *fileptr)