summaryrefslogtreecommitdiffstats
path: root/src/io.c
diff options
context:
space:
mode:
authorGravatar Gediminas Jakutis <gediminas@varciai.lt> 2021-02-11 08:17:03 +0200
committerGravatar Gediminas Jakutis <gediminas@varciai.lt> 2021-02-11 08:17:03 +0200
commit4a14ab7ab48e3fd591dde33d59c6d29fc39f1c5d (patch)
tree8d4e527e4a8ad76819e3baa1b89441eeb1081f15 /src/io.c
parent41efe7b8f9f67d5956ab677f3631478c48114ac1 (diff)
downloadalgos-ld1-4a14ab7ab48e3fd591dde33d59c6d29fc39f1c5d.tar.gz
algos-ld1-4a14ab7ab48e3fd591dde33d59c6d29fc39f1c5d.tar.bz2
algos-ld1-4a14ab7ab48e3fd591dde33d59c6d29fc39f1c5d.zip
continue the overhaul.
we can finally create a basic array input data file too! Signed-off-by: Gediminas Jakutis <gediminas@varciai.lt>
Diffstat (limited to 'src/io.c')
-rw-r--r--src/io.c108
1 files changed, 84 insertions, 24 deletions
diff --git a/src/io.c b/src/io.c
index d323573..41c5880 100644
--- a/src/io.c
+++ b/src/io.c
@@ -17,27 +17,37 @@
#include "datagen.h"
#include "cache.h"
-static int stream_open_out(struct stream * const in, const struct settings * const s);
-static int stream_open_out_lite(struct stream * const in, const struct settings * const s);
-static int stream_open_in(struct stream * const in, const struct settings * const s);
-static int stream_open_special(struct stream * const in);
-
-int stream_open(struct stream * const in, const struct settings * const s)
+static int stream_open_out(struct stream * const in);
+static int stream_open_out_lite(struct stream * const in);
+static int stream_open_in(struct stream * const in);
+static int stream_open_chardev(struct stream * const in);
+static int stream_flush(struct stream * const in);
+static int stream_flush_array(struct stream * const in);
+static int stream_flush_list(struct stream * const in);
+
+int stream_open(struct stream * const in)
{
int ret = 0;
- try(!in || in->fd > 0 || !in->name || !s, err, EINVAL, "invalid argunent");
+ try(!in || in->fd > 0 || !in->name, err, EINVAL, "invalid argunent");
- if (in->out == 2) {
- ret = stream_open_out_lite(in, s);
- } else if (in->out == 1) {
+ switch (in->type) {
+ case (stream_outlite):
+ ret = stream_open_out_lite(in);
+ break;
+ case (stream_out):
try(!in->name, err, EINVAL, "no filename given");
- ret = stream_open_out(in, s);
- } else if (!in->out) {
+ ret = stream_open_out(in);
+ break;
+ case (stream_in):
try(!in->name, err, EINVAL, "no filename given");
- ret = stream_open_in(in, s);
- } else {
- ret = stream_open_special(in);
+ ret = stream_open_in(in);
+ break;
+ case (stream_chardev):
+ ret = stream_open_chardev(in);
+ break;
+ default:
+ try(0, err, EINVAL, "cannot open stream: stream is invalid");
}
err:
@@ -50,7 +60,7 @@ int stream_close(struct stream * const in)
try(!in || in->fd < 0, early_err, EINVAL, "invalid argunent");
- if (in->out != 1) {
+ if (in->type != stream_out) {
goto out;
}
@@ -58,6 +68,8 @@ int stream_close(struct stream * const in)
char path[PATH_MAX];
struct stat st;
+ try_s((ret = stream_flush(in)), err);
+
snprintf(path, PATH_MAX, "/proc/self/fd/%i", in->fd);
if (!stat(in->name, &st)) {
@@ -85,7 +97,7 @@ early_err:
return ret;
}
-static int stream_open_out(struct stream * const in, const struct settings * const s)
+static int stream_open_out(struct stream * const in)
{
struct stat st;
mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP;
@@ -108,14 +120,14 @@ static int stream_open_out(struct stream * const in, const struct settings * con
in->fd = open(dname, O_TMPFILE | O_RDWR, mode);
try(in->fd < 0, err, errno, "failed creating temporary output file: %s", strerror(ret));
- try(ftruncate(in->fd, s->stride * in->n), err, errno, "failed setting output file size: %s", strerror(ret));
+ try(ftruncate(in->fd, in->settings->stride * in->n), err, errno, "failed setting output file size: %s", strerror(ret));
err:
free(dname);
return ret;
}
-static int stream_open_out_lite(struct stream * const in, const struct settings * const s)
+static int stream_open_out_lite(struct stream * const in)
{
struct stat st;
char *dname = NULL;
@@ -132,21 +144,21 @@ static int stream_open_out_lite(struct stream * const in, const struct settings
in->fd = open(dname, O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);
try(in->fd < 0, err, errno, "failed creating temporary output file: %s", strerror(ret));
- try(ftruncate(in->fd, s->stride * in->n), err, errno, "failed setting output file size: %s", strerror(ret));
+ try(ftruncate(in->fd, in->settings->stride * in->n), err, errno, "failed setting output file size: %s", strerror(ret));
err:
free(dname);
return ret;
}
-static int stream_open_in(struct stream * const in, const struct settings * const s)
+static int stream_open_in(struct stream * const in)
{
struct stat st;
int ret = 0;
try(stat(in->name, &st), err, errno, "stat failed: %s", strerror(ret));
- try(!(st.st_mode & S_IFREG) || !st.st_size || (st.st_size % s->stride), err, EINVAL, "invalid input file");
- in->n = st.st_size / s->stride;
+ try(!(st.st_mode & S_IFREG) || !st.st_size || (st.st_size % in->settings->stride), err, EINVAL, "invalid input file");
+ in->n = st.st_size / in->settings->stride;
in->fd = open(in->name, O_RDONLY | O_NOATIME);
try(in->fd < 0, err, errno, "failed opening input file: %s", strerror(ret));
@@ -154,7 +166,7 @@ err:
return ret;
}
-static int stream_open_special(struct stream * const in)
+static int stream_open_chardev(struct stream * const in)
{
struct stat st;
int ret = 0;
@@ -166,3 +178,51 @@ static int stream_open_special(struct stream * const in)
err:
return ret;
}
+
+int stream_flush(struct stream * const in)
+{
+ int ret = 0;
+
+ try(in->settings->access != cached, err, EINVAL, "cannot flush an uncached stream");
+ try(in->type != stream_out, err, EINVAL, "cannot flush a non-output cache");
+
+ if (in->settings->format == array) {
+ ret = stream_flush_array(in);
+ } else {
+ ret = stream_flush_list(in);
+ }
+err:
+ return ret;
+}
+
+int stream_flush_array(struct stream * const in)
+{
+ ssize_t ret = 0;
+ size_t remaining = in->n * in->settings->stride;
+ ssize_t written = 0;
+
+ do {
+ ret = write(in->fd, in->cache + written, remaining);
+ if (ret < 0) {
+ try(errno != EAGAIN, err, errno, "Writing to stream failed with %zi", ret);
+ } else {
+ written += ret;
+ remaining -= ret;
+ ret = 0;
+ }
+ } while (remaining);
+
+err:
+ return ret;
+}
+
+int stream_flush_list(struct stream * const in)
+{
+ int ret = ENOSYS;
+
+ (void) in;
+
+ rin_warn("stub!");
+
+ return ret;
+}