#include "SlaveIO.hh" #ifndef WIN32 #include #include #include #include #else #include #endif #include #include #include #include #ifdef T3E #include #endif #ifdef SGI #include #endif // Win32/Solaris lseek crap... #if defined(WIN32) || defined(SOLARIS) || defined(sun) #define L_INCR SEEK_CUR #ifndef L_SET // for that wanky Solaris compiler #define L_SET SEEK_SET #endif #define L_XTND SEEK_END #endif // T3E lseek crap... #ifdef T3E // I'm a T3E and I ignore ANSI/Posix standards #define L_INCR SEEK_CUR #define L_SET SEEK_SET #define L_XTND SEEK_END #endif SlaveIO::SlaveIO():fid(-1){} SlaveIO::SlaveIO(char *name){ fid = open(name,O_RDWR,0644); // should fail if file doesn't exist } SlaveIO::~SlaveIO(){ if(fid>=0) close(fid); fid=-1; // closed state } int SlaveIO::writeTo(void *data,Long8 len,Long8 offset){ lseek(fid,offset,L_SET); // seek from beginning of file return write(fid,data,len); } #ifdef SGI SGISlaveIO::SGISlaveIO(char *name):SlaveIO(name){} // use writepos elemental operation rather than separate lseek int SGISlaveIO::writeTo(void *data,Long8 len,Long8 offset){ return pwrite64(fid,data,len,offset); } AIOSlaveIO::AIOSlaveIO(char *name):SlaveIO(name),write_complete(0){ // init AIO (check global var for that) } AIOSlaveIO::~AIOSlaveIO(){ // flush file first (make sure it is flushed) if(fid>=0) close(fid); fid=-1; } int AIOSlaveIO::writeTo(void *data,Long8 len, Long8 offset){ return 1; } void AIOSlaveIO::sync(){ // do wait on the file operation } #endif // SGI #ifdef T3E FFSlaveIO::FFSlaveIO(char *name,char *optionstring){ struct ffsw ffopens_status; fid = ffopens(name,O_RDWR,0644,0, 0, &ffopens_status,optionstring); } FFSlaveIO::FFSlaveIO(char *name,int bufsize,int numbufs){ char optionstring[256]; int cblks; long cbits; struct statfs statfs_info; struct ffsw ffopens_status; sprintf(optionstring,"bufa.bufsize=%u.num_buffers=%u",bufsize,numbufs); fid = ffopens(name,O_RDWR,0644,0, 0, &ffopens_status,optionstring); ffwrite(fid,optionstring,255); // bogus write to testfile ffclose(name); // now close it statfs(name,&statfs_info,sizeof(statfs_info),0); cbits=0; cbits|=(1<<24); cbits|=(1<<06); cbits|=(1<<26); cbits|=(1<<23); cblks=100; fid = ffopens(name,O_WRONLY|O_PLACE,O_IWRITE|O_IREAD, cbits,cblks,&ffopens_status,LAYERS); // ? system("setf -n32768b:128b -c -p 24:06:23:26 bla"); // ? } FFSlaveIO::FFSlaveIO(char *name){ struct ffsw ffopens_status; fid = ffopens(name,O_RDWR,0644,0, 0, &ffopens_status, "bufa.bufsize=256.num_buffers=4"); } FFSlaveIO::~FFSlaveIO(){ if(fid>=0) ffclose(fid); fid=-1; // closed state } int FFSlaveIO::writeTo(void *data,Long8 len,Long8 offset){ ffseek(fid,offset,L_SET); // seek from beginning of file return ffwrite(fid,data,len); } #endif // T3E #ifdef SGI DirectSlaveIO::DirectSlaveIO(char *name):SlaveIO(name){ struct dioattr dio; dfid = open(name,O_WRONLY|O_DIRECT,0644); // unbuffered writes fcntl(dfid,F_DIOINFO,&dio); blocksize = dio.d_miniosz; maxiosize = dio.d_maxiosz; memoryalignment = dio.d_mem; diobuffersize=8*blocksize; diobuffer = (char*)memalign(memoryalignment,8*blocksize); } DirectSlaveIO::~DirectSlaveIO(){ if(fid>=0) close(fid); fid=-1; // closed state if(dfid>=0) close(dfid); dfid=-1; } int DirectSlaveIO::writeTo(void *vdata,Long8 len,Long8 offset){ char *data = (char *)vdata; Long8 startlen,midlen,endlen; Long8 startoffset,midoffset,endoffset; // compute starts based on blocksize startlen = offset % blocksize; // so now we have the start remainder endlen = (offset+len) % blocksize; // computed end-remainder midlen = len - (startlen+endlen); // compute offsets startoffset = offset; midoffset = startoffset + startlen; endoffset = midoffset + midlen; // should probably use aio for the end-writes pwrite64(fid,data,startlen,startoffset); // should use write // try this with AIO as well perhaps lseek(dfid,midoffset,L_SET); for(register int off=0;offmidlen)?midlen-off:diobuffersize; memcpy(diobuffer,data+off+startlen,sz); write(dfid,data+startlen,sz); // write direct and unbuffered } // now here we use the blockbuffer to manage writing of // the non-aligned portions of the data pwrite64(fid,data+startlen+midlen,endlen,endoffset); // block at the end if AIO } #endif // SGI