summaryrefslogtreecommitdiffstats
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..53ca54b
--- /dev/null
+++ b/main.c
@@ -0,0 +1,137 @@
+#include <ebs.c>
+#include <sys/mman.h>
+#include <error.h>
+#include <errno.h>
+#include <poll.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <stdatomic.h>
+#include <time.h>
+#define S0(x) ((x) ? (x) : "")
+static unsigned long long micros (void) {
+ struct timespec tp;
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+ return tp.tv_sec*1000000+tp.tv_nsec/1000;
+}
+struct nit {
+ atomic_int možen;
+ int pipe;
+};
+static void * pričakuj (void * ptr) {
+ struct nit * nit = (struct nit *) ptr;
+ struct pollfd pollfd[] = {
+ {
+ .fd = STDIN_FILENO,
+ .events = POLLIN
+ },
+ {
+ .fd = nit->pipe,
+ .events = POLLIN
+ }
+ };
+ while (1) {
+ int ret = poll(pollfd, 2, -1);
+ if (ret == -1) {
+ error_at_line(0, errno, __FILE__, __LINE__, "poll");
+ nit->možen = 2;
+ return NULL;
+ }
+ if (pollfd[1].revents & POLLIN)
+ return NULL;
+ if (pollfd[0].revents & POLLIN)
+ nit->možen = 1;
+ }
+}
+int main (int argc, char ** argv) {
+ if (argc != 1+1)
+ error_at_line(1, 0, __FILE__, __LINE__, "%s program.ebs", S0(argv[0]));
+ int r = 0;
+ struct ebs ebs;
+ ebs_init(&ebs);
+ pthread_t vhod;
+ int pipefd[2];
+ int threadret = -1;
+ int pfd = -1;
+ if (pipe(pipefd) == -1)
+ error_at_line(2, errno, __FILE__, __LINE__, "pipe");
+ struct nit nit = {
+ .možen = 0,
+ .pipe = pipefd[0]
+ };
+ if ((threadret = pthread_create(&vhod, NULL, pričakuj, &nit))) {
+ error_at_line(0, threadret, __FILE__, __LINE__, "pthread_create");
+ r = 3;
+ goto r;
+ }
+ if ((pfd = open(argv[1], O_RDONLY | O_CLOEXEC)) == -1) {
+ error_at_line(0, errno, __FILE__, __LINE__, "open(%s)", argv[1]);
+ r = 4;
+ goto r;
+ }
+ struct stat statbuf;
+ if (fstat(pfd, &statbuf) == -1) {
+ error_at_line(0, errno, __FILE__, __LINE__, "fstat(pfd, &statbuf)");
+ r = 5;
+ goto r;
+ }
+ if (!(ebs.pm_velikost = statbuf.st_size)) {
+ error_at_line(0, errno, __FILE__, __LINE__, "!(ebs.pm_velikost = statbuf.st_size)");
+ r = 6;
+ goto r;
+ }
+ if (!(ebs.pm = mmap(NULL, ebs.pm_velikost, PROT_READ, MAP_SHARED, pfd, 0))) {
+ error_at_line(0, errno, __FILE__, __LINE__, "!mmap(NULL, ebs.pm_velikost, PROT_READ, MAP_SHARED, pfd, 0)");
+ r = 7;
+ goto r;
+ }
+ unsigned long long int začetek = micros();
+ unsigned long long inštrukcij = 0;
+ while (ebs_delo(&ebs) == nadaljuj) {
+ inštrukcij++;
+ if (!(inštrukcij % 100000000))
+ fprintf(stderr, "hitrost izvajanja: %llu op/us (MHz)\r", inštrukcij/(micros()-začetek));
+ switch (nit.možen) {
+ case 0: // ni vhoda, ni napake
+ break;
+ case 1: // imamo vsaj en bajt
+ if (ebs.vhod_medp_indeks > 7) {
+ char buf;
+ int got = read(STDIN_FILENO, &buf, 1);
+ if (got == -1) {
+ error_at_line(0, errno, __FILE__, __LINE__, "read");
+ r = 8;
+ goto r;
+ }
+ ebs.vhod_medp_indeks = 0;
+ ebs.vhod_medp = buf;
+ nit.možen = 0;
+ }
+ break;
+ case 2: // napaka
+ error_at_line(0, 0, __FILE__, __LINE__, "napaka v vhodni niti");
+ r = 8;
+ goto r;
+ break;
+ }
+ }
+ fprintf(stderr, "konec izvajanja");
+ r:
+ if (!threadret) {
+ if (write(pipefd[1], "", 1) == -1)
+ error_at_line(0, errno, __FILE__, __LINE__, "write");
+ threadret = pthread_join(vhod, NULL);
+ if (threadret)
+ error_at_line(0, threadret, __FILE__, __LINE__, "pthread_join");
+ }
+ if (close(pipefd[0]) == -1)
+ error_at_line(0, errno, __FILE__, __LINE__, "close(pipefd[0])");
+ if (close(pipefd[1]) == -1)
+ error_at_line(0, errno, __FILE__, __LINE__, "close(pipefd[1])");
+ if (ebs.pm && munmap(ebs.pm, ebs.pm_velikost) == -1)
+ error_at_line(0, errno, __FILE__, __LINE__, "munmap(ebs.pm, ebs.pm_velikost)");
+ close(pfd);
+ pfd = -1;
+ return r;
+}