diff --git a/api/fs/fat.hpp b/api/fs/fat.hpp index c298f9ce0f..2a4f1f310c 100644 --- a/api/fs/fat.hpp +++ b/api/fs/fat.hpp @@ -24,6 +24,7 @@ #include #include #include +#include namespace fs { @@ -32,24 +33,26 @@ namespace fs struct FAT : public FileSystem { /// ----------------------------------------------------- /// - virtual void mount(uint64_t lba, uint64_t size, on_mount_func on_mount) override; + void mount(uint64_t lba, uint64_t size, on_mount_func on_mount) override; // path is a path in the mounted filesystem - virtual void ls (const std::string& path, on_ls_func) override; - virtual void ls (const Dirent& entry, on_ls_func) override; - virtual List ls(const std::string& path) override; - virtual List ls(const Dirent&) override; + void ls (const std::string& path, on_ls_func) override; + void ls (const Dirent& entry, on_ls_func) override; + List ls(const std::string& path) override; + List ls(const Dirent&) override; /** Read @n bytes from file pointed by @entry starting at position @pos */ - virtual void read(const Dirent&, uint64_t pos, uint64_t n, on_read_func) override; - virtual Buffer read(const Dirent&, uint64_t pos, uint64_t n) override; + void read(const Dirent&, uint64_t pos, uint64_t n, on_read_func) override; + Buffer read(const Dirent&, uint64_t pos, uint64_t n) override; // return information about a filesystem entity - virtual void stat(const std::string&, on_stat_func) override; - virtual Dirent stat(const std::string& ent) override; + void stat(const std::string&, on_stat_func) override; + Dirent stat(const std::string& ent) override; + // async cached stat + void cstat(const std::string&, on_stat_func) override; // returns the name of the filesystem - virtual std::string name() const override + std::string name() const override { switch (this->fat_type) { @@ -91,7 +94,7 @@ namespace fs uint8_t attrib; uint8_t pad1[8]; uint16_t cluster_hi; - uint8_t pad2[4]; + uint32_t modified; uint16_t cluster_lo; uint32_t filesize; @@ -210,6 +213,9 @@ namespace fs uint32_t root_cluster; // index of root cluster uint32_t data_index; // index of first data sector (relative to partition) uint32_t data_sectors; // number of data sectors + + // simplistic cache for stat results + std::map stat_cache; }; } // fs diff --git a/api/fs/filesystem.hpp b/api/fs/filesystem.hpp index d102454e69..05a01ab038 100644 --- a/api/fs/filesystem.hpp +++ b/api/fs/filesystem.hpp @@ -62,15 +62,16 @@ namespace fs { struct Dirent { /** Default constructor */ explicit Dirent(const Enttype t = INVALID_ENTITY, const std::string& n = "", - const uint64_t blk = 0U, const uint64_t pr = 0U, - const uint64_t sz = 0U, const uint32_t attr = 0U) : - ftype {t}, - fname {n}, - block {blk}, - parent {pr}, - size_ {sz}, - attrib {attr}, - timestamp {0} + const uint64_t blk = 0, const uint64_t pr = 0, + const uint64_t sz = 0, const uint32_t attr = 0, + const uint32_t modt = 0) + : ftype {t}, + fname {n}, + block {blk}, + parent {pr}, + size_ {sz}, + attrib {attr}, + modif {modt} {} Enttype type() const noexcept @@ -108,6 +109,25 @@ namespace fs { } //< switch (type) } + // good luck + uint64_t modified() const + { + /* + uint32_t oldshit = modif; + uint32_t day = (oldshit & 0x1f); + uint32_t month = (oldshit >> 5) & 0x0f; + uint32_t year = (oldshit >> 9) & 0x7f; + oldshit >>= 16; + uint32_t secs = (oldshit & 0x1f) * 2; + uint32_t mins = (oldshit >> 5) & 0x3f; + uint32_t hrs = (oldshit >> 11) & 0x1f; + // invalid timestamp? + if (hrs > 23 or mins > 59 or secs > 59) + return 0; + */ + return modif; + } + uint64_t size() const noexcept { return size_; } @@ -118,7 +138,7 @@ namespace fs { uint64_t parent; //< Parent's block# uint64_t size_; uint32_t attrib; - int64_t timestamp; + uint32_t modif; }; //< struct Dirent struct List { @@ -168,6 +188,9 @@ namespace fs { virtual void stat(const std::string& ent, on_stat_func) = 0; virtual Dirent stat(const std::string& ent) = 0; + /** Cached async stat */ + virtual void cstat(const std::string&, on_stat_func) = 0; + /** Returns the name of this filesystem */ virtual std::string name() const = 0; diff --git a/api/kernel/os.hpp b/api/kernel/os.hpp index 78a1fc8d42..7c6d0f068d 100644 --- a/api/kernel/os.hpp +++ b/api/kernel/os.hpp @@ -18,10 +18,6 @@ #ifndef KERNEL_OS_HPP #define KERNEL_OS_HPP -#ifndef OS_VERSION -#define OS_VERSION "v?.?.?" -#endif - #include #include #include @@ -45,7 +41,7 @@ class OS { /* Get the version of the os */ static std::string version() - { return std::string(OS_VERSION); } + { return version_field; } /** Clock cycles since boot. */ static uint64_t cycles_since_boot() { @@ -168,7 +164,7 @@ class OS { static hw::Serial& com1; static RTC::timestamp_t booted_at_; - + static std::string version_field; struct Custom_init_struct { Custom_init_struct(Custom_init f, const char* n) diff --git a/src/fs/fat.cpp b/src/fs/fat.cpp index c310d32ce9..a8a335c9e3 100644 --- a/src/fs/fat.cpp +++ b/src/fs/fat.cpp @@ -239,7 +239,8 @@ namespace fs D->dir_cluster(root_cluster), sector, // parent block D->size(), - D->attrib); + D->attrib, + D->modified); } } else { @@ -255,7 +256,8 @@ namespace fs D->dir_cluster(root_cluster), sector, // parent block D->size(), - D->attrib); + D->attrib, + D->modified); } } // entry is long name diff --git a/src/fs/fat_async.cpp b/src/fs/fat_async.cpp index e6fc75211b..b5f5609969 100644 --- a/src/fs/fat_async.cpp +++ b/src/fs/fat_async.cpp @@ -198,6 +198,7 @@ namespace fs void FAT::stat(const std::string& strpath, on_stat_func func) { + // manual lookup auto path = std::make_shared (strpath); if (unlikely(path->empty())) { // root doesn't have any stat anyways @@ -223,7 +224,7 @@ namespace fs // find the matching filename in directory for (auto& e : *dirents) { if (unlikely(e.name() == filename)) { - // read this file + // return this dir entry func(no_error, e); return; } @@ -233,4 +234,21 @@ namespace fs func({ error_t::E_NOENT, filename }, Dirent(INVALID_ENTITY, filename)); }); } + + void FAT::cstat(const std::string& strpath, on_stat_func func) + { + // cache lookup + auto it = stat_cache.find(strpath); + if (it != stat_cache.end()) { + debug("used cached stat for %s\n", strpath.c_str()); + func(no_error, it->second); + return; + } + + stat(strpath, + [this, strpath, func] (error_t error, const FileSystem::Dirent& ent) { + stat_cache[strpath] = ent; + func(error, ent); + }); + } } diff --git a/src/hw/pit.cpp b/src/hw/pit.cpp index 79315572e6..9cb4450585 100644 --- a/src/hw/pit.cpp +++ b/src/hw/pit.cpp @@ -61,8 +61,8 @@ namespace hw { void PIT::disable_regular_interrupts() { - oneshot(1); - IRQ_manager::get().disable_irq(0); + if (current_mode_ != ONE_SHOT) + oneshot(1); } PIT::PIT() {} diff --git a/src/kernel/os.cpp b/src/kernel/os.cpp index 05a99c6812..afd4a4a1ae 100644 --- a/src/kernel/os.cpp +++ b/src/kernel/os.cpp @@ -54,6 +54,11 @@ const uintptr_t OS::elf_binary_size_ {(uintptr_t)&_ELF_END_ - (uintptr_t)&_ELF_S std::vector OS::custom_init_; +#ifndef OS_VERSION +#define OS_VERSION "v?.?.?" +#endif +std::string OS::version_field = OS_VERSION; + // Set default rsprint_handler OS::rsprint_func OS::rsprint_handler_ = &OS::default_rsprint; hw::Serial& OS::com1 = hw::Serial::port<1>(); diff --git a/src/seed/Makefile b/src/seed/Makefile index ebcfa27ab3..8ff805bacb 100644 --- a/src/seed/Makefile +++ b/src/seed/Makefile @@ -40,7 +40,7 @@ INC_NEWLIB=$(INSTALL)/newlib/include INC_LIBCXX=$(INSTALL)/libcxx/include CC = $(shell command -v clang-3.8 || command -v clang-3.6) -target i686-elf -CPP = $(shell command -v clang++-3.8 || command -v clang++-3.6) -target i686-elf +CPP = $(shell command -v clang++-3.8 || command -v clang++-3.6 || command -v clang++) -target i686-elf ifndef LD_INC LD_INC = ld endif diff --git a/src/seed/Makelib b/src/seed/Makelib index 01ea02e8a3..4af855cd77 100644 --- a/src/seed/Makelib +++ b/src/seed/Makelib @@ -22,7 +22,7 @@ INC_NEWLIB=$(INSTALL)/newlib/include INC_LIBCXX=$(INSTALL)/libcxx/include CC = $(shell command -v clang-3.8 || command -v clang-3.6) -target i686-elf -CPP = $(shell command -v clang++-3.8 || command -v clang++-3.6) -target i686-elf +CPP = $(shell command -v clang++-3.8 || command -v clang++-3.6 || command -v clang++) -target i686-elf ifndef AR_INC AR_INC = ar diff --git a/test/stress/service.cpp b/test/stress/service.cpp index aae047600a..ad0200fbd3 100644 --- a/test/stress/service.cpp +++ b/test/stress/service.cpp @@ -71,6 +71,11 @@ uint64_t TCP_BYTES_SENT = 0; void Service::start(const std::string&) { + + // Timer spam + for (int i = 0; i < 1000; i++) + Timers::oneshot(std::chrono::microseconds(i + 200), [](auto){}); + static auto& inet = net::Inet4::stack<0>(); // Static IP configuration, until we (possibly) get DHCP