Skip to content

Commit f9ea5bf

Browse files
authored
Merge pull request #1350 from fwsGonzo/dev
Enable stack sampling, update acorn
2 parents dea9b21 + d2ade65 commit f9ea5bf

9 files changed

Lines changed: 57 additions & 25 deletions

File tree

api/util/statman.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ class Statman {
127127
Stat& create(const Stat::Stat_type type, const std::string& name);
128128
// retrieve stat based on address from stats counter: &stat.get_xxx()
129129
Stat& get(const void* addr);
130+
// if you know the name of a statistic already
131+
Stat& get_by_name(const char* name);
130132
// free/delete stat based on address from stats counter
131133
void free(void* addr);
132134

cmake/library.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/settings.cmake)
3737
# Various global defines
3838
# * OS_TERMINATE_ON_CONTRACT_VIOLATION provides classic assert-like output from Expects / Ensures
3939
# * _GNU_SOURCE enables POSIX-extensions in newlib, such as strnlen. ("everything newlib has", ref. cdefs.h)
40-
set(CAPABS "${CAPABS} -fstack-protector-strong -DOS_TERMINATE_ON_CONTRACT_VIOLATION -D_GNU_SOURCE")
40+
set(CAPABS "${CAPABS} -mno-red-zone -fstack-protector-strong -DOS_TERMINATE_ON_CONTRACT_VIOLATION -D_GNU_SOURCE")
4141
set(WARNS "-Wall -Wextra") #-pedantic
4242

4343
# configure options

examples/acorn/service.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
// See the License for the specific language governing permissions and
1616
// limitations under the License.
1717

18-
#include <sstream>
19-
2018
#include <os>
2119
#include <acorn>
2220

@@ -123,7 +121,7 @@ void Service::start()
123121
dashboard_ = std::make_unique<dashboard::Dashboard>(8192);
124122
// Add singleton component
125123
dashboard_->add(dashboard::Memmap::instance());
126-
//dashboard_->add(dashboard::StackSampler::instance());
124+
dashboard_->add(dashboard::StackSampler::instance());
127125
dashboard_->add(dashboard::Status::instance());
128126
// Construct component
129127
dashboard_->construct<dashboard::Statman>(Statman::get());

src/arch/x86_64/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)
22

33
### x86_64 arch specific ###
44
set(ARCH_OBJECTS
5-
profile_intr.asm
65
apic_asm.asm
76
arch_start.asm
87
interrupts.asm

src/arch/x86_64/interrupts.asm

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,19 @@
1818
global unused_interrupt_handler:function
1919
global modern_interrupt_handler:function
2020
global cpu_sampling_irq_entry:function
21+
global parasite_interrupt_handler:function
22+
global __stack_storage_area
2123

2224
extern current_eoi_mechanism
2325
extern current_intr_handler
2426
extern cpu_sampling_irq_handler
27+
extern profiler_stack_sampler
2528

2629
SECTION .bss
2730
ALIGN 16
28-
xsave_storage_area: resb 512
31+
__xsave_storage_area: resb 512
2932
ALIGN 16
30-
stack_storage_area: resb 512
33+
__stack_storage_area: resb 512
3134

3235
%macro PUSHAQ 0
3336
push rax
@@ -46,11 +49,11 @@ stack_storage_area: resb 512
4649
push r15
4750

4851
; Preserve extended state
49-
fxsave [xsave_storage_area]
52+
;fxsave [__xsave_storage_area]
5053
%endmacro
5154
%macro POPAQ 0
5255
; Restore extended state
53-
fxrstor [xsave_storage_area]
56+
;fxrstor [__xsave_storage_area]
5457

5558
pop r15
5659
pop r14
@@ -70,7 +73,7 @@ stack_storage_area: resb 512
7073

7174
%macro SPSAVE 0
7275
mov rax, rsp
73-
mov rsp, stack_storage_area+512-16
76+
mov rsp, __stack_storage_area+512-16
7477
push rax ;; save old RSP
7578
push rbp
7679
%endmacro
@@ -111,3 +114,15 @@ cpu_sampling_irq_entry:
111114
POPAQ
112115
sti
113116
iretq
117+
118+
parasite_interrupt_handler:
119+
cli
120+
PUSHAQ
121+
mov rdi, QWORD [rsp + 8*14]
122+
SPSAVE
123+
call profiler_stack_sampler
124+
call QWORD [current_intr_handler]
125+
SPRSTOR
126+
POPAQ
127+
sti
128+
iretq

src/arch/x86_64/profile_intr.asm

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,10 @@ extern profiler_stack_sampler
5858
parasite_interrupt_handler:
5959
cli
6060
PUSHAQ
61-
push QWORD [rsp + 32]
61+
mov rax, rsp
62+
push rsp
63+
mov rsi, QWORD [rsp + 32]
6264
call profiler_stack_sampler
63-
pop rax
6465
call QWORD [current_intr_handler]
6566
POPAQ
6667
sti

src/platform/x86_pc/pit.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,18 @@ namespace x86
8181

8282
void PIT::oneshot(milliseconds timeval, timeout_handler handler)
8383
{
84-
if (get().current_mode_ != RATE_GEN) {
84+
if (get().current_mode_ != RATE_GEN)
8585
get().set_mode(RATE_GEN);
86-
}
87-
8886
if (get().current_freq_divider_ != MILLISEC_INTERVAL)
8987
get().set_freq_divider(MILLISEC_INTERVAL);
9088

91-
get().expiration = now() + timeval;
92-
get().handler = handler;
93-
get().run_forever = timeval == milliseconds::zero();
89+
bool forever = timeval == milliseconds::zero();
90+
if (forever) {
91+
get().forev_handler = handler;
92+
} else {
93+
get().expiration = now() + timeval;
94+
get().handler = handler;
95+
}
9496
}
9597

9698
void PIT::forever(timeout_handler handler)
@@ -113,17 +115,20 @@ namespace x86
113115
{
114116
IRQ_counter ++;
115117

116-
if (now() >= this->expiration || run_forever)
118+
if (now() >= this->expiration)
117119
{
118-
// reset when not running forever
119-
if (this->run_forever == false)
120-
{
121-
disable_regular_interrupts();
122-
}
123120
if (this->handler) {
124121
this->handler();
125122
this->handler = nullptr;
126123
}
124+
// stop PIT when not running forever
125+
if (this->forev_handler == nullptr)
126+
disable_regular_interrupts();
127+
}
128+
// always call forever handler, if set
129+
if (this->forev_handler)
130+
{
131+
this->forev_handler();
127132
}
128133
}
129134

src/platform/x86_pc/pit.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ namespace x86
4343
@param handler: A delegate or function to be called on timeout. */
4444
static void oneshot(std::chrono::milliseconds ms, timeout_handler handler);
4545

46+
/** Run a custom handler forever */
4647
static void forever(timeout_handler handler);
4748

4849
/** Stop PIT interrupts */
@@ -81,12 +82,12 @@ namespace x86
8182

8283
// State-keeping
8384
uint16_t current_freq_divider_;
84-
bool run_forever;
8585
Mode current_mode_;
8686
int64_t IRQ_counter;
8787

8888
// Timer handler & expiration timestamp
8989
timeout_handler handler;
90+
timeout_handler forev_handler;
9091
std::chrono::milliseconds expiration;
9192

9293
// Access mode bits are bits 4- and 5 in the Mode register

src/util/statman.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,17 @@ Stat& Statman::get(const void* addr)
124124
throw std::out_of_range("Address out of range");
125125
}
126126

127+
Stat& Statman::get_by_name(const char* name)
128+
{
129+
for (auto* st = begin(); st < end(); st++)
130+
{
131+
if (st->unused() == false)
132+
if (strncmp(st->name(), name, Stat::MAX_NAME_LEN) == 0)
133+
return *st;
134+
}
135+
throw std::out_of_range("No stat found with exact given name");
136+
}
137+
127138
void Statman::free(void* addr)
128139
{
129140
auto& stat = this->get(addr);

0 commit comments

Comments
 (0)