Skip to content

Commit b2dcf17

Browse files
committed
Storage 3 lecture code
1 parent 0e1a9d1 commit b2dcf17

12 files changed

+367
-0
lines changed

storage3/.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
noncommutative
2+
[rw][0-9]*sector
3+
[rw][0-9]*byte
4+
[rw][0-9]*block
5+
data

storage3/GNUmakefile

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
PROGRAMS = noncommutative $(sort $(patsubst %.c,%,$(wildcard r[0-9]*.c)))
2+
all: $(PROGRAMS) data
3+
4+
include ../common/rules.mk
5+
6+
%.o: %.c $(BUILDSTAMP)
7+
$(CC) $(CPPFLAGS) $(CFLAGS) $(DEPCFLAGS) $(O) -o $@ -c $<
8+
9+
noncommutative: noncommutative.o
10+
$(CC) $(CFLAGS) $(O) -o $@ $^ -lm
11+
12+
r%: r%.o
13+
$(CC) $(CFLAGS) $(O) -o $@ $^
14+
15+
data:
16+
yes 77777777777777777777777777777777777777777 | tr -d '\n' | head -c 51200000 > data
17+
18+
clean:
19+
rm -f *.o $(PROGRAMS) data
20+
rm -rf $(DEPSDIR) *.dSYM
21+
22+
.PHONY: all clean

storage3/iobench.h

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#ifndef IOBENCH_H
2+
#define IOBENCH_H
3+
4+
#define _GNU_SOURCE 1
5+
#include <unistd.h>
6+
#include <sys/types.h>
7+
#include <sys/stat.h>
8+
#include <fcntl.h>
9+
#include <stdio.h>
10+
#include <stdlib.h>
11+
#include <assert.h>
12+
#include <string.h>
13+
#include <limits.h>
14+
#include <sys/time.h>
15+
16+
static inline double tstamp(void) {
17+
struct timeval tv;
18+
gettimeofday(&tv, 0);
19+
return tv.tv_sec + tv.tv_usec / 1000000.;
20+
}
21+
22+
// Print a report to stderr of # bytes printed, elapsed time, and rate.
23+
static inline void report(size_t n, double elapsed) {
24+
fprintf(stderr, "\r%zd bytes %.3f sec %g byte/sec ",
25+
n, elapsed, n / elapsed);
26+
}
27+
28+
// Return the size of a file.
29+
static inline ssize_t filesize(int fd) {
30+
struct stat s;
31+
int r = fstat(fd, &s);
32+
if (r >= 0 && S_ISREG(s.st_mode) && s.st_size <= SSIZE_MAX)
33+
return s.st_size;
34+
else
35+
return -1;
36+
}
37+
38+
#ifndef PRINT_FREQUENCY
39+
#define PRINT_FREQUENCY 4096
40+
#endif
41+
42+
#endif

storage3/noncommutative.c

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include <stdio.h>
2+
3+
int main() {
4+
double answer = 0;
5+
6+
answer += 100000000000;
7+
for (int i = 0; i < 100000; ++i)
8+
answer += 0.01;
9+
10+
printf("%.12g (%a)\n", answer, answer);
11+
}

storage3/r01-directsector.c

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include "iobench.h"
2+
3+
int main() {
4+
#ifndef O_DIRECT
5+
fprintf(stderr, "ERROR: O_DIRECT not supported here\n");
6+
# define O_DIRECT 0
7+
#endif
8+
#ifndef O_DSYNC
9+
# define O_DSYNC 0
10+
#endif
11+
12+
int fd = STDIN_FILENO;
13+
if (isatty(fd))
14+
fd = open("data", O_RDONLY | O_DIRECT | O_DSYNC);
15+
if (fd < 0) {
16+
perror("open");
17+
exit(1);
18+
}
19+
20+
size_t size = filesize(fd);
21+
size_t block_size = 512;
22+
char* buf;
23+
posix_memalign((void **) &buf, 512, block_size);
24+
double start = tstamp();
25+
26+
size_t n = 0;
27+
while (n < size) {
28+
ssize_t r = read(fd, buf, block_size);
29+
if (r == -1) {
30+
perror("read");
31+
exit(1);
32+
} else if (r != (ssize_t) block_size)
33+
break;
34+
n += r;
35+
if (n % PRINT_FREQUENCY == 0)
36+
report(n, tstamp() - start);
37+
}
38+
39+
close(fd);
40+
report(n, tstamp() - start);
41+
fprintf(stderr, "\n");
42+
}

storage3/r02-sector.c

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include "iobench.h"
2+
3+
int main() {
4+
int fd = STDIN_FILENO;
5+
if (isatty(fd))
6+
fd = open("data", O_RDONLY);
7+
if (fd < 0) {
8+
perror("open");
9+
exit(1);
10+
}
11+
12+
size_t size = filesize(fd);
13+
char* buf = (char*) malloc(512);
14+
double start = tstamp();
15+
16+
size_t n = 0;
17+
while (n < size) {
18+
ssize_t r = read(fd, buf, 512);
19+
if (r == -1) {
20+
perror("read");
21+
exit(1);
22+
} else if (r != 512)
23+
break;
24+
n += r;
25+
if (n % PRINT_FREQUENCY == 0)
26+
report(n, tstamp() - start);
27+
}
28+
29+
close(fd);
30+
report(n, tstamp() - start);
31+
fprintf(stderr, "\n");
32+
}

storage3/r03-byte.c

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include "iobench.h"
2+
3+
int main() {
4+
int fd = STDIN_FILENO;
5+
if (isatty(fd))
6+
fd = open("data", O_RDONLY);
7+
if (fd < 0) {
8+
perror("open");
9+
exit(1);
10+
}
11+
12+
size_t size = filesize(fd);
13+
char* buf = (char*) malloc(1);
14+
double start = tstamp();
15+
16+
size_t n = 0;
17+
while (n < size) {
18+
ssize_t r = read(fd, buf, 1);
19+
if (r == -1) {
20+
perror("read");
21+
exit(1);
22+
} else if (r != 1)
23+
break;
24+
n += r;
25+
if (n % PRINT_FREQUENCY == 0)
26+
report(n, tstamp() - start);
27+
}
28+
29+
close(fd);
30+
report(n, tstamp() - start);
31+
fprintf(stderr, "\n");
32+
}

storage3/r04-stdiobyte.c

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include "iobench.h"
2+
3+
int main() {
4+
FILE* f = stdin;
5+
if (isatty(fileno(f)))
6+
f = fopen("data", "r");
7+
if (!f) {
8+
perror("fopen");
9+
exit(1);
10+
}
11+
12+
size_t size = filesize(fileno(f));
13+
double start = tstamp();
14+
15+
size_t n = 0;
16+
while (n < size) {
17+
int ch = fgetc(f);
18+
if (ch == EOF && ferror(f)) {
19+
perror("fgetc");
20+
exit(1);
21+
} else if (ch == EOF)
22+
break;
23+
n += 1;
24+
if (n % PRINT_FREQUENCY == 0)
25+
report(n, tstamp() - start);
26+
}
27+
28+
fclose(f);
29+
report(n, tstamp() - start);
30+
fprintf(stderr, "\n");
31+
}

storage3/r05-revbyte.c

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include "iobench.h"
2+
3+
int main() {
4+
int fd = STDIN_FILENO;
5+
if (isatty(fd))
6+
fd = open("data", O_RDONLY);
7+
if (fd < 0) {
8+
perror("open");
9+
exit(1);
10+
}
11+
12+
size_t size = filesize(fd);
13+
char* buf = (char*) malloc(1);
14+
double start = tstamp();
15+
16+
off_t pos = size;
17+
size_t n = 0;
18+
while (pos > 0) {
19+
pos -= 1;
20+
if (lseek(fd, pos, SEEK_SET) == (off_t) -1) {
21+
perror("lseek");
22+
exit(1);
23+
}
24+
ssize_t r = read(fd, buf, 1);
25+
if (r == -1) {
26+
perror("read");
27+
exit(1);
28+
} else if (r != 1)
29+
break;
30+
n += r;
31+
if (n % PRINT_FREQUENCY == 0)
32+
report(n, tstamp() - start);
33+
}
34+
35+
close(fd);
36+
report(n, tstamp() - start);
37+
fprintf(stderr, "\n");
38+
}

storage3/r06-stdiorevbyte.c

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include "iobench.h"
2+
3+
int main() {
4+
FILE* f = stdin;
5+
if (isatty(fileno(f)))
6+
f = fopen("data", "r");
7+
if (!f) {
8+
perror("fopen");
9+
exit(1);
10+
}
11+
12+
size_t size = filesize(fileno(f));
13+
double start = tstamp();
14+
15+
off_t pos = size;
16+
size_t n = 0;
17+
while (pos > 0) {
18+
pos -= 1;
19+
if (fseek(f, pos, SEEK_SET) == -1) {
20+
perror("fseek");
21+
exit(1);
22+
}
23+
int ch = fgetc(f);
24+
if (ch == EOF && ferror(f)) {
25+
perror("fgetc");
26+
exit(1);
27+
} else if (ch == EOF)
28+
break;
29+
n += 1;
30+
if (n % PRINT_FREQUENCY == 0)
31+
report(n, tstamp() - start);
32+
}
33+
34+
fclose(f);
35+
report(n, tstamp() - start);
36+
fprintf(stderr, "\n");
37+
}

storage3/r07-stridebyte.c

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include "iobench.h"
2+
3+
int main() {
4+
int fd = STDIN_FILENO;
5+
if (isatty(fd))
6+
fd = open("data", O_RDONLY);
7+
if (fd < 0) {
8+
perror("open");
9+
exit(1);
10+
}
11+
12+
size_t size = filesize(fd);
13+
size_t stride = size / 100;
14+
char* buf = (char*) malloc(1);
15+
double start = tstamp();
16+
17+
size_t n = 0, pos = 0;
18+
while (n < size) {
19+
ssize_t r = read(fd, buf, 1);
20+
if (r == -1) {
21+
perror("read");
22+
exit(1);
23+
} else if (r != 1)
24+
break;
25+
n += r;
26+
if (n % PRINT_FREQUENCY == 0)
27+
report(n, tstamp() - start);
28+
29+
pos += stride;
30+
if (pos >= size)
31+
pos = (pos - size) + 1;
32+
lseek(fd, pos, SEEK_SET);
33+
}
34+
35+
close(fd);
36+
report(n, tstamp() - start);
37+
fprintf(stderr, "\n");
38+
}

storage3/r08-stdiostridebyte.c

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include "iobench.h"
2+
3+
int main() {
4+
FILE* f = stdin;
5+
if (isatty(fileno(f)))
6+
f = fopen("data", "r");
7+
if (!f) {
8+
perror("fopen");
9+
exit(1);
10+
}
11+
12+
size_t size = filesize(fileno(f));
13+
size_t stride = size / 100;
14+
double start = tstamp();
15+
16+
size_t n = 0, pos = 0;
17+
while (n < size) {
18+
int ch = fgetc(f);
19+
if (ch == EOF && ferror(f)) {
20+
perror("fgetc");
21+
exit(1);
22+
} else if (ch == EOF)
23+
break;
24+
n += 1;
25+
if (n % PRINT_FREQUENCY == 0)
26+
report(n, tstamp() - start);
27+
28+
pos += stride;
29+
if (pos >= size)
30+
pos = (pos - size) + 1;
31+
fseek(f, pos, SEEK_SET);
32+
}
33+
34+
fclose(f);
35+
report(n, tstamp() - start);
36+
fprintf(stderr, "\n");
37+
}

0 commit comments

Comments
 (0)