diff options
Diffstat (limited to 'src/SlaveIO.cc')
-rw-r--r-- | src/SlaveIO.cc | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/src/SlaveIO.cc b/src/SlaveIO.cc new file mode 100644 index 0000000..bb14b09 --- /dev/null +++ b/src/SlaveIO.cc @@ -0,0 +1,169 @@ +#include "SlaveIO.hh" +#ifndef WIN32 +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/file.h> +#else +#include <io.h> +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <string.h> + +#ifdef T3E +#include <ffio.h> +#endif + +#ifdef SGI +#include <aio.h> +#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;off<midlen;off+=diobuffersize){ + int sz=(diobuffersize+off>midlen)?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 |