Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
mpim-sw
libcdi
Commits
b703fad1
Commit
b703fad1
authored
Apr 30, 2020
by
Uwe Schulzweida
Browse files
file library update to 1.9.0.
parent
2784bed9
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/file.c
View file @
b703fad1
...
...
@@ -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
*
)
M
alloc
((
size_t
)
_file_max
*
sizeof
(
filePtrToIdx
));
_fileList
=
(
filePtrToIdx
*
)
m
alloc
((
size_t
)
_file_max
*
sizeof
(
filePtrToIdx
));
}
static
void
file_list_delete
(
void
)
static
void
file_list_delete
(
void
)
{
if
(
_fileList
)
if
(
_fileList
)
{
F
ree
(
_fileList
);
f
ree
(
_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
();
F
ree
(
fileptr
);
f
ree
(
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
)
{
F
ILE_
Debug
=
debug
;
if
(
FILE_
Debug
)
Message
(
"Debug level %d"
,
debug
);
F
ile
Debug
=
debug
;
if
(
File
Debug
)
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
(
File
Debug
)
{
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
(
File
Debug
)
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
)