// Miscellaneous utilities #include "libutil.h" #include #include #include #include #include #include #include #include #include #include static void __attribute__((noreturn)) vdie(const char* errstr, va_list ap) { vfprintf(stderr, errstr, ap); fprintf(stderr, "\n"); exit(1); } void __attribute__((noreturn)) die(const char* errstr, ...) { va_list ap; va_start(ap, errstr); vdie(errstr, ap); } void edie(const char* errstr, ...) { va_list ap; va_start(ap, errstr); #ifdef XV6_USER // There is no errno on xv6 vdie(errstr, ap); #else vfprintf(stderr, errstr, ap); va_end(ap); fprintf(stderr, ": %s\n", strerror(errno)); exit(1); #endif } size_t xread(int fd, void *buf, size_t n) { size_t pos = 0; while (pos < n) { int r = read(fd, (char*)buf + pos, n - pos); if (r < 0) edie("read failed"); if (r == 0) break; pos += r; } return pos; } void xwrite(int fd, const void *buf, size_t n) { int r; while (n) { r = write(fd, buf, n); if (r < 0 || r == 0) edie("write failed"); buf = (char *) buf + r; n -= r; } } uint64_t now_usec(void) { struct timeval tv; if (gettimeofday(&tv, nullptr) < 0) edie("gettimeofday"); return tv.tv_sec * 1000000ull + tv.tv_usec; } #if !defined(XV6_USER) // setaffinity is a syscall in xv6, but not standard in Linux int setaffinity(int c) { cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(c, &cpuset); if (sched_setaffinity(0, sizeof(cpuset), &cpuset) < 0) edie("setaffinity, sched_setaffinity failed"); return 0; } ulong rdtsc(void) { #if defined(__x86_64__) ulong low, hi; asm volatile( "rdtsc\n" : "=a"(low), "=d"(hi) : :); return hi << 32 | low; #else // TODO: aarch64 return 0; #endif } #endif