stacktor.hpp:40:13: note: the value of the stack pointer after an ‘asm’ statement must be the same as it was before the statement
This commit is contained in:
commit
2c312ff1f4
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.out
|
||||
.gdb_history
|
34
main.cpp
Normal file
34
main.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
// @BAKE g++ $@ -o stacktor.out -ggdb -O0
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "stacktor.hpp"
|
||||
|
||||
void print_stractor(stacktor<int> &s) {
|
||||
fputs("[ ", stdout);
|
||||
/*
|
||||
for (auto i : s) {
|
||||
printf("%d ", i);
|
||||
}
|
||||
*/
|
||||
for (int i = 0; i < s.size(); i++) {
|
||||
printf("%d ", s.get(i));
|
||||
}
|
||||
fputc(']', stdout);
|
||||
}
|
||||
|
||||
signed main() {
|
||||
// It MUST be on the heap
|
||||
stacktor<int> * s = new stacktor<int>();
|
||||
|
||||
puts("");
|
||||
s->push_back(10);
|
||||
puts("");
|
||||
s->push_back(12);
|
||||
puts("");
|
||||
s->push_back(6);
|
||||
puts("");
|
||||
print_stractor(*s);
|
||||
|
||||
return 0;
|
||||
}
|
130
stacktor.hpp
Normal file
130
stacktor.hpp
Normal file
@ -0,0 +1,130 @@
|
||||
#include <thread>
|
||||
#include <functional>
|
||||
|
||||
#ifndef DEBUG
|
||||
# define DEBUG 0
|
||||
#endif
|
||||
|
||||
#if DEBUG == 1
|
||||
# define DEBUG_PRINT(x) do { puts(x); fflush(stdout); } while (0)
|
||||
#else
|
||||
# define DEBUG_PRINT(x) do { ; } while (0)
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
class stacktor {
|
||||
private:
|
||||
std::thread provider;
|
||||
T data_swap;
|
||||
T * data = nullptr;
|
||||
size_t current_size = 0;
|
||||
size_t request = -1;
|
||||
size_t order = -1;
|
||||
bool do_exit = false;
|
||||
|
||||
int lock = 0;
|
||||
|
||||
void bahaha() {
|
||||
int data_size = sizeof(T);
|
||||
|
||||
asm (
|
||||
"movq %%rsp, %0;"
|
||||
: "=r" (data)
|
||||
:
|
||||
:
|
||||
);
|
||||
|
||||
goto pass;
|
||||
|
||||
start:
|
||||
asm volatile (
|
||||
"sub %%rsp, %0;"
|
||||
:
|
||||
: "" (data_size)
|
||||
);
|
||||
DEBUG_PRINT("Element allocated.");
|
||||
--lock;
|
||||
|
||||
pass:
|
||||
DEBUG_PRINT("Locking.");
|
||||
while (not lock) {
|
||||
if (request != -1) {
|
||||
data_swap = data[-request];
|
||||
request = -1;
|
||||
DEBUG_PRINT("Data request satisfied.");
|
||||
}
|
||||
if (order != -1) {
|
||||
data[-order] = data_swap;
|
||||
order = -1;
|
||||
DEBUG_PRINT("Data order satisfied.");
|
||||
}
|
||||
if (do_exit) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
goto start;
|
||||
}
|
||||
|
||||
public:
|
||||
stacktor() : provider(std::bind(&stacktor::bahaha, this)) {
|
||||
DEBUG_PRINT("Waiting for data field initialization...");
|
||||
while (not data);
|
||||
DEBUG_PRINT("Stacktor initialized.");
|
||||
}
|
||||
|
||||
//stacktor(const stacktor& other);
|
||||
|
||||
//stacktor(stacktor&& other) noexcept;
|
||||
|
||||
~stacktor() {
|
||||
do_exit = true;
|
||||
provider.join();
|
||||
}
|
||||
|
||||
//stacktor& operator=(const stacktor& other);
|
||||
|
||||
//stacktor& operator=(stacktor&& other) noexcept;
|
||||
|
||||
void push_back(const T& value) {
|
||||
DEBUG_PRINT("Push initiated...");
|
||||
lock = 1;
|
||||
while (lock);
|
||||
this->set(this->current_size, value);
|
||||
this->current_size += 1;
|
||||
}
|
||||
|
||||
void pop_back() {
|
||||
--current_size;
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return this->current_size;
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
return (this->size() == 0);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
current_size = 0;
|
||||
}
|
||||
|
||||
T& get(size_t index) {
|
||||
DEBUG_PRINT("Request initiated...");
|
||||
|
||||
request = index;
|
||||
while (request != -1);
|
||||
DEBUG_PRINT("Response recieved.");
|
||||
return data_swap;
|
||||
}
|
||||
|
||||
void set(size_t index, T value) {
|
||||
DEBUG_PRINT("Data order initiated...");
|
||||
|
||||
data_swap = value;
|
||||
order = index;
|
||||
while (order != -1);
|
||||
DEBUG_PRINT("Data order followed.");
|
||||
return;
|
||||
}
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user