b’lab4.tar.gz’
#!/bin/bash
if [ “$#” -ne 1 ]; then
echo “You should provide your zip file as a parameter and nothing else!”
exit 1
fi
if ! [[ “$1” =~ ^E[0-9]{7}.zip$ ]]; then
echo “zip file is wrongly named: it should be
exit 1
fi
echo “Unzipping file: $1”
if [ ! -f “$1” ]; then
echo “File $1 does not exist.”
exit 1
fi
tmp_folder=”$(mktemp -d)”
function cleanup {
cd /tmp
rm -rf “$tmp_folder”
}
trap cleanup EXIT
zip_path=”$(realpath “$1″)”
cd “$tmp_folder”
mkdir unzip; cd unzip
if ! unzip “$zip_path” > /dev/null; then
echo “Unzipping $1 failed; corrupt file?”
exit 1
fi
if [ ! -f userswap.c ]; then
echo “userswap.c missing”
exit 1
fi
if [ -f bonus_userswap.c ] && [ ! -f bonus_userswap.txt ]; then
echo “bonus_userswap.c present but bonus_userswap.txt missing”
exit 1
fi
if [ ! -f bonus_userswap.c ] && [ -f bonus_userswap.txt ]; then
echo “bonus_userswap.txt present but bonus_userswap.c missing”
exit 1
fi
mkdir ../compile
mv userswap.c bonus_userswap.c bonus_userswap.txt ../compile 2>/dev/null
if find -type f | grep .; then
echo “Above extraneous files found.”
exit 1
fi
cd ../compile
cat > userswap.h <
void userswap_set_size(size_t size);
void *userswap_alloc(size_t size);
void userswap_free(void *mem);
void *userswap_map(int fd, size_t size);
#endif
EOF
if ! gcc -g -std=c18 -O2 -c userswap.c; then
echo “userswap.c compilation failed.”
exit 1
fi
if [ -f bonus_userswap.c ] && ! gcc -g -std=c18 -O2 -c bonus_userswap.c; then
echo “bonus_userswap.c compilation failed.”
exit 1
fi
echo “Success!”
CC := gcc
CFLAGS := -g -std=c18 -O2 -Wall -Wextra -Werror -Wno-error=unused-parameter
all: workload_wraddr workload_readonly workload_rdfile workload_wrfile
workload_readonly: workload_readonly.o userswap.o userswap.h
workload_wraddr: workload_wraddr.o userswap.o userswap.h
workload_rdfile: workload_rdfile.o userswap.o userswap.h
workload_wrfile: workload_wrfile.o userswap.o userswap.h
clean:
rm -f *.o workload_wraddr workload_readonly workload_rdfile workload_wrfile
.PHONY: all clean
#include “userswap.h”
void userswap_set_size(size_t size) {
}
void *userswap_alloc(size_t size) {
return NULL;
}
void userswap_free(void *mem) {
}
void *userswap_map(int fd, size_t size) {
return NULL;
}
#ifndef USERSWAP_H
#define USERSWAP_H
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 200809L
#endif
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include
void userswap_set_size(size_t size);
void *userswap_alloc(size_t size);
void userswap_free(void *mem);
void *userswap_map(int fd, size_t size);
#endif
#include “userswap.h”
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[]) {
(void)argc;
(void)argv;
const _Bool use_userswap = 1;
const size_t memory_size = 10 * 1024 * 1024;
uintptr_t *const mem = malloc(memory_size);
if (!mem) {
return 1;
}
for (size_t i = 0; i < memory_size / sizeof(uintptr_t); ++i) {
mem[i] = (uintptr_t)(mem + i);
}
char tempfn[] = "/tmp/uswlrdflXXXXXX";
int tempfile = mkstemp(tempfn);
if (tempfile == -1) {
fprintf(stderr, "Failed to make temporary file\n");
return 1;
}
unlink(tempfn);
if (write(tempfile, mem, memory_size) != memory_size) {
fprintf(stderr, "Failed to write to temporary file\n");
return 1;
}
uintptr_t *const file_map = use_userswap
? userswap_map(tempfile, memory_size)
: mmap(NULL, memory_size, PROT_READ, MAP_PRIVATE, tempfile, 0);
if (!file_map || file_map == MAP_FAILED) {
fprintf(stderr, "Failed to map file\n");
return 1;
}
_Bool failed = 0;
for (size_t i = 0; i < memory_size / sizeof(uintptr_t); ++i) {
if (mem[i] != file_map[i]) {
printf("Failed at entry %zu, expected %" PRIxPTR ", got %" PRIxPTR "\n", i, mem[i],
file_map[i]);
failed = 1;
}
}
return failed;
}
#include "userswap.h"
#include
#include
#include
#include
int main(int argc, char *argv[]) {
(void)argc;
(void)argv;
const _Bool use_userswap = 1;
const size_t memory_size = 10 * 1024 * 1024;
volatile size_t *const mem = use_userswap ? userswap_alloc(memory_size) : malloc(memory_size);
if (!mem) {
return 1;
}
size_t scratch = 0;
for (size_t i = 0; i < memory_size / sizeof(size_t); ++i) {
scratch += mem[i];
}
if (use_userswap) {
userswap_free((void *)mem);
} else {
free((void *)mem);
}
printf("%zu\n", scratch);
return 0;
}
#include "userswap.h"
#include
#include
#include
#include
int main(int argc, char *argv[]) {
(void)argc;
(void)argv;
const _Bool use_userswap = 1;
const size_t memory_size = 10 * 1024 * 1024;
volatile uintptr_t *const mem = use_userswap ? userswap_alloc(memory_size) : malloc(memory_size);
if (!mem) {
return 1;
}
for (size_t i = 0; i < memory_size / sizeof(uintptr_t); ++i) {
mem[i] = (uintptr_t)(mem + i);
}
_Bool failed = 0;
for (size_t i = 0; i < memory_size / sizeof(uintptr_t); ++i) {
if (mem[i] != (uintptr_t)(mem + i)) {
printf("Failed at %p: %" PRIxPTR "\n", mem + i, mem[i]);
failed = 1;
}
}
if (use_userswap) {
userswap_free((void *)mem);
} else {
free((void *)mem);
}
return failed;
}
#include "userswap.h"
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[]) {
(void)argc;
(void)argv;
const _Bool use_userswap = 1;
const size_t memory_size = 10 * 1024 * 1024;
uintptr_t *const mem = malloc(memory_size);
if (!mem) {
return 1;
}
for (size_t i = 0; i < memory_size / sizeof(uintptr_t); ++i) { mem[i] = (uintptr_t)(mem + i); } char tempfn[] = "/tmp/uswlrdflXXXXXX"; int tempfile = mkstemp(tempfn); if (tempfile == -1) { fprintf(stderr, "Failed to make temporary file\n"); return 1; } unlink(tempfn); if (write(tempfile, mem, memory_size) != memory_size) { fprintf(stderr, "Failed to write to temporary file\n"); return 1; } uintptr_t *const file_map = use_userswap ? userswap_map(tempfile, memory_size) : mmap(NULL, memory_size, PROT_READ | PROT_WRITE, MAP_SHARED, tempfile, 0); if (!file_map || file_map == MAP_FAILED) { fprintf(stderr, "Failed to map file\n"); return 1; } _Bool failed = 0; for (size_t i = 0; i < memory_size / sizeof(uintptr_t); ++i) { if (mem[i] != file_map[i]) { printf("Failed read at entry %zu, expected %" PRIxPTR ", got %" PRIxPTR "\n", i, mem[i], file_map[i]); failed = 1; } file_map[i] = i; } if (use_userswap) { userswap_free(file_map); } else { if (msync(file_map, memory_size, MS_SYNC) != 0) { perror("msync failed\n"); return 1; } munmap(file_map, memory_size); } if (pread(tempfile, mem, memory_size, 0) != memory_size) { fprintf(stderr, "Failed to write back from temporary file\n"); } for (size_t i = 0; i < memory_size / sizeof(uintptr_t); ++i) { if (mem[i] != i) { printf("Failed read at entry %zu, expected %zx, got %" PRIxPTR "\n", i, i, file_map[i]); failed = 1; } } return failed; } check_zip.sh Makefile userswap.c userswap.h workload_rdfile.c workload_readonly.c workload_wraddr.c workload_wrfile.c