mirror of
https://github.com/XTXMarkets/ternfs.git
synced 2026-01-06 11:00:10 -06:00
Span drop improvements
We could get into situations where async droppings were scheduled at every read.
This commit is contained in:
@@ -7,17 +7,27 @@
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
|
||||
#define die(fmt, ...) do { fprintf(stderr, fmt "\n" __VA_OPT__(,) __VA_ARGS__); exit(1); } while(false)
|
||||
|
||||
const char* exe = NULL;
|
||||
|
||||
#define badUsage(...) do { \
|
||||
fprintf(stderr, "Bad usage, expecting %s writefile <command arguments>\n", exe); \
|
||||
fprintf(stderr, "Bad usage, expecting %s writefile|readfile <command arguments>\n", exe); \
|
||||
__VA_OPT__(fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n");) \
|
||||
exit(2); \
|
||||
} while(0) \
|
||||
|
||||
static uint64_t nanosNow() {
|
||||
struct timespec tp;
|
||||
if (clock_gettime(CLOCK_REALTIME, &tp) < 0) {
|
||||
die("could not get time: %d (%s)", errno, strerror(errno));
|
||||
}
|
||||
return tp.tv_sec*1000000000ull + tp.tv_nsec;
|
||||
}
|
||||
|
||||
// Just a super dumb file test, to have a controlled environment
|
||||
// where every syscall is accounted for.
|
||||
static void writeFile(int argc, const char** argv) {
|
||||
@@ -59,12 +69,15 @@ static void writeFile(int argc, const char** argv) {
|
||||
die("could not allocate: %d (%s)", errno, strerror(errno));
|
||||
}
|
||||
|
||||
while (fileSize > 0) {
|
||||
ssize_t res = write(fd, buffer, fileSize > bufSize ? bufSize : fileSize);
|
||||
uint64_t start = nanosNow();
|
||||
|
||||
ssize_t toWrite = fileSize;
|
||||
while (toWrite > 0) {
|
||||
ssize_t res = write(fd, buffer, toWrite > bufSize ? bufSize : toWrite);
|
||||
if (res < 0) {
|
||||
die("couldn't write %s: %d (%s)", filename, errno, strerror(errno));
|
||||
}
|
||||
fileSize -= res;
|
||||
toWrite -= res;
|
||||
}
|
||||
|
||||
printf("finished writing, will now close\n");
|
||||
@@ -73,7 +86,74 @@ static void writeFile(int argc, const char** argv) {
|
||||
die("couldn't close %s: %d (%s)", filename, errno, strerror(errno));
|
||||
}
|
||||
|
||||
printf("done.\n");
|
||||
uint64_t elapsed = nanosNow() - start;
|
||||
printf("done (%fGB/s).\n", (double)fileSize/(double)elapsed);
|
||||
}
|
||||
|
||||
// Same as writeFile, but for reading.
|
||||
static void readFile(int argc, const char** argv) {
|
||||
ssize_t bufSize = -1; // if -1, all in one go
|
||||
const char* filename = NULL;
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (std::string(argv[i]) == "-buf-size") {
|
||||
if (i+1 >= argc) { badUsage("No argument after -buf-size"); } i++;
|
||||
bufSize = strtoull(argv[i], NULL, 0);
|
||||
if (bufSize == ULLONG_MAX) {
|
||||
badUsage("Bad -buf-size: %d (%s)", errno, strerror(errno));
|
||||
}
|
||||
} else {
|
||||
if (filename != NULL) { badUsage("Filename already specified: %s", filename); }
|
||||
filename = argv[i];
|
||||
}
|
||||
}
|
||||
|
||||
size_t fileSize;
|
||||
{
|
||||
struct stat st;
|
||||
if(stat(filename, &st) != 0) {
|
||||
die("couldn't stat %s: %d (%s)", filename, errno, strerror(errno));
|
||||
}
|
||||
fileSize = st.st_size;
|
||||
}
|
||||
|
||||
printf("reading %ld bytes with bufsize %ld to %s\n", fileSize, bufSize, filename);
|
||||
|
||||
int fd = open(filename, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
die("could not open file %s: %d (%s)", filename, errno, strerror(errno));
|
||||
}
|
||||
|
||||
uint8_t* buffer = (uint8_t*)malloc(bufSize);
|
||||
if (buffer == NULL) {
|
||||
die("could not allocate: %d (%s)", errno, strerror(errno));
|
||||
}
|
||||
|
||||
uint64_t start = nanosNow();
|
||||
|
||||
size_t readSize = 0;
|
||||
for (;;) {
|
||||
ssize_t ret = read(fd, buffer, bufSize);
|
||||
if (ret < 0) {
|
||||
die("could not read file %s: %d (%s)", filename, errno, strerror(errno));
|
||||
}
|
||||
if (ret == 0) { break; }
|
||||
readSize += ret;
|
||||
}
|
||||
|
||||
if (readSize != fileSize) {
|
||||
die("expected to read %lu (file size), but read %lu instead", fileSize, readSize);
|
||||
}
|
||||
|
||||
printf("finished reading, will now close\n");
|
||||
|
||||
if (close(fd) < 0) {
|
||||
die("couldn't close %s: %d (%s)", filename, errno, strerror(errno));
|
||||
}
|
||||
|
||||
uint64_t elapsed = nanosNow() - start;
|
||||
|
||||
printf("done (%fGB/s).\n", (double)fileSize/(double)elapsed);
|
||||
}
|
||||
|
||||
int main(int argc, const char** argv) {
|
||||
@@ -85,6 +165,8 @@ int main(int argc, const char** argv) {
|
||||
|
||||
if (cmd == "writefile") {
|
||||
writeFile(argc - 2, argv + 2);
|
||||
} else if (cmd == "readfile") {
|
||||
readFile(argc - 2, argv + 2);
|
||||
} else {
|
||||
badUsage("Bad command %s", cmd.c_str());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user