61 lines
1.6 KiB
C++
61 lines
1.6 KiB
C++
// SPDX-License-Identifier: AGPL-1.0-only
|
|
// Copyright (C) 2018 Ludvig Strigeus <info@tunsafe.com>. All Rights Reserved.
|
|
#include "stdafx.h"
|
|
#include "tunsafe_threading.h"
|
|
#include <stdlib.h>
|
|
|
|
MultithreadedDelayedDelete::MultithreadedDelayedDelete() {
|
|
table_ = NULL;
|
|
num_threads_ = 0;
|
|
}
|
|
|
|
MultithreadedDelayedDelete::~MultithreadedDelayedDelete() {
|
|
assert(curr_.size() == 0);
|
|
assert(next_.size() == 0);
|
|
assert(to_delete_.size() == 0);
|
|
free(table_);
|
|
}
|
|
|
|
void MultithreadedDelayedDelete::Configure(uint32 num_threads) {
|
|
assert(table_ == NULL);
|
|
num_threads_ = num_threads;
|
|
table_ = (CheckpointData*)calloc(sizeof(CheckpointData), num_threads);
|
|
}
|
|
|
|
void MultithreadedDelayedDelete::Add(DoDeleteFunc *func, void *param) {
|
|
if (num_threads_ == 0) {
|
|
func(param);
|
|
return;
|
|
}
|
|
lock_.Acquire();
|
|
Entry e = {func, param};
|
|
curr_.push_back(e);
|
|
lock_.Release();
|
|
}
|
|
|
|
void MultithreadedDelayedDelete::Checkpoint(uint32 thread_id) {
|
|
table_[thread_id].value.store(1);
|
|
}
|
|
|
|
void MultithreadedDelayedDelete::MainCheckpoint() {
|
|
// Wait for all threads to signal that they reached the checkpoint
|
|
for (size_t i = 0; i < num_threads_; i++) {
|
|
if (table_[i].value.load() == 0)
|
|
return;
|
|
}
|
|
|
|
// All threads reached the checkpoint, clear the values
|
|
for (size_t i = 0; i < num_threads_; i++)
|
|
table_[i].value.store(0);
|
|
|
|
// Swap curr and next, and delete all nexts.
|
|
lock_.Acquire();
|
|
std::swap(curr_, next_);
|
|
std::swap(curr_, to_delete_);
|
|
lock_.Release();
|
|
|
|
for (auto it = to_delete_.begin(); it != to_delete_.end(); ++it) {
|
|
it->func(it->param);
|
|
}
|
|
to_delete_.clear();
|
|
}
|