Skip to content

Commit e2efe3f

Browse files
authored
Merge pull request #1642 from hioa-cs/dev
Dev
2 parents 34bb08c + 68cff00 commit e2efe3f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+1904
-908
lines changed

api/arch.hpp

+13-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include <cstddef>
2424
#include <cstdint>
2525
#include <cassert>
26+
#include <ctime>
27+
#include <string>
2628

2729
extern void __arch_init();
2830
extern void __arch_poweroff();
@@ -37,7 +39,9 @@ extern void __arch_preempt_forever(void(*)());
3739

3840
inline void __arch_hw_barrier() noexcept;
3941
inline void __sw_barrier() noexcept;
40-
extern int64_t __arch_time_now() noexcept;
42+
43+
extern uint64_t __arch_system_time() noexcept;
44+
extern timespec __arch_wall_clock() noexcept;
4145
inline uint64_t __arch_cpu_cycles() noexcept;
4246

4347

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

62+
// retrieve system information
63+
struct arch_system_info_t
64+
{
65+
std::string uuid;
66+
uint64_t physical_memory;
67+
};
68+
const arch_system_info_t& __arch_system_info() noexcept;
69+
5870
#endif

api/hw/ioport.hpp

+27
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,33 @@ namespace hw {
7474
asm volatile ("outw %%ax,%%dx"::"a" (data), "d"(port));
7575
#else
7676
#error "outw() not implemented for selected arch"
77+
#endif
78+
}
79+
80+
/** Receive a double-word from port.
81+
@param port : The port number to receive from
82+
*/
83+
static inline uint32_t inl(int port)
84+
{
85+
uint32_t ret;
86+
#if defined(ARCH_x86)
87+
//asm volatile ("xorl %eax,%eax");
88+
asm volatile ("inl %%dx,%%eax":"=a" (ret):"d"(port));
89+
#else
90+
#error "inw() not implemented for selected arch"
91+
#endif
92+
return ret;
93+
}
94+
95+
/** Send a double-word to port.
96+
@param port : The port to send to
97+
@param data : Double-word of data
98+
*/
99+
static inline void outl(int port, uint32_t data) {
100+
#if defined(ARCH_x86)
101+
asm volatile ("outl %%eax,%%dx"::"a" (data), "d"(port));
102+
#else
103+
#error "outw() not implemented for selected arch"
77104
#endif
78105
}
79106

api/kernel/os.hpp

+31-13
Original file line numberDiff line numberDiff line change
@@ -60,27 +60,26 @@ class OS {
6060
static const char* cmdline_args() noexcept;
6161

6262
/** Clock cycles since boot. */
63-
static uint64_t cycles_since_boot() {
64-
return __arch_cpu_cycles();
65-
}
66-
/** micro seconds since boot */
67-
static int64_t micros_since_boot() noexcept;
63+
static uint64_t cycles_since_boot() noexcept;
64+
65+
/** Nanoseconds since boot converted from cycles */
66+
static uint64_t nanos_since_boot() noexcept;
6867

6968
/** Timestamp for when OS was booted */
70-
static RTC::timestamp_t boot_timestamp();
69+
static RTC::timestamp_t boot_timestamp() noexcept;
7170

7271
/** Uptime in whole seconds. */
73-
static RTC::timestamp_t uptime();
72+
static RTC::timestamp_t uptime() noexcept;
7473

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

78-
/** Time spent sleeping (halt) in micros */
79-
static uint64_t micros_asleep() noexcept;
77+
/** Time spent sleeping (halt) in nanoseconds */
78+
static uint64_t nanos_asleep() noexcept;
8079

8180

82-
static MHz cpu_freq() noexcept
83-
{ return cpu_mhz_; }
81+
static auto cpu_freq() noexcept
82+
{ return cpu_khz_; }
8483

8584
/**
8685
* Reboot operating system
@@ -236,6 +235,8 @@ class OS {
236235
/** Initialize common subsystems, call Service::start */
237236
static void post_start();
238237

238+
static void install_cpu_frequency(MHz);
239+
239240
private:
240241
/** Process multiboot info. Called by 'start' if multibooted **/
241242
static void multiboot(uint32_t boot_addr);
@@ -254,9 +255,8 @@ class OS {
254255
static bool boot_sequence_passed_;
255256
static bool m_is_live_updated;
256257
static bool m_block_drivers_ready;
257-
static MHz cpu_mhz_;
258+
static KHz cpu_khz_;
258259

259-
static RTC::timestamp_t booted_at_;
260260
static uintptr_t liveupdate_loc_;
261261
static std::string version_str_;
262262
static std::string arch_str_;
@@ -295,4 +295,22 @@ inline OS::Span_mods OS::modules()
295295
return nullptr;
296296
}
297297

298+
inline uint64_t OS::cycles_since_boot() noexcept
299+
{
300+
return __arch_cpu_cycles();
301+
}
302+
inline uint64_t OS::nanos_since_boot() noexcept
303+
{
304+
return (cycles_since_boot() * 1e6) / cpu_freq().count();
305+
}
306+
307+
inline RTC::timestamp_t OS::boot_timestamp() noexcept
308+
{
309+
return RTC::boot_timestamp();
310+
}
311+
inline RTC::timestamp_t OS::uptime() noexcept
312+
{
313+
return RTC::time_since_boot();
314+
}
315+
298316
#endif //< KERNEL_OS_HPP

api/kernel/rtc.hpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,16 @@
2626
class RTC
2727
{
2828
public:
29-
using timestamp_t = int64_t;
29+
using timestamp_t = uint64_t;
3030

31+
/// a 64-bit nanosecond timestamp of the current time
32+
static timestamp_t nanos_now() {
33+
return __arch_system_time();
34+
}
3135
/// returns a 64-bit unix timestamp of the current time
32-
static timestamp_t now() { return __arch_time_now(); }
36+
static timestamp_t now() {
37+
return __arch_wall_clock().tv_sec;
38+
}
3339

3440
/// returns a 64-bit unix timestamp for when the OS was booted
3541
static timestamp_t boot_timestamp() {

api/kernel/timers.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class Timers
2929
{
3030
public:
3131
using id_t = int32_t;
32-
using duration_t = std::chrono::microseconds;
32+
using duration_t = std::chrono::nanoseconds;
3333
using handler_t = delegate<void(id_t)>;
3434

3535
static constexpr id_t UNUSED_ID = -1;

api/net/super_stack.hpp

+26
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,35 @@ class Super_stack {
6262
template <typename IPV>
6363
static Inet<IPV>& get(int N, int sub);
6464

65+
/**
66+
* @brief Get a stack by MAC addr.
67+
* Throws if no NIC with the given MAC exists.
68+
*
69+
* @param[in] mac The mac
70+
*
71+
* @tparam IPV IP version
72+
*
73+
* @return A stack
74+
*/
75+
template <typename IPV>
76+
static Inet<IPV>& get(const std::string& mac);
77+
6578
template <typename IPV>
6679
Inet<IPV>& create(hw::Nic& nic, int N, int sub);
6780

81+
/**
82+
* @brief Create a stack on the given Nic,
83+
* occupying the first free index.
84+
*
85+
* @param nic The nic
86+
*
87+
* @tparam IPV IP version
88+
*
89+
* @return A stack
90+
*/
91+
template <typename IPV>
92+
Inet<IPV>& create(hw::Nic& nic);
93+
6894
IP4_stacks& ip4_stacks()
6995
{ return ip4_stacks_; }
7096

api/profile

+2-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ class ScopedProfiler
118118
* --------------------------------------------------------------------------------
119119
*
120120
*/
121-
static std::string get_statistics();
121+
static std::string get_statistics(bool sorted = true);
122122

123123
private:
124124
uint64_t tick_start;
@@ -132,6 +132,7 @@ class ScopedProfiler
132132
std::string function_name;
133133
unsigned num_samples;
134134
uint64_t cycles_average;
135+
uint64_t nanos_start;
135136
};
136137

137138

diskimagebuild/filetree.cpp

+45-14
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ File::File(const char* path)
2020
rewind(f);
2121

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

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

8593
auto* dir = opendir(cwd_buffer);
86-
if (dir == nullptr)
87-
{
88-
printf("Could not open directory:\n-> %s\n", cwd_buffer);
89-
return;
94+
// throw immediately when unable to open directory
95+
if (dir == nullptr) {
96+
fprintf(stderr, "Unable to open directory %s\n", cwd_buffer);
97+
throw std::runtime_error("Unable to open directory " + std::string(cwd_buffer));
9098
}
99+
100+
std::vector<std::string> sub_dirs;
101+
std::vector<std::string> sub_files;
102+
91103
struct dirent* ent;
92104
while ((ent = readdir(dir)) != nullptr)
93105
{
94106
std::string name(ent->d_name);
95107
if (name == ".." || name == ".") continue;
96108

97109
if (ent->d_type == DT_DIR) {
98-
auto& d = dvec.add_dir(ent->d_name);
99-
add_dir(d);
110+
sub_dirs.push_back(std::move(name));
100111
}
101112
else {
102-
try {
103-
dvec.add_file(ent->d_name);
104-
} catch (std::exception& e) {
105-
fprintf(stderr, "%s\n", e.what());
106-
}
113+
sub_files.push_back(std::move(name));
107114
}
108115
}
116+
// close directory before adding more folders and files
117+
res = closedir(dir);
118+
if (res < 0) {
119+
throw std::runtime_error("diskbuilder: Failed to close directory");
120+
}
121+
122+
// add sub directories
123+
for (const auto& dirname : sub_dirs) {
124+
auto& d = dvec.add_dir(dirname.c_str());
125+
add_dir(d);
126+
}
127+
// add files in current directory
128+
for (const auto& filename : sub_files)
129+
{
130+
try {
131+
dvec.add_file(filename.c_str());
132+
} catch (std::exception& e) {
133+
fprintf(stderr, "%s\n", e.what());
134+
}
135+
}
136+
109137
// pop work dir
110-
chdir(pwd_buffer);
138+
res = chdir(pwd_buffer);
139+
if (res < 0) {
140+
throw std::runtime_error("diskbuilder: Failed to return back to parent directory");
141+
}
111142
}
112143

113144
void FileSys::gather(const char* path)

examples/IRCd/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ set(LOCAL_INCLUDES "")
4040
set(DRIVERS
4141
virtionet
4242
vmxnet3
43+
#boot_logger
4344
)
4445

4546
set (PLUGINS

examples/IRCd/service.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,19 @@
1818
#include <os>
1919
#include <profile>
2020
#include <timers>
21+
#include <sys/time.h>
2122
#define USE_STACK_SAMPLING
2223
#define PERIOD_SECS 4
2324

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

2729
void Service::start()
2830
{
2931
// run a small self-test to verify parser is sane
3032
extern void selftest(); selftest();
31-
33+
3234
ircd = IrcServer::from_config();
3335

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

139-
using namespace std::chrono;
140141
Timers::periodic(seconds(1), seconds(PERIOD_SECS), print_stats);
142+
143+
// profiler statistics
144+
printf("%s\n", ScopedProfiler::get_statistics(false).c_str());
141145
}

examples/IRCd/vm.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"image" : "IRCd",
3-
"net" : [{"device" : "vmxnet3"}],
3+
"net" : [{"device" : "virtio"}],
44
"mem" : 1024
55
}

examples/STREAM/service.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
double mysecond()
2222
{
23-
return OS::micros_since_boot() / 1000000.f;
23+
return OS::nanos_since_boot() / 1.0e9;
2424
}
2525

2626
void Service::start()

examples/TCP_perf/service.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ void start_measure()
6464
packets_tx = Statman::get().get_by_name("eth0.ethernet.packets_tx").get_uint64();
6565
printf("<Settings> DACK: %lli ms WSIZE: %u WS: %u CALC_WIN: %u TS: %s\n",
6666
dack.count(), winsize, wscale, winsize << wscale, timestamps ? "ON" : "OFF");
67-
ts = OS::micros_since_boot();
67+
ts = OS::nanos_since_boot();
6868
activity_before.reset();
6969
}
7070

7171
void stop_measure()
7272
{
73-
auto diff = OS::micros_since_boot() - ts;
73+
auto diff = OS::nanos_since_boot() - ts;
7474
activity_after.reset();
7575

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

0 commit comments

Comments
 (0)