-
Notifications
You must be signed in to change notification settings - Fork 0
/
sync.c
248 lines (214 loc) · 7.99 KB
/
sync.c
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/uio.h>
#include <errno.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include "sync.h"
#define __USE_GNU 1
#include <fcntl.h>
int io_file_reset_pos(IOFile * io_file){
lseek(io_file->fd, 0, SEEK_SET);
io_file->current_position = 0;
return 0;
}
int io_file_set_pos(IOFile * io_file, off_t offset){
lseek(io_file->fd, offset, SEEK_SET);
io_file->current_position = offset;
return 0;
}
int io_file_get_size(IOFile * io_file){
struct stat stats;
fstat(io_file->fd, &stats);
return (int)stats.st_size;
}
int delete_io_file(IOFile * io_file){
close(io_file->fd);
free(io_file->lba_history);
free(io_file->bs_history);
free(io_file);
return 1;
}
int io_file_print_stats(IOFile * io_file, long int time_seconds){
printf("writes: %llu \n", io_file->writes);
printf("MB per second: %d \n", io_file->writes/ 1024 / 1024 / time_seconds);
printf("reads: %llu \n", io_file->reads);
printf("MB per second: %d \n", io_file->reads/ 1024 / 1024 / time_seconds);
printf("IO_LOG:\n");
for (int i = 0; i < io_file->history_size; i++){
printf("LBA: %llu \n", io_file->lba_history[i]);
printf("BS: %llu \n", io_file->bs_history[i]);
}
}
int read_file(IOFile * io_file, off_t block_size, off_t offset){
if (offset != 0) io_file_set_pos(io_file, offset);
int * buffer = (int *) malloc(sizeof(int) * block_size);
int bytes_read = read(io_file->fd, buffer, block_size);
if(bytes_read == -1){
perror("read error: ");
}
io_file->lba_history[io_file->history_size - 1] = io_file->current_position;
io_file->bs_history[io_file->history_size - 1] = bytes_read;
io_file->current_position += bytes_read;
io_file->reads += bytes_read;
io_file->history_size = io_file->history_size + 1;
io_file->lba_history = (unsigned long long *) realloc(io_file->lba_history, sizeof(unsigned long long int) * io_file->history_size);
io_file->bs_history = (unsigned long long *) realloc(io_file->bs_history, sizeof(unsigned long long int) * io_file->history_size);
free(buffer);
return bytes_read;
}
int write_file(IOFile * io_file, off_t block_size, off_t offset){
if (offset != 0) io_file_set_pos(io_file, offset);
int * buffer = (int *) malloc(sizeof(int) * block_size);
for( int i = 0; i < block_size; i++){
buffer[i] = rand();
}
int bytes_written = write(io_file->fd, buffer, block_size);
if(bytes_written == -1){
perror("write error: ");
}
io_file->lba_history[io_file->history_size - 1] = io_file->current_position;
io_file->bs_history[io_file->history_size - 1] = bytes_written;
io_file->current_position += bytes_written;
io_file->writes += bytes_written;
io_file->history_size = io_file->history_size + 1;
io_file->lba_history = (unsigned long long *) realloc(io_file->lba_history, sizeof(unsigned long long int) * io_file->history_size);
io_file->bs_history = (unsigned long long *) realloc(io_file->bs_history, sizeof(unsigned long long int) * io_file->history_size);
free(buffer);
return bytes_written;
}
IOFile * io_file(const char * file_name, int direct, off_t size){
int open_flags = O_RDWR | O_CREAT;
if(direct) open_flags = open_flags | O_DIRECT;
int file_desc = open(file_name, open_flags, S_IRWXU | S_IRWXG | S_IRWXO);
if (file_desc == -1){
perror("could not open file: ");
}
unsigned long long int * lba_history = (unsigned long long int *) malloc(sizeof(unsigned long long int));
unsigned long long int * bs_history = (unsigned long long int *) malloc(sizeof(unsigned long long int));
IOFile * io_file_object = (IOFile*) malloc(sizeof(IOFile));
* io_file_object = (IOFile){file_desc, 0, 0, 0, direct, lba_history, bs_history, 1, size};
return io_file_object;
}
int write_worker(IOFile * io_file, long int time_seconds){
time_t c_time = time(NULL);
long int int_time_start = (long int) c_time;
long int int_current_time = int_time_start;
printf("starting time: %ld\n", c_time);
printf("timestamp: %ld\n", int_current_time);
printf("diff: %ld\n", int_current_time - int_time_start);
while((int_current_time - int_time_start) < time_seconds){
if (io_file->current_position >= io_file_get_size(io_file)){
io_file_reset_pos(io_file);
}
write_file(io_file, 1024, 0);
int_current_time = (long int) time(NULL);
}
return 1;
}
int read_worker(IOFile * io_file, long int time_seconds){
time_t c_time = time(NULL);
long int int_time_start = (long int) c_time;
long int int_current_time = int_time_start;
printf("starting time: %ld\n", c_time);
printf("timestamp: %ld\n", int_current_time);
printf("diff: %ld\n", int_current_time - int_time_start);
while((int_current_time - int_time_start) < time_seconds){
if (io_file->current_position >= io_file_get_size(io_file)){
io_file_reset_pos(io_file);
}
read_file(io_file, 1024, 0);
int_current_time = (long int) time(NULL);
}
return 1;
}
//typedef struct workload {
// int bs;
// int time_based;
// int time;
// int size;
// int rw;
//} Workload;
//
//typedef struct worker {
// IOFile * io_file;
// Workload * workload;
//} worker;
Workload* workload(off_t bs, int time_based, long int time, off_t size, int rw, off_t offset, int sequential){
Workload * workload = (Workload*) malloc(sizeof(Workload));
workload->bs = bs;
workload->time_based = time_based;
workload->time = time;
workload->size = size;
workload->rw = rw;
workload->offset = offset;
workload->sequential = sequential;
return workload;
}
Worker* worker(IOFile * io_file, Workload * workload, IOEngine * io_engine){
Worker * worker = (Worker*) malloc(sizeof(Worker));
worker->io_file = io_file;
worker->workload = workload;
worker->io_engine = io_engine;
return worker;
}
int worker_run(Worker * worker){
time_t c_time = time(NULL);
long int int_time_start = (long int) c_time;
long int int_current_time = int_time_start;
off_t offset = worker->workload->offset;
printf("starting time: %ld\n", c_time);
printf("timestamp: %ld\n", int_current_time);
printf("diff: %ld\n", int_current_time - int_time_start);
//if worker->workload->sequential:
while((int_current_time - int_time_start) < worker->workload->time){
if(worker->workload->sequential == 0) offset = (off_t)rand() % worker->io_file->size - worker->workload->bs;
if (worker->io_file->current_position + worker->workload->bs >= worker->workload->size){
io_file_reset_pos(worker->io_file);
}
if(worker->workload->rw == 0) {
worker->io_engine->read_file(worker->io_file, worker->workload->bs, offset);
} else if (worker->workload->rw == 1){
worker->io_engine->write_file(worker->io_file, worker->workload->bs, offset);
} else {
printf("invalid operation type: %d\n", worker->workload->rw);
}
int_current_time = (long int) time(NULL);
}
return 1;
}
//define the io engines here
static IOEngine sync_engine = {
.write_file = write_file,
.read_file = read_file
};
int main(int argc, char * argv[]){
//who cares
srand(1);
int opt;
long int runtime = 3;
char filename[128];
strcpy(filename, "filename");
while(( opt = getopt(argc, argv, "t:f:")) != -1 ){
switch(opt) {
case 't':
runtime = (long int) atoi(optarg);
break;
case 'f':
strcpy(filename, optarg);
break;
default:
printf("Invalid parameter");
exit(EXIT_FAILURE);
}
}
IOFile * test_file = io_file(filename, 1, 1000000);
Workload * test_workload = workload(1024, 1, runtime, 1000000, 1, 0, 0);
Worker * test_worker = worker(test_file, test_workload, &sync_engine);
worker_run(test_worker);
io_file_print_stats(test_file, runtime);
delete_io_file(test_file);
}