fix task node leaks

This commit is contained in:
2023-10-24 22:29:12 +02:00
parent b44cb7cc68
commit 389582b7a5
6 changed files with 41 additions and 22 deletions

View File

@@ -60,17 +60,17 @@ void freeprinter() {
char buf[69];
while (1) {
all_tty_putstr("=====\n");
itoa(get_free(), buf, 10);
itoa(get_free() * 1024, buf, 10);
all_tty_putstr("Free mem: ");
all_tty_putstr(buf);
write_serial('\n');
itoa(get_heap_allocated() / 1024, buf, 10);
itoa(get_heap_allocated(), buf, 10);
all_tty_putstr("Heap allocated: ");
all_tty_putstr(buf);
write_serial('\n');
itoa(get_heap_used() / 1024, buf, 10);
itoa(get_heap_used(), buf, 10);
all_tty_putstr("Heap used: ");
all_tty_putstr(buf);
write_serial('\n');

View File

@@ -34,11 +34,11 @@ List<Task *> NextTasks;
// Task freer
Spinlock TasksToFree_lock;
List<Task *> TasksToFree;
List<List<Task *>::Node *> TasksToFree;
// Waiting
Spinlock WaitingTasks_lock;
SkipList<uint64_t, Task *> WaitingTasks;
SkipList<uint64_t, List<Task *>::Node *> WaitingTasks;
static std::atomic<bool> initialized = false;
@@ -55,9 +55,10 @@ static void task_freer() {
{
LockGuard l(TasksToFree_lock);
while (!TasksToFree.empty()) {
auto t = TasksToFree.back();
List<Task *>::Node *t = TasksToFree.back();
TasksToFree.pop_back();
free_task(t);
free_task(t->val);
delete t;
}
}
}
@@ -100,7 +101,8 @@ struct Task *new_ktask(void (*fn)(), const char *name) {
void remove_self() {
{
LockGuard l(TasksToFree_lock);
TasksToFree.emplace_front(cur_task());
assert(RunningTask != nullptr);
TasksToFree.emplace_front(RunningTask);
NextTasks_lock.lock();
RunningTask->val->state = TS_BLOCKED;
}
@@ -117,12 +119,13 @@ void sleep_self(uint64_t diff) {
// TODO this is all ugly
uint64_t l1 = 0;
for(auto cur = &*WaitingTasks.begin(); !cur->end; cur=cur->next[0])l1++;
for (auto cur = &*WaitingTasks.begin(); !cur->end; cur = cur->next[0]) l1++;
assert(WaitingTasks.add(wake_time, cur_task()) != nullptr);
assert(RunningTask != nullptr);
assert(WaitingTasks.add(wake_time, RunningTask) != nullptr);
uint64_t l2 = 0;
for(auto cur = &*WaitingTasks.begin(); !cur->end; cur=cur->next[0])l2++;
for (auto cur = &*WaitingTasks.begin(); !cur->end; cur = cur->next[0]) l2++;
assert(l2 - l1 == 1);
NextTasks_lock.lock();
@@ -146,27 +149,26 @@ static void task_waker() {
{
LockGuard l(WaitingTasks_lock);
while (WaitingTasks.begin() != WaitingTasks.end() && WaitingTasks.begin()->key <= micros && WaitingTasks.begin()->data->state != TS_RUNNING) {
while (WaitingTasks.begin() != WaitingTasks.end() && WaitingTasks.begin()->key <= micros && WaitingTasks.begin()->data->val->state != TS_RUNNING) {
auto *node = &*WaitingTasks.begin();
auto task = WaitingTasks.begin()->data;
// TODO this is all ugly
uint64_t l1 = 0;
for(auto cur = node; !cur->end; cur=cur->next[0])l1++;
for (auto cur = node; !cur->end; cur = cur->next[0]) l1++;
WaitingTasks.erase(node, node->next[0], false);
uint64_t l2 = 0;
for(auto *cur = &*WaitingTasks.begin(); !cur->end; cur=cur->next[0])l2++;
for (auto *cur = &*WaitingTasks.begin(); !cur->end; cur = cur->next[0]) l2++;
assert(l1 - l2 == 1);
task->sleep_until = 0;
task->state = TS_RUNNING;
task->val->sleep_until = 0;
task->val->state = TS_RUNNING;
auto new_node = NextTasks.create_node(task);
{
LockGuard l(NextTasks_lock);
NextTasks.emplace_front(new_node);
NextTasks.emplace_front(task);
}
}
}
@@ -237,7 +239,20 @@ void unblock(Task *what) {
}
};
void unblock(List<Task *>::Node *what) {
what->val->state = TS_RUNNING;
{
LockGuard l(NextTasks_lock);
NextTasks.emplace_front(what);
}
};
struct Task *cur_task() {
if (!RunningTask) return NULL;
return RunningTask->val;
}
List<Task *>::Node *extract_running_task_node() {
if (!RunningTask) return nullptr;
return RunningTask;
}

View File

@@ -5,6 +5,7 @@
#ifndef OS1_TASK_H
#define OS1_TASK_H
#include "List.hpp"
#include "idt.hpp"
#define TASK_SS 16384
@@ -33,18 +34,19 @@ struct Task {
};
struct Task *cur_task();
List<Task *>::Node *extract_running_task_node();
void init_tasks();
struct Task *new_ktask(void (*fn)(), const char *name);
void remove_self();
void sleep_self(uint64_t diff);
void self_block();
class Spinlock;
void self_block(Spinlock &to_unlock);
void unblock(Task *what);
void unblock(List<Task *>::Node *what);
extern "C" void switch_task(struct task_frame *cur_frame);

View File

@@ -15,6 +15,8 @@ public:
lock->unlock();
}
LockGuard(LockGuard const &d) = delete;
private:
T *lock;
};

View File

@@ -54,7 +54,7 @@ void Mutex::lock() {
while (!Mutex::try_lock()) {
waiters_lock.lock();
waiters.emplace_front(cur_task());
waiters.emplace_front(extract_running_task_node());
self_block(waiters_lock);
}
}
@@ -64,7 +64,7 @@ void Mutex::unlock() {
bool expected = true;
if (!locked.compare_exchange_strong(expected, false))
writestr("Unlocking an unlocked mutex!\n");
Task *t = nullptr;
List<Task *>::Node *t = nullptr;
{
LockGuard l(waiters_lock);
if (!waiters.empty()) {

View File

@@ -28,7 +28,7 @@ public:
private:
std::atomic<bool> locked = false;
List<Task *> waiters; // leaking List<Task *>::Node
List<List<Task *>::Node *> waiters;
Spinlock waiters_lock;
Task *owner = nullptr;