aboutsummaryrefslogtreecommitdiff
path: root/src/SlaveIO.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/SlaveIO.cc')
-rw-r--r--src/SlaveIO.cc169
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