-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathuintr.h
134 lines (100 loc) · 3.19 KB
/
uintr.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#pragma once
#include <unistd.h>
#include <x86gprintrin.h>
#include <cstdint>
#include <pthread.h>
#include <stdlib.h>
#include <malloc.h>
#include <unordered_map>
#include <mutex>
#include <atomic>
#ifndef __NR_uintr_register_handler
#define __NR_uintr_register_handler 471
#define __NR_uintr_unregister_handler 472
#define __NR_uintr_create_fd 473
#define __NR_uintr_register_sender 474
#define __NR_uintr_unregister_sender 475
#define __NR_uintr_wait 476
#endif
#define uintr_register_handler(handler, flags) syscall(__NR_uintr_register_handler, handler, flags)
#define uintr_unregister_handler(flags) syscall(__NR_uintr_unregister_handler, flags)
#define uintr_create_fd(vector, flags) syscall(__NR_uintr_create_fd, vector, flags)
#define uintr_register_sender(fd, flags) syscall(__NR_uintr_register_sender, fd, flags)
#define uintr_unregister_sender(ipi_idx, flags) syscall(__NR_uintr_unregister_sender, ipi_idx, flags)
#define uintr_wait(flags) syscall(__NR_uintr_wait, flags)
#define NUM_CONTEXTS 2
#define MAX_CORES 64
// #define SPACE
// #define mymalloc malloc SPACE
// #define myfree free SPACE
// #define malloc(size) ({ \
// pcontext::lock(); \
// void* p = mymalloc(size); \
// pcontext::unlock(); \
// p; \
// })
// #define free(p) do { \
// pcontext::lock(); \
// myfree(p); \
// pcontext::unlock(); \
// } while (0)
// Spinlock class definition
class Spinlock {
std::atomic_flag flag = ATOMIC_FLAG_INIT;
public:
void lock() {
while (flag.test_and_set(std::memory_order_acquire)) {
// Busy-wait loop
}
}
bool try_lock() {
return !flag.test_and_set(std::memory_order_acquire);
}
void unlock() {
flag.clear(std::memory_order_release);
}
};
struct alignas(64) pcontext {
pcontext();
char xsave_area[8192];
void *reg[1]; // reg[0] = rsp
void *context_data_oid;
bool xid_epoch_context_initialized = false;
bool new_context = false;
uint64_t stack_start;
uint64_t stack_end;
uint64_t fs;
uint64_t gs;
uint64_t start_timestamp;
uint64_t preempted_cycles;
void SetRSP(void *rsp);
bool ValidRSP(void *rsp);
void xsave();
void xrstor();
void reset_timer();
void add_preempted_time(uint64_t cycles);
bool starved();
static pcontext* get_current_context();
static void set_current_context(pcontext* ctx);
static void Set_Worker_Id(uint32_t id);
static uint64_t get_lock_counter();
static void set_lock_counter(uint64_t counter);
static bool locked();
static void lock();
static void unlock();
};
extern pcontext* curr_ctx[MAX_CORES];
uint32_t GetWorkerId();
extern "C" void* handler_helper(void* rsp);
extern "C" void* init_stack(void* st, void* fn) asm("init_stack");
extern "C" void __attribute__((interrupt)) __attribute__((noinline))
__attribute__((target("general-regs-only", "inline-all-stringops")))
interrupt_handler_func(struct __uintr_frame *ui_frame, unsigned long long vector);
extern "C" void swap_context(void *current_context, void *next_context) asm("swap_context");
// inline void *operator new (size_t size) {
// void *p = malloc(size);
// return p;
// }
// inline void operator delete (void *p) noexcept {
// free(p);
// }