Skip to content

Commit

Permalink
Merge pull request #1642 from hioa-cs/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
alfreb authored Jan 16, 2018
2 parents 34bb08c + 68cff00 commit e2efe3f
Show file tree
Hide file tree
Showing 95 changed files with 1,904 additions and 908 deletions.
14 changes: 13 additions & 1 deletion api/arch.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include <cstddef>
#include <cstdint>
#include <cassert>
#include <ctime>
#include <string>

extern void __arch_init();
extern void __arch_poweroff();
Expand All @@ -37,7 +39,9 @@ extern void __arch_preempt_forever(void(*)());

inline void __arch_hw_barrier() noexcept;
inline void __sw_barrier() noexcept;
extern int64_t __arch_time_now() noexcept;

extern uint64_t __arch_system_time() noexcept;
extern timespec __arch_wall_clock() noexcept;
inline uint64_t __arch_cpu_cycles() noexcept;


Expand All @@ -55,4 +59,12 @@ inline void __sw_barrier() noexcept
#error "Unsupported arch specified"
#endif

// retrieve system information
struct arch_system_info_t
{
std::string uuid;
uint64_t physical_memory;
};
const arch_system_info_t& __arch_system_info() noexcept;

#endif
27 changes: 27 additions & 0 deletions api/hw/ioport.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,33 @@ namespace hw {
asm volatile ("outw %%ax,%%dx"::"a" (data), "d"(port));
#else
#error "outw() not implemented for selected arch"
#endif
}

/** Receive a double-word from port.
@param port : The port number to receive from
*/
static inline uint32_t inl(int port)
{
uint32_t ret;
#if defined(ARCH_x86)
//asm volatile ("xorl %eax,%eax");
asm volatile ("inl %%dx,%%eax":"=a" (ret):"d"(port));
#else
#error "inw() not implemented for selected arch"
#endif
return ret;
}

/** Send a double-word to port.
@param port : The port to send to
@param data : Double-word of data
*/
static inline void outl(int port, uint32_t data) {
#if defined(ARCH_x86)
asm volatile ("outl %%eax,%%dx"::"a" (data), "d"(port));
#else
#error "outw() not implemented for selected arch"
#endif
}

Expand Down
44 changes: 31 additions & 13 deletions api/kernel/os.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,27 +60,26 @@ class OS {
static const char* cmdline_args() noexcept;

/** Clock cycles since boot. */
static uint64_t cycles_since_boot() {
return __arch_cpu_cycles();
}
/** micro seconds since boot */
static int64_t micros_since_boot() noexcept;
static uint64_t cycles_since_boot() noexcept;

/** Nanoseconds since boot converted from cycles */
static uint64_t nanos_since_boot() noexcept;

/** Timestamp for when OS was booted */
static RTC::timestamp_t boot_timestamp();
static RTC::timestamp_t boot_timestamp() noexcept;

/** Uptime in whole seconds. */
static RTC::timestamp_t uptime();
static RTC::timestamp_t uptime() noexcept;

/** Time spent sleeping (halt) in cycles */
static uint64_t cycles_asleep() noexcept;

/** Time spent sleeping (halt) in micros */
static uint64_t micros_asleep() noexcept;
/** Time spent sleeping (halt) in nanoseconds */
static uint64_t nanos_asleep() noexcept;


static MHz cpu_freq() noexcept
{ return cpu_mhz_; }
static auto cpu_freq() noexcept
{ return cpu_khz_; }

/**
* Reboot operating system
Expand Down Expand Up @@ -236,6 +235,8 @@ class OS {
/** Initialize common subsystems, call Service::start */
static void post_start();

static void install_cpu_frequency(MHz);

private:
/** Process multiboot info. Called by 'start' if multibooted **/
static void multiboot(uint32_t boot_addr);
Expand All @@ -254,9 +255,8 @@ class OS {
static bool boot_sequence_passed_;
static bool m_is_live_updated;
static bool m_block_drivers_ready;
static MHz cpu_mhz_;
static KHz cpu_khz_;

static RTC::timestamp_t booted_at_;
static uintptr_t liveupdate_loc_;
static std::string version_str_;
static std::string arch_str_;
Expand Down Expand Up @@ -295,4 +295,22 @@ inline OS::Span_mods OS::modules()
return nullptr;
}

inline uint64_t OS::cycles_since_boot() noexcept
{
return __arch_cpu_cycles();
}
inline uint64_t OS::nanos_since_boot() noexcept
{
return (cycles_since_boot() * 1e6) / cpu_freq().count();
}

inline RTC::timestamp_t OS::boot_timestamp() noexcept
{
return RTC::boot_timestamp();
}
inline RTC::timestamp_t OS::uptime() noexcept
{
return RTC::time_since_boot();
}

#endif //< KERNEL_OS_HPP
10 changes: 8 additions & 2 deletions api/kernel/rtc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,16 @@
class RTC
{
public:
using timestamp_t = int64_t;
using timestamp_t = uint64_t;

/// a 64-bit nanosecond timestamp of the current time
static timestamp_t nanos_now() {
return __arch_system_time();
}
/// returns a 64-bit unix timestamp of the current time
static timestamp_t now() { return __arch_time_now(); }
static timestamp_t now() {
return __arch_wall_clock().tv_sec;
}

/// returns a 64-bit unix timestamp for when the OS was booted
static timestamp_t boot_timestamp() {
Expand Down
2 changes: 1 addition & 1 deletion api/kernel/timers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class Timers
{
public:
using id_t = int32_t;
using duration_t = std::chrono::microseconds;
using duration_t = std::chrono::nanoseconds;
using handler_t = delegate<void(id_t)>;

static constexpr id_t UNUSED_ID = -1;
Expand Down
26 changes: 26 additions & 0 deletions api/net/super_stack.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,35 @@ class Super_stack {
template <typename IPV>
static Inet<IPV>& get(int N, int sub);

/**
* @brief Get a stack by MAC addr.
* Throws if no NIC with the given MAC exists.
*
* @param[in] mac The mac
*
* @tparam IPV IP version
*
* @return A stack
*/
template <typename IPV>
static Inet<IPV>& get(const std::string& mac);

template <typename IPV>
Inet<IPV>& create(hw::Nic& nic, int N, int sub);

/**
* @brief Create a stack on the given Nic,
* occupying the first free index.
*
* @param nic The nic
*
* @tparam IPV IP version
*
* @return A stack
*/
template <typename IPV>
Inet<IPV>& create(hw::Nic& nic);

IP4_stacks& ip4_stacks()
{ return ip4_stacks_; }

Expand Down
3 changes: 2 additions & 1 deletion api/profile
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ class ScopedProfiler
* --------------------------------------------------------------------------------
*
*/
static std::string get_statistics();
static std::string get_statistics(bool sorted = true);

private:
uint64_t tick_start;
Expand All @@ -132,6 +132,7 @@ class ScopedProfiler
std::string function_name;
unsigned num_samples;
uint64_t cycles_average;
uint64_t nanos_start;
};


Expand Down
59 changes: 45 additions & 14 deletions diskimagebuild/filetree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ File::File(const char* path)
rewind(f);

this->data = std::unique_ptr<char[]> (new char[size], std::default_delete<char[]> ());
fread(this->data.get(), this->size, 1, f);
size_t actual = fread(this->data.get(), this->size, 1, f);
if (actual != 1) {
throw std::runtime_error("diskbuilder: Could not read from file " + std::string(path));
}
fclose(f);
}
Dir::Dir(const char* path)
Expand Down Expand Up @@ -80,34 +83,62 @@ void FileSys::add_dir(Dir& dvec)
strcat(cwd_buffer, dvec.name.c_str());

//printf("*** Entering %s...\n", cwd_buffer);
chdir(cwd_buffer);
int res = chdir(cwd_buffer);
// throw immediately when unable to read directory
if (res < 0) {
fprintf(stderr, "Unable to enter directory %s\n", cwd_buffer);
throw std::runtime_error("Unable to enter directory " + std::string(cwd_buffer));
}

auto* dir = opendir(cwd_buffer);
if (dir == nullptr)
{
printf("Could not open directory:\n-> %s\n", cwd_buffer);
return;
// throw immediately when unable to open directory
if (dir == nullptr) {
fprintf(stderr, "Unable to open directory %s\n", cwd_buffer);
throw std::runtime_error("Unable to open directory " + std::string(cwd_buffer));
}

std::vector<std::string> sub_dirs;
std::vector<std::string> sub_files;

struct dirent* ent;
while ((ent = readdir(dir)) != nullptr)
{
std::string name(ent->d_name);
if (name == ".." || name == ".") continue;

if (ent->d_type == DT_DIR) {
auto& d = dvec.add_dir(ent->d_name);
add_dir(d);
sub_dirs.push_back(std::move(name));
}
else {
try {
dvec.add_file(ent->d_name);
} catch (std::exception& e) {
fprintf(stderr, "%s\n", e.what());
}
sub_files.push_back(std::move(name));
}
}
// close directory before adding more folders and files
res = closedir(dir);
if (res < 0) {
throw std::runtime_error("diskbuilder: Failed to close directory");
}

// add sub directories
for (const auto& dirname : sub_dirs) {
auto& d = dvec.add_dir(dirname.c_str());
add_dir(d);
}
// add files in current directory
for (const auto& filename : sub_files)
{
try {
dvec.add_file(filename.c_str());
} catch (std::exception& e) {
fprintf(stderr, "%s\n", e.what());
}
}

// pop work dir
chdir(pwd_buffer);
res = chdir(pwd_buffer);
if (res < 0) {
throw std::runtime_error("diskbuilder: Failed to return back to parent directory");
}
}

void FileSys::gather(const char* path)
Expand Down
1 change: 1 addition & 0 deletions examples/IRCd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ set(LOCAL_INCLUDES "")
set(DRIVERS
virtionet
vmxnet3
#boot_logger
)

set (PLUGINS
Expand Down
8 changes: 6 additions & 2 deletions examples/IRCd/service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,19 @@
#include <os>
#include <profile>
#include <timers>
#include <sys/time.h>
#define USE_STACK_SAMPLING
#define PERIOD_SECS 4

#include "ircd/ircd.hpp"
static std::unique_ptr<IrcServer> ircd = nullptr;
using namespace std::chrono;

void Service::start()
{
// run a small self-test to verify parser is sane
extern void selftest(); selftest();

ircd = IrcServer::from_config();

ircd->set_motd([] () -> const std::string& {
Expand Down Expand Up @@ -136,6 +138,8 @@ void Service::ready()
//StackSampler::set_mode(StackSampler::MODE_CALLER);
#endif

using namespace std::chrono;
Timers::periodic(seconds(1), seconds(PERIOD_SECS), print_stats);

// profiler statistics
printf("%s\n", ScopedProfiler::get_statistics(false).c_str());
}
2 changes: 1 addition & 1 deletion examples/IRCd/vm.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"image" : "IRCd",
"net" : [{"device" : "vmxnet3"}],
"net" : [{"device" : "virtio"}],
"mem" : 1024
}
2 changes: 1 addition & 1 deletion examples/STREAM/service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

double mysecond()
{
return OS::micros_since_boot() / 1000000.f;
return OS::nanos_since_boot() / 1.0e9;
}

void Service::start()
Expand Down
6 changes: 3 additions & 3 deletions examples/TCP_perf/service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ void start_measure()
packets_tx = Statman::get().get_by_name("eth0.ethernet.packets_tx").get_uint64();
printf("<Settings> DACK: %lli ms WSIZE: %u WS: %u CALC_WIN: %u TS: %s\n",
dack.count(), winsize, wscale, winsize << wscale, timestamps ? "ON" : "OFF");
ts = OS::micros_since_boot();
ts = OS::nanos_since_boot();
activity_before.reset();
}

void stop_measure()
{
auto diff = OS::micros_since_boot() - ts;
auto diff = OS::nanos_since_boot() - ts;
activity_after.reset();

StackSampler::print(15);
Expand All @@ -79,7 +79,7 @@ void stop_measure()
packets_rx = Statman::get().get_by_name("eth0.ethernet.packets_rx").get_uint64() - packets_rx;
packets_tx = Statman::get().get_by_name("eth0.ethernet.packets_tx").get_uint64() - packets_tx;
printf("Packets RX [%llu] TX [%llu]\n", packets_rx, packets_tx);
double durs = ((double)diff) / 1000 / 1000;
double durs = (double) diff / 1000000000ULL;
double mbits = (received/(1024*1024)*8) / durs;
printf("Duration: %.2fs - Payload: %lld/%u MB - %.2f MBit/s\n",
durs, received/(1024*1024), SIZE/(1024*1024), mbits);
Expand Down
Loading

0 comments on commit e2efe3f

Please sign in to comment.