/** registers the 'file' as open. return 1 on success, 0 otherwise. */ int OTF_FileManager_registerFile( OTF_FileManager* m, OTF_File* file ) { /* OTF_fprintf( stderr, "OTF_FileManager_registerFile()\n" ); */ if ( OTF_FILESTATUS_ACTIVE != OTF_File_status( file ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "file not open.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } if ( m->count >= m->number ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "cannot register new file because limit %u exceeded, call " "'OTF_FileManager_guaranteeFile()' before.\n", __FUNCTION__, __FILE__, __LINE__, m->number ); return 0; } OTF_FileManager_listInsertAtHead( &(m->list), file ); /* OTF_fprintf( stderr, " c++ %u -> %u\n", m->count, m->count+1 ); */ m->count++; return 1; }
uint64_t OTF_File_size( OTF_File* file ) { struct stat st; if ( NULL != file->externalbuffer ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "not yet supported in 'external buffer' mode.\n", __FUNCTION__, __FILE__, __LINE__ ); return (uint64_t) -1; } if ( stat( file->filename, &st ) == -1 ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "stat() failed: %s\n", __FUNCTION__, __FILE__, __LINE__, strerror(errno) ); return 0; } else { return st.st_size; } }
void OTF_FileManager_listPrint( OTF_FileList** list ) { OTF_FileList* pos; if ( NULL == *list ) { OTF_fprintf( stderr, "empty list\n ----- \n" ); return; } pos= *list; OTF_fprintf( stderr, "head: %p --> %p (%p %u)\n", (void*)pos, (void*)pos->next, (void*)pos->file, OTF_File_status( pos->file ) ); while ( pos != (*list)->prev ) { pos= pos->next; OTF_fprintf( stderr, " %p --> %p (%p %u)\n", (void*)pos, (void*)pos->next, (void*)pos->file, OTF_File_status( pos->file ) ); } OTF_fprintf( stderr, " ----- \n" ); }
void OTF_File_setZBufferSize( OTF_File* file, uint32_t size ) { #ifdef HAVE_ZLIB if( NULL != file->z ) { if ( 32 > size ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "intended zbuffer size %u is too small, rejected.\n", __FUNCTION__, __FILE__, __LINE__, size ); return; } else if ( 512 > size ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "zbuffer size %u is very small, accepted though.\n", __FUNCTION__, __FILE__, __LINE__, size ); } else if ( 10 * 1024 *1024 < size ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "zbuffer size %u is rather big, accepted though.\n", __FUNCTION__, __FILE__, __LINE__, size ); } file->zbuffersize= size; if( NULL != file->zbuffer ) { free( file->zbuffer ); } file->zbuffer= malloc( size ); assert( file->zbuffer ); if( NULL != file->ybuffer ) { free( file->ybuffer ); } file->ybuffer= malloc( size ); assert( file->ybuffer ); } #endif /* HAVE_ZLIB */ }
OTF_HandlerArray* OTF_HandlerArray_open() { OTF_HandlerArray* ret; ret = (OTF_HandlerArray*) malloc( sizeof( OTF_HandlerArray ) ); if( NULL == ret ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "no memory left.\n", __FUNCTION__, __FILE__, __LINE__ ); return NULL; } ret->pointer = (OTF_FunctionPointer**) malloc( OTF_NRECORDS * sizeof( OTF_FunctionPointer* ) ); if( NULL == ret->pointer ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "no memory left.\n", __FUNCTION__, __FILE__, __LINE__ ); free( ret ); ret= NULL; return NULL; } ret->firsthandlerarg = (void**) malloc( OTF_NRECORDS * sizeof( void* ) ); if( NULL == ret->firsthandlerarg ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "no memory left.\n", __FUNCTION__, __FILE__, __LINE__ ); free( ret->pointer ); ret->pointer= NULL; free( ret ); ret= NULL; return NULL; } OTF_HandlerArray_init( ret ); return ret; }
OTF_FileStatus OTF_File_status( OTF_File* file ) { if ( NULL != file->externalbuffer ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "not yet supported in 'external buffer' mode.\n", __FUNCTION__, __FILE__, __LINE__ ); return OTF_FILESTATUS_UNKNOWN; } if ( NULL == file->file ) { if ( 0 == file->pos ) { return OTF_FILESTATUS_CLOSED; } else { return OTF_FILESTATUS_SUSPENDED; } } return OTF_FILESTATUS_ACTIVE; }
void OTF_FileManager_finalize( OTF_FileManager* manager ) { OTF_FileList* pos; OTF_FileList* next; # ifdef OTF_DEBUG if ( 0 < manager->count ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "open file remaining.\n", __FUNCTION__, __FILE__, __LINE__ ); } # endif /* OTF_DEBUG */ if ( NULL != manager->list ) { pos= manager->list; pos->prev->next= NULL; while ( NULL != pos ) { next = pos->next; free( pos ); pos = next; } } manager->list= NULL; }
int OTF_FileManager_listInsertAtHead( OTF_FileList** list, OTF_File* entry ) { OTF_FileList* newentry= (OTF_FileList*) malloc( sizeof(OTF_FileList) ); if( NULL == newentry ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "no memory left.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } if ( NULL != (*list) ) { /* OTF_fprintf( stderr, "pre insert : %p --> %p (%p)\n", *list, (*list)->next, (*list)->file ); */ newentry->file= entry; newentry->prev= (*list)->prev; newentry->next= (*list); /* OTF_fprintf( stderr, "new entry : %p --> %p (%p)\n", newentry, newentry->next, newentry->file ); */ (*list)->prev->next= newentry; (*list)->prev= newentry; *list= newentry; /* OTF_fprintf( stderr, "post insert: %p --> %p (%p)\n", *list, (*list)->next, (*list)->file ); */ } else { /* empty list */ newentry->file= entry; newentry->prev= newentry; newentry->next= newentry; *list= newentry; } /* OTF_fprintf( stderr, "after OTF_FileManager_listInsertAtHead():\n" ); */ /* OTF_FileManager_listPrint( list ); */ return 0; }
/** suspend an open file explicitly. this may be called externaly or internally. return 1 on success, 0 otherwise. */ int OTF_FileManager_suspendFile( OTF_FileManager* m, OTF_File* file ) { /* OTF_fprintf( stderr, "OTF_FileManager_suspendFile()\n" ); */ if ( OTF_FILESTATUS_ACTIVE != OTF_File_status( file ) ) { /* file not open, so cannot be suspended */ OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "file to be suspended is not open.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } if ( 0 == OTF_FileManager_listUnlinkAtTail( &(m->list), file ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "could not unlink this entry.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; }; /* OTF_fprintf( stderr, " c-- %u -> %u\n", m->count, m->count-1 ); */ m->count--; OTF_File_suspend( file ); return 1; }
int OTF_HandlerArray_setHandler( OTF_HandlerArray* handlers, OTF_FunctionPointer* pointer, uint32_t recordtype ) { if( recordtype >= OTF_NRECORDS ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "unknown record type %u.\n", __FUNCTION__, __FILE__, __LINE__, recordtype ); return 0; } handlers->pointer[recordtype] = pointer; return 1; }
uint32_t OTF_FileManager_setNumber( OTF_FileManager* fh, uint32_t number ) { if ( 0 == number ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "illegal value 0 ignored.\n", __FUNCTION__, __FILE__, __LINE__ ); return fh->number; } fh->number= number; return fh->number; }
int OTF_HandlerArray_setFirstHandlerArg( OTF_HandlerArray* handlers, void* firsthandlerarg, uint32_t recordtype ) { if( recordtype >= OTF_NRECORDS ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "unknown record type %u.\n", __FUNCTION__, __FILE__, __LINE__, recordtype ); return 0; } handlers->firsthandlerarg[recordtype] = firsthandlerarg; return 1; }
void OTF_File_suspend( OTF_File* file ) { if ( NULL != file->externalbuffer ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "not yet supported in 'external buffer' mode.\n", __FUNCTION__, __FILE__, __LINE__ ); return; } /* get status and close OS file */ file->pos= ftello( file->file ); fclose( file->file ); file->file= NULL; }
int OTF_HandlerArray_close( OTF_HandlerArray* handlers ) { if( NULL == handlers ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "handlers have not been specified.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } OTF_HandlerArray_finish( handlers ); free( handlers ); handlers = NULL; return 1; }
uint64_t OTF_File_tell( OTF_File* file ) { if ( NULL != file->externalbuffer ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "not yet supported in 'external buffer' mode.\n", __FUNCTION__, __FILE__, __LINE__ ); return (uint64_t) -1; } if ( NULL != file->file ) { file->pos= ftello( file->file ); } return file->pos; }
uint64_t OTF_File_size( OTF_File* file ) { struct stat st; if ( stat( file->filename, &st ) == -1 ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "stat() failed: %s\n", __FUNCTION__, __FILE__, __LINE__, strerror(errno) ); return 0; } else { return st.st_size; } }
OTF_FileManager* OTF_FileManager_open( uint32_t number ) { OTF_FileManager* ret= (OTF_FileManager*) malloc( sizeof(OTF_FileManager) ); if( NULL == ret ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "no memory left.\n", __FUNCTION__, __FILE__, __LINE__ ); return NULL; } OTF_FileManager_init( ret ); OTF_FileManager_setNumber( ret, number ); return ret; }
/** ensure there is a free file handle available after this call. return 1 on success, 0 otherwise (which is not supposed to happen) */ int OTF_FileManager_guaranteeFile( OTF_FileManager* m ) { /* OTF_fprintf( stderr, "OTF_FileManager_guaranteeFile()\n" ); */ if ( m->count < m->number ) { /* free file handles available */ /* OTF_fprintf( stderr, " OTF_FileManager_guaranteeFile() free handles left\n" ); */ return 1; } /* OTF_fprintf( stderr, " OTF_FileManager_guaranteeFile() need new handles\n" ); */ /* suspend last entry in list */ if ( 0 == OTF_FileManager_suspendFile( m, m->list->file ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_FileManager_suspendFile() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } /* OTF_fprintf( stderr, "post suspend %u / %u\n", m->count, m->number ); */ return 1; }
int OTF_File_revive( OTF_File* file, OTF_FileMode mode ) { switch ( mode ) { case OTF_FILEMODE_READ : /* *** read *** */ if ( NULL == file->file ) { /* file currently closed */ /* OTF_fprintf( stderr, "OTF_File_revive() READ: ask FileManager for free handle\n" ); */ if ( 0 == OTF_FileManager_guaranteeFile( file->manager ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_FileManager_guaranteeFile() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } if ( 0 != file->pos ) { /* re-open */ file->file= fopen( file->filename, "rb" ); if( NULL == file->file ) { /* show this error every time */ OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "cannot open file %s for reading. Maybe the number of " "opened filehandles exceeds your system's limit\n", __FUNCTION__, __FILE__, __LINE__, file->filename ); return 0; } fseeko( file->file, file->pos, SEEK_SET ); } else { /* open first time */ file->file= fopen( file->filename, "rb" ); if( NULL == file->file ) { /* show this error every time */ OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "cannot open file %s for reading. Maybe the number of " "opened filehandles exceeds your system's limit\n", __FUNCTION__, __FILE__, __LINE__, file->filename ); return 0; } } if ( 0 == OTF_FileManager_registerFile( file->manager, file ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_FileManager_registerFile() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } } else { /* file already opened */ /* OTF_fprintf( stderr, "OTF_File_revive() READ: update FileManagers LRU list\n" ); */ if ( 0 == OTF_FileManager_touchFile( file->manager, file ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_FileManager_touchFile() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } } return 1; case OTF_FILEMODE_WRITE : /* *** write *** */ if ( NULL == file->file ) { /* file currently closed */ /* OTF_fprintf( stderr, "OTF_File_revive() WRITE: ask FileManager for free handle\n" ); */ if ( 0 == OTF_FileManager_guaranteeFile( file->manager ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_FileManager_guaranteeFile() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } if ( 0 != file->pos ) { /* re-open */ file->file= fopen( file->filename, "ab" ); if( NULL == file->file ) { /* show this error every time */ OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "cannot open file %s for writing. Maybe the number of " "opened filehandles exceeds your system's limit\n", __FUNCTION__, __FILE__, __LINE__, file->filename ); return 0; } } else { /* open first time */ file->file= fopen( file->filename, "wb" ); if( NULL == file->file ) { /* show this error every time */ OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "cannot open file %s for writing. Maybe the number of " "opened filehandles exceeds your system's limit\n", __FUNCTION__, __FILE__, __LINE__, file->filename ); return 0; } } /* OTF_fprintf( stderr, "OTF_File_revive() WRITE: register opened file with FileManager\n" ); */ if ( 0 == OTF_FileManager_registerFile( file->manager, file ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_FileManager_registerFile() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } } else { /* file already opened */ /* OTF_fprintf( stderr, "OTF_File_revive() WRITE: update FileManagers LRU list\n" ); */ if ( 0 == OTF_FileManager_touchFile( file->manager, file ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_FileManager_touchFile() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } } return 1; case OTF_FILEMODE_SEEK : /* *** seek *** */ if ( NULL == file->file ) { /* file currently closed */ /* OTF_fprintf( stderr, "OTF_File_revive() READ: ask FileManager for free handle\n" ); */ if ( 0 == OTF_FileManager_guaranteeFile( file->manager ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_FileManager_guaranteeFile() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } if ( 0 != file->pos ) { /* re-open */ file->file= fopen( file->filename, "rb" ); if( NULL == file->file ) { /* show this error every time */ OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "cannot open file %s for reading. Maybe the number of " "opened filehandles exceeds your system's limit\n", __FUNCTION__, __FILE__, __LINE__, file->filename ); return 0; } /* dont need to seek to the saved position because there will be another seek anyway*/ /* fseeko( file->file, file->pos, SEEK_SET ); */ } else { /* open first time */ file->file= fopen( file->filename, "rb" ); if( NULL == file->file ) { /* show this error every time */ OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "cannot open file %s for reading. Maybe the number of " "opened filehandles exceeds your system's limit\n", __FUNCTION__, __FILE__, __LINE__, file->filename ); return 0; } } /* OTF_fprintf( stderr, "OTF_File_revive() SEEK: register opened file with FileManager\n" ); */ if ( 0 == OTF_FileManager_registerFile( file->manager, file ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_FileManager_registerFile() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } } else { /* file already opened */ /* OTF_fprintf( stderr, "OTF_File_revive() READ: update FileManagers LRU list\n" ); */ if ( 0 == OTF_FileManager_touchFile( file->manager, file ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_FileManager_touchFile() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } } return 1; default: /* *** unknown mode *** */ return 0; } }
int OTF_File_close( OTF_File* file ) { #ifdef HAVE_ZLIB size_t byteswritten; int status; #endif /* HAVE_ZLIB */ if ( NULL == file ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "file has not been specified.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } #ifdef HAVE_ZLIB if ( NULL != file->z ) { if ( OTF_FILEMODE_WRITE != file->mode ) { inflateEnd( file->z ); } else { if ( file->z->avail_in > 0 ) { file->z->next_in = file->ybuffer; file->z->next_out = file->zbuffer; file->z->avail_out = file->zbuffersize; status = deflate( file->z, Z_FULL_FLUSH ); if ( status != Z_OK ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "error in uncompressing, status %u.\n", __FUNCTION__, __FILE__, __LINE__, status ); return 0; } if( 0 == OTF_File_revive( file, OTF_FILEMODE_WRITE ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_File_revive() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } byteswritten= fwrite( file->zbuffer, 1, file->zbuffersize - file->z->avail_out, file->file ); if( byteswritten < (file->zbuffersize - file->z->avail_out) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "less bytes written than expected %u < %u.\n", __FUNCTION__, __FILE__, __LINE__, (uint32_t) byteswritten, (uint32_t) (file->zbuffersize - file->z->avail_out) ); } } deflateEnd( file->z ); } free( file->z ); free( file->ybuffer ); free( file->zbuffer ); } #endif /* HAVE_ZLIB */ if ( NULL != file->file ) { OTF_FileManager_suspendFile( file->manager, file ); } free( file->filename ); OTF_File_finalize( file ); free( file ); file = NULL; return 1; }
int OTF_File_seek( OTF_File* file, uint64_t pos ) { int ret; #ifdef HAVE_ZLIB int sync; uint64_t read; #endif /* HAVE_ZLIB */ if( OTF_FILEMODE_WRITE == file->mode ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "current file->mode is OTF_FILEMODE_WRITE. seeking forbidden.\n", __FUNCTION__, __FILE__, __LINE__ ); return -1; } if( 0 == OTF_File_revive( file, OTF_FILEMODE_SEEK ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_File_revive() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return -1; } ret= fseeko( file->file, pos, SEEK_SET ); #ifdef HAVE_ZLIB if ( NULL != file->z && 0 == ret ) { do { /* OTF_fprintf( stderr, "OTF_File_seek() with zlib: jump to %llu\n", (unsigned long long) pos ); */ read= fread( file->zbuffer, 1, file->zbuffersize, file->file ); /* OTF_fprintf( stderr, "OTF_File_seek() with zlib: read %llu bytes\n", (unsigned long long) read ); */ file->z->next_in= file->zbuffer; file->z->avail_in= (uInt) read; file->z->total_in= 0; /* re-initialize z object */ inflateEnd( file->z ); inflateInit( file->z ); /* do not sync at very beginning of compressed stream because it would skip the first block */ sync= Z_OK; if ( 0 != pos ) { sync= inflateSync( file->z ); } if ( Z_OK == sync ) { return ret; } if ( Z_BUF_ERROR == sync ) { continue; } if ( Z_DATA_ERROR == sync ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "Z_DATA_ERROR.\n", __FUNCTION__, __FILE__, __LINE__ ); return -1; } if ( Z_STREAM_ERROR == sync ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "Z_STREAM_ERROR.\n", __FUNCTION__, __FILE__, __LINE__ ); return -1; } } while ( 1 ); } #endif /* HAVE_ZLIB */ return ret; }
size_t OTF_File_read( OTF_File* file, void* ptr, size_t size ) { #ifdef HAVE_ZLIB /* size_t read; */ int status; #endif /* HAVE_ZLIB */ if( OTF_FILEMODE_WRITE == file->mode ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "current file->mode is OTF_FILEMODE_WRITE. reading forbidden.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } if( 0 == OTF_File_revive( file, OTF_FILEMODE_READ ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_File_revive() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } #ifdef HAVE_ZLIB if ( NULL != file->z ) { file->z->next_out= ptr; file->z->avail_out= (uInt) size; while ( 0 < file->z->avail_out ) { if ( 0 == file->z->avail_in ) { file->z->avail_in= (uInt) fread( file->zbuffer, 1, file->zbuffersize, file->file ); file->z->next_in= file->zbuffer; } if ( 0 == file->z->avail_in ) { break; } status = inflate( file->z, Z_SYNC_FLUSH ); if ( status != Z_OK ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "error in uncompressing, status %u.\n", __FUNCTION__, __FILE__, __LINE__, status ); return 0; } } return size - file->z->avail_out; } else { return fread( ptr, 1, size, file->file ); } #else /* HAVE_ZLIB */ return fread( ptr, 1, size, file->file ); #endif /* HAVE_ZLIB */ }
size_t OTF_File_write( OTF_File* file, const void* ptr, size_t size ) { size_t byteswritten; #ifdef HAVE_ZLIB int len = 0; int rest = (int) size; int status; #endif/* HAVE_ZLIB */ if( OTF_FILEMODE_WRITE != file->mode ) { OTF_fprintf ( stderr, "ERROR in function %s, file: %s, line: %i:\n " "current file->mode is not OTF_FILEMODE_WRITE. writing forbidden.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } /* OTF_fprintf( stderr, "OTF_File_write: %u / %u file handles\n", OTF_FileManager_getCount( file->manager ), OTF_FileManager_getNumber( file->manager ) ); */ if( 0 == OTF_File_revive( file, OTF_FILEMODE_WRITE ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_File_revive() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } #ifdef HAVE_ZLIB if ( NULL != file->z ) { /* step 1 */ /* is any data in the y-buffer */ if ( 0 < file->z->avail_in ) { /* len of the piece to fill the y buffer (to 10Kbyte) */ len = file->zbuffersize - file->z->avail_in; /* is enough data in the "*ptr" to fill the ybuffer fully */ if ( len <= rest ) { memcpy( file->ybuffer + file->z->avail_in, ptr, len ); file->z->avail_in = file->zbuffersize; file->z->next_in = file->ybuffer; file->z->avail_out = file->zbuffersize; file->z->next_out = file->zbuffer; status = deflate( file->z, Z_FULL_FLUSH ); if ( status != Z_OK ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "error in compressing, status %u.\n", __FUNCTION__, __FILE__, __LINE__, status ); return 0; } byteswritten= fwrite( file->zbuffer, 1, file->zbuffersize - file->z->avail_out, file->file ); if( byteswritten < (file->zbuffersize - file->z->avail_out) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "less bytes written than expected %u < %u.\n", __FUNCTION__, __FILE__, __LINE__, (uint32_t) byteswritten, (uint32_t) (file->zbuffersize - file->z->avail_out) ); } /* test if avail_in really ran empty */ if ( 0 < file->z->avail_in ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "error in compressing.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } rest -= len; } else { /* no, it is not */ /* only copy the new data into the ybuffer */ memcpy( file->ybuffer + file->z->avail_in, ptr, rest ); file->z->avail_in += rest; rest = 0; } } /* step 2 */ /* if theres more than 10k in the "*ptr" */ while( (uint32_t) rest >= file->zbuffersize ) { file->z->avail_in = file->zbuffersize; file->z->next_in = ( ( ( unsigned char* ) ptr ) + len ); file->z->avail_out = file->zbuffersize; file->z->next_out = file->zbuffer; rest -= file->zbuffersize; len += file->zbuffersize; status = deflate( file->z, Z_FULL_FLUSH ); if ( status != Z_OK ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "error in compressing, status %u.\n", __FUNCTION__, __FILE__, __LINE__, status ); return 0; } byteswritten= fwrite( file->zbuffer, 1, file->zbuffersize - file->z->avail_out, file->file ); if( byteswritten < (file->zbuffersize - file->z->avail_out) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "less bytes written than expected %u < %u.\n", __FUNCTION__, __FILE__, __LINE__, (uint32_t) byteswritten, (uint32_t) (file->zbuffersize - file->z->avail_out) ); } /* test if avail_in really ran empty */ if ( 0 < file->z->avail_in ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "error in compressing.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } } /* step 3 */ /* is there less than 10k data left ... throw it into the ybuffer */ if ( rest > 0 ) { memcpy( file->ybuffer, ( ( unsigned char* ) ptr ) + len, rest ); file->z->avail_in = rest; } return size; } else { #endif /* HAVE_ZLIB */ /* OTF_fprintf( stderr, "OTF_File_write(): buffer %p, size %u file %p\n", ptr, (uint32_t) size, file->file ); */ byteswritten= fwrite( ptr, 1, size, file->file ); if( byteswritten < size ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "less bytes written than expected %u < %u.\n", __FUNCTION__, __FILE__, __LINE__, (uint32_t) byteswritten, (uint32_t) size ); } return byteswritten; #ifdef HAVE_ZLIB } #endif /* HAVE_ZLIB */ }
OTF_File* OTF_File_open_with_external_buffer( uint32_t len, const char* buffer, uint8_t is_compressed, OTF_FileMode mode ) { OTF_File* ret; ret= (OTF_File*) malloc( sizeof(OTF_File) ); if( NULL == ret ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "no memory left.\n", __FUNCTION__, __FILE__, __LINE__ ); return NULL; } OTF_File_init( ret ); ret->externalbuffer= buffer; ret->externalpos= 0; ret->externallen= (uint64_t) len; ret->mode = mode; if ( is_compressed ) { #ifdef HAVE_ZLIB /* alloc zlib stuff */ ret->z= malloc( sizeof(z_stream) ); if( NULL == ret->z ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "no memory left.\n", __FUNCTION__, __FILE__, __LINE__ ); free( ret ); ret= NULL; return NULL; } ret->z->next_in= NULL; ret->z->avail_in= 0; ret->z->zalloc= NULL; ret->z->zfree= NULL; ret->z->opaque= NULL; inflateInit( ret->z ); ret->zbuffer= malloc( ret->zbuffersize ); ret->ybuffer= malloc( ret->zbuffersize ); if( NULL == ret->zbuffer || NULL == ret->ybuffer) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "no memory left.\n", __FUNCTION__, __FILE__, __LINE__ ); free( ret->zbuffer ); free( ret->ybuffer ); ret->zbuffer= NULL; ret->ybuffer= NULL; free( ret->z ); ret->z= NULL; free( ret ); ret= NULL; return NULL; } #else /* HAVE_ZLIB */ free( ret ); ret= NULL; OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "built without HAVE_ZLIB, still trying to open with compressed buffer.\n", __FUNCTION__, __FILE__, __LINE__ ); return NULL; #endif /* HAVE_ZLIB */ } else { /* normal, don't need any special setup */ } ret->manager= NULL; return ret; }
OTF_File* OTF_File_open_zlevel( const char* filename, OTF_FileManager* manager, OTF_FileMode mode, OTF_FileCompression zlevel ) { uint32_t len; /* OTF_fprintf( stderr, "OTF_File_open_zlevel() zlevel: %u, filename: \"%s\"\n", zlevel, filename ); */ OTF_File* ret= (OTF_File*) malloc( sizeof(OTF_File) ); if( NULL == ret ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "no memory left.\n", __FUNCTION__, __FILE__, __LINE__ ); return NULL; } OTF_File_init( ret ); if( NULL == filename ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "no filename has been specified.\n", __FUNCTION__, __FILE__, __LINE__ ); free( ret ); ret= NULL; return NULL; } len= (uint32_t) strlen( filename ); ret->filename= malloc( len +3 ); if( NULL == ret->filename ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "no memory left.\n", __FUNCTION__, __FILE__, __LINE__ ); free( ret ); ret= NULL; return NULL; } strncpy( ret->filename, filename, len +1 ); ret->mode = mode; if ( OTF_FILEMODE_READ == mode || OTF_FILEMODE_SEEK == mode ) { #ifdef HAVE_ZLIB if ( 0 != access( ret->filename, F_OK ) ) { /* file not found, try '.z' suffix */ strncpy( ret->filename +len, ".z", 3 ); /* OTF_fprintf( stderr, "try '%s'\n", ret->filename ); */ if ( 0 != access( ret->filename, F_OK ) ) { /* file still not found, give up */ free( ret->filename ); ret->filename= NULL; free( ret ); ret= NULL; return ret; } ret->z= malloc( sizeof(z_stream) ); if( NULL == ret->z ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "no memory left.\n", __FUNCTION__, __FILE__, __LINE__ ); free( ret->filename ); ret->filename= NULL; free( ret ); ret= NULL; return NULL; } ret->z->next_in= NULL; ret->z->avail_in= 0; ret->z->zalloc= NULL; ret->z->zfree= NULL; ret->z->opaque= NULL; inflateInit( ret->z ); ret->zbuffer= malloc( ret->zbuffersize ); ret->ybuffer= malloc( ret->zbuffersize ); if( NULL == ret->zbuffer || NULL == ret->ybuffer) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "no memory left.\n", __FUNCTION__, __FILE__, __LINE__ ); free( ret->z ); ret->z= NULL; free( ret->filename ); ret->filename= NULL; free( ret ); ret= NULL; return NULL; } } #else /* HAVE_ZLIB */ if ( 0 != access( ret->filename, F_OK ) ) { /* file still not found, give up */ free( ret->filename ); ret->filename= NULL; free( ret ); ret= NULL; return ret; } #endif /* HAVE_ZLIB */ } else { /* filemode write */ #ifdef HAVE_ZLIB /* is a .z appended to the file name */ if ( len > 2 && 0 == strcmp( ret->filename + len - 2, ".z" ) ) { ret->z= malloc( sizeof(z_stream) ); if( NULL == ret->z ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "no memory left.\n", __FUNCTION__, __FILE__, __LINE__ ); free( ret->filename ); ret->filename= NULL; free( ret ); ret= NULL; return NULL; } ret->z->next_in= NULL; ret->z->avail_in= 0; ret->z->zalloc= NULL; ret->z->zfree= NULL; ret->z->opaque= NULL; deflateInit( ret->z, zlevel ); ret->zbuffer= malloc( ret->zbuffersize ); ret->ybuffer= malloc( ret->zbuffersize ); if( NULL == ret->zbuffer || NULL == ret->ybuffer ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "no memory left.\n", __FUNCTION__, __FILE__, __LINE__ ); free( ret->z ); ret->z= NULL; free( ret->filename ); ret->filename= NULL; free( ret ); ret= NULL; return NULL; } } #endif /* HAVE_ZLIB */ } if( NULL == manager ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "manager has not been specified.\n", __FUNCTION__, __FILE__, __LINE__ ); # ifdef HAVE_ZLIB free( ret->zbuffer ); ret->zbuffer= NULL; free( ret->ybuffer ); ret->ybuffer= NULL; free( ret->z ); ret->z= NULL; # endif /* HAVE_ZLIB */ free( ret->filename ); ret->filename= NULL; free( ret ); ret= NULL; return NULL; } ret->manager= manager; return ret; }
int OTF_File_revive( OTF_File* file, OTF_FileMode mode ) { if ( NULL != file->externalbuffer ) { /* no need to revive, everything is fine in 'external buffer' mode */ return 1; } switch ( mode ) { case OTF_FILEMODE_READ : /* *** read *** */ if ( NULL == file->file ) { /* file currently closed, aka open or reopen */ /* OTF_fprintf( stderr, "OTF_File_revive() READ: ask FileManager for free handle\n" ); */ if ( 0 == OTF_FileManager_guaranteeFile( file->manager ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_FileManager_guaranteeFile() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } /* open first time, as we open O_RDONLY plus O_NOATIME, which fopen doesn't know, use open/fdopen */ #ifdef _GNU_SOURCE { int fd; int retry_num = 5; int flags = O_RDONLY | O_NOATIME; while ( -1 == ( fd = open( file->filename, flags ) ) ) { /* if the user is not the owner of the file, open with O_NOATIME will fail with errno == EPERM; try to open without O_NOATIME again to avoid this problem */ if ( EPERM == errno ) { flags = O_RDONLY; continue; /* the file name might be stale, e.g. on Network File System (NFS) */ } else if ( ESTALE == errno && 0 < --retry_num ) { sleep(1); continue; } else { /* show this error every time */ OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "cannot open file %s for reading. Maybe the number of " "opened filehandles exceeds your system's limit\n", __FUNCTION__, __FILE__, __LINE__, file->filename ); return 0; } } file->file= fdopen( fd, "r" ); } #else /* _GNU_SOURCE */ file->file= fopen( file->filename, "rb" ); #endif /* _GNU_SOURCE */ if( NULL == file->file ) { /* show this error every time */ OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "cannot open file %s for reading. Maybe the number of " "opened filehandles exceeds your system's limit\n", __FUNCTION__, __FILE__, __LINE__, file->filename ); return 0; } /* Upon repoen, seek to the current position */ if ( 0 != file->pos ) { fseeko( file->file, file->pos, SEEK_SET ); } if ( 0 == OTF_FileManager_registerFile( file->manager, file ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_FileManager_registerFile() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } } else { /* file already opened */ /* OTF_fprintf( stderr, "OTF_File_revive() READ: update FileManagers LRU list\n" ); */ if ( 0 == OTF_FileManager_touchFile( file->manager, file ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_FileManager_touchFile() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } } return 1; case OTF_FILEMODE_WRITE : /* *** write *** */ if ( NULL == file->file ) { /* file currently closed */ /* OTF_fprintf( stderr, "OTF_File_revive() WRITE: ask FileManager for free handle\n" ); */ if ( 0 == OTF_FileManager_guaranteeFile( file->manager ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_FileManager_guaranteeFile() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } if ( 0 != file->pos ) { /* re-open */ file->file= fopen( file->filename, "ab" ); if( NULL == file->file ) { /* show this error every time */ OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "cannot open file %s for writing. Maybe the number of " "opened filehandles exceeds your system's limit\n", __FUNCTION__, __FILE__, __LINE__, file->filename ); return 0; } } else { /* open first time */ file->file= fopen( file->filename, "wb" ); if( NULL == file->file ) { /* show this error every time */ OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "cannot open file %s for writing. Maybe the number of " "opened filehandles exceeds your system's limit\n", __FUNCTION__, __FILE__, __LINE__, file->filename ); return 0; } } /* OTF_fprintf( stderr, "OTF_File_revive() WRITE: register opened file with FileManager\n" ); */ if ( 0 == OTF_FileManager_registerFile( file->manager, file ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_FileManager_registerFile() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } } else { /* file already opened */ /* OTF_fprintf( stderr, "OTF_File_revive() WRITE: update FileManagers LRU list\n" ); */ if ( 0 == OTF_FileManager_touchFile( file->manager, file ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_FileManager_touchFile() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } } return 1; case OTF_FILEMODE_SEEK : /* *** seek *** */ if ( NULL == file->file ) { /* file currently closed */ /* OTF_fprintf( stderr, "OTF_File_revive() READ: ask FileManager for free handle\n" ); */ if ( 0 == OTF_FileManager_guaranteeFile( file->manager ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_FileManager_guaranteeFile() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } if ( 0 != file->pos ) { /* re-open */ file->file= fopen( file->filename, "rb" ); if( NULL == file->file ) { /* show this error every time */ OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "cannot open file %s for reading. Maybe the number of " "opened filehandles exceeds your system's limit\n", __FUNCTION__, __FILE__, __LINE__, file->filename ); return 0; } /* dont need to seek to the saved position because there will be another seek anyway*/ /* fseeko( file->file, file->pos, SEEK_SET ); */ } else { /* open first time */ file->file= fopen( file->filename, "rb" ); if( NULL == file->file ) { /* show this error every time */ OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "cannot open file %s for reading. Maybe the number of " "opened filehandles exceeds your system's limit\n", __FUNCTION__, __FILE__, __LINE__, file->filename ); return 0; } } /* OTF_fprintf( stderr, "OTF_File_revive() SEEK: register opened file with FileManager\n" ); */ if ( 0 == OTF_FileManager_registerFile( file->manager, file ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_FileManager_registerFile() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } } else { /* file already opened */ /* OTF_fprintf( stderr, "OTF_File_revive() READ: update FileManagers LRU list\n" ); */ if ( 0 == OTF_FileManager_touchFile( file->manager, file ) ) { OTF_fprintf( stderr, "ERROR in function %s, file: %s, line: %i:\n " "OTF_FileManager_touchFile() failed.\n", __FUNCTION__, __FILE__, __LINE__ ); return 0; } } return 1; default: /* *** unknown mode *** */ return 0; } }