diff options
Diffstat (limited to 'semestr-5/so/lista6')
-rw-r--r-- | semestr-5/so/lista6/so21_lista_6/Makefile.include | 105 | ||||
-rw-r--r-- | semestr-5/so/lista6/so21_lista_6/writeperf.c | 88 | ||||
-rwxr-xr-x | semestr-5/so/lista6/so21_lista_6/writeperf.sh | 17 |
3 files changed, 210 insertions, 0 deletions
diff --git a/semestr-5/so/lista6/so21_lista_6/Makefile.include b/semestr-5/so/lista6/so21_lista_6/Makefile.include new file mode 100644 index 0000000..196c9a5 --- /dev/null +++ b/semestr-5/so/lista6/so21_lista_6/Makefile.include @@ -0,0 +1,105 @@ +CC = gcc -g +CFLAGS = -Og -Wall -Werror -Wstrict-prototypes +AS = as -g +ASFLAGS = +CPPFLAGS = -Iinclude +LDLIBS = -Llibcsapp -lcsapp +SED = sed + +# Recognize operating system +ifeq ($(shell uname -s), Darwin) +CPPFLAGS += -DMACOS +SED = gsed +endif + +ifeq ($(shell uname -s), Linux) +CPPFLAGS += -DLINUX +endif + +ifeq ($(shell uname -s), FreeBSD) +CPPFLAGS += -DFREEBSD +endif + +# Pass "VERBOSE=1" at command line to display command being invoked by GNU Make +ifneq ($(VERBOSE), 1) +.SILENT: +endif + +LIBSRC_C = $(wildcard libcsapp/*.c) +LIBSRC_S = $(wildcard libcsapp/*.s) +LIBSRC_H = $(wildcard include/*.h) +LIBSRCS = $(LIBSRC_C) $(LIBSRC_S) $(LIBSRC_H) +LIBOBJS = $(LIBSRC_C:%.c=%.o) +ifneq ($(shell uname -s), Darwin) +LIBOBJS += $(LIBSRC_S:%.s=%.o) +endif +LIB = libcsapp/libcsapp.a + +SRC_C = $(wildcard *.c) +SRC_S = $(wildcard *.s) +SRC_H = $(wildcard *.h) +SRCS = $(SRC_C) $(SRC_S) +OBJS = $(SRC_C:%.c=%.o) + +SOURCES = $(SRCS) $(LIBSRCS) +OBJECTS = $(OBJS) $(LIBOBJS) +DEPFILES = $(foreach f,$(SRC_C) $(LIBSRC_C),\ + $(dir $(f))$(patsubst %.c,.%.d,$(notdir $(f)))) + +ARCHIVE = so$(shell date +'%y')_$(shell basename $(PWD)) +FILES = Makefile Makefile.include $(EXTRA-FILES) + +all: $(DEPFILES) $(LIB) $(PROGS) + +$(LIB): $(LIBOBJS) + +# Generate dependencies automatically +ifeq ($(words $(findstring $(MAKECMDGOALS), archive clean)), 0) + -include $(DEPFILES) +endif + +# Disable all built-in recipes and define our own +.SUFFIXES: + +.%.d: %.c + $(CC) $(CPPFLAGS) -MM -MG -o $@ $< + +%.o: %.c .%.d + @echo "[CC] $@ <- $<" + $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $< + +%.o: %.s + @echo "[AS] $@ <- $<" + $(AS) $(ASFLAGS) -c -o $@ $< + +%.a: + @echo "[AR] $@ <- $^" + $(AR) rc $@ $^ + +%: %.o $(LIB) + @echo "[LD] $@ <- $^" + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) + +clean: + rm -vf $(PROGS) $(OBJECTS) $(DEPFILES) $(LIB) + rm -vf $(shell find -L . -iname '*~') + rm -vf $(ARCHIVE).tar.gz + rm -vrf $(EXTRA-CLEAN) *.dSYM + +format: + clang-format --style=file -i $(LIBSRC_C) $(LIBSRC_H) $(SRC_C) $(SRC_H) + +archive: clean + mkdir -p $(ARCHIVE) $(ARCHIVE)/libcsapp $(ARCHIVE)/include + cp -L $(SRCS) $(SRC_H) $(FILES) $(ARCHIVE)/ + cp -L $(LIBSRCS) $(ARCHIVE)/libcsapp/ + cp -L $(LIBSRC_H) $(ARCHIVE)/include/ + for f in $(SRCS:%=$(ARCHIVE)/%); do \ + $(SED) --in-place='' -e '/^#if.*STUDENT/,/^#endif.*STUDENT/d' $$f; \ + done + tar cvzhf $(ARCHIVE).tar.gz $(ARCHIVE) + rm -rf $(ARCHIVE) + +.PHONY: all clean format archive + +# vim: ts=8 sw=8 noet diff --git a/semestr-5/so/lista6/so21_lista_6/writeperf.c b/semestr-5/so/lista6/so21_lista_6/writeperf.c new file mode 100644 index 0000000..b397188 --- /dev/null +++ b/semestr-5/so/lista6/so21_lista_6/writeperf.c @@ -0,0 +1,88 @@ +#include "csapp.h" + +static noreturn void usage(int argc, char *argv[]) { + fprintf(stderr, "Usage: %s [-t times] [-l length] -s " + "[write|fwrite|fwrite-line|fwrite-full|writev]\n", argv[0]); + exit(EXIT_FAILURE); +} + +int main(int argc, char *argv[]) { + int length = -1, times = -1; + bool dosync = false; + int opt; + + while ((opt = getopt(argc, argv, "l:t:s")) != -1) { + if (opt == 'l') + length = atoi(optarg); + else if (opt == 't') + times = atoi(optarg); + else if (opt == 's') + dosync = true; + else + usage(argc, argv); + } + + if (optind >= argc || length <= 0 || times <= 0) + usage(argc, argv); + + char *choice = argv[optind]; + + char *line = malloc(length + 1); + memset(line, '*', length); + line[length] = '\n'; + + if (strcmp(choice, "write") == 0) { + for (int j = 0; j < times; j++) + for (int k = 0; k < length; k++) + write(STDOUT_FILENO, line + k, length + 1 - k); + } + + if (strncmp(choice, "fwrite", 6) == 0) { + size_t size; + int mode; + void *buf; + + if (strcmp(choice, "fwrite-line") == 0) { + mode = _IOLBF; + size = length + 1; + } else if (strcmp(choice, "fwrite-full") == 0) { + mode = _IOFBF; + size = getpagesize(); + } else { + mode = _IONBF; + size = 0; + } + + buf = malloc(size + 1); + /* TODO: Attach new buffer to stdout stream. */ + setvbuf(stdout, buf, mode, size); + + for (int j = 0; j < times; j++) + for (int k = 0; k < length; k++) + fwrite(line + k, length + 1 - k, 1, stdout); + fflush(stdout); + + free(buf); + } + + + if (strcmp(choice, "writev") == 0) { + int n = sysconf(_SC_IOV_MAX); + struct iovec iov[n]; + /* TODO: Write file by filling in iov array and issuing writev. */ + for (int k = 0; k < length; k++) { + iov[k].iov_base = line + k; + iov[k].iov_len = length + 1 - k; + } + for (int j = 0; j < times; j++) + Writev(1, iov, length); + } + + + free(line); + + if (dosync && !isatty(STDOUT_FILENO)) + fsync(STDOUT_FILENO); + + return 0; +} diff --git a/semestr-5/so/lista6/so21_lista_6/writeperf.sh b/semestr-5/so/lista6/so21_lista_6/writeperf.sh new file mode 100755 index 0000000..55f34ae --- /dev/null +++ b/semestr-5/so/lista6/so21_lista_6/writeperf.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +OPTS="-l 1000 -t 1000" + +runtest() { + echo "Method: $1" + time ./writeperf $OPTS $1 > test + md5sum test + rm test + echo "" +} + +runtest write +runtest fwrite +runtest fwrite-line +runtest fwrite-full +runtest writev |