#include #include #include #include #include #include #include #include #include #include #include #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)); int možen = nit.možen; switch (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; }