/* This is already sort of deprecated as I introduce it -- * it doesn't seem to provide much benefit over _sys_time, which I think I * have to keep anyways, so processes in an empty namespace can still keep * time. */ #include #include #include #include #include #include #include #include #include #include #include typedef struct { uint64_t base; } TimeObj; static long handle(VfsReq *req) { TimeObj *h; if (req->type == VFSOP_OPEN) { if (reqpathcmp(req, "")) { h = kmalloc(sizeof *h, "dev/time"); h->base = uptime_ns(); return (uintptr_t)h; } else { return -ENOENT; } } h = (__force void*)req->id; if (req->type == VFSOP_CLOSE) { assert(h); kfree(h); return 0; } uint64_t now = uptime_ns(); union { char buf[8]; uint64_t t; } u; switch (req->type) { case VFSOP_READ: u.t = now - h->base; return req_readcopy(req, u.buf, sizeof u.buf); case VFSOP_GETSIZE: return 8; case VFSOP_WRITE: if (req->input.len == 8) { assert(!req->input.kern); if (pcpy_from(req->caller, u.buf, req->input.buf, sizeof u.buf) != sizeof(u.buf)) { return -EGENERIC; } h->base = now - u.t; assert(u.t == now - h->base); return 8; } return -EGENERIC; default: return -ENOSYS; } } static void accept(VfsReq *req) { vfsreq_finish_short(req, handle(req)); } void time_init(void) { vfs_root_register("/dev/bintime", accept); }