aboutsummaryrefslogtreecommitdiff
path: root/src/SlaveIO.cc
blob: bb14b0928a7682737b78ef809ea17630db05016b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
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