mirror of
https://github.com/intel/llvm.git
synced 2026-01-14 11:57:39 +08:00
115 lines
3.2 KiB
C
115 lines
3.2 KiB
C
|
|
//===-- PerThreadTable.h -- PerThread Storage Structure ----*- C++ -*-===//
|
||
|
|
//
|
||
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
||
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||
|
|
//
|
||
|
|
//===----------------------------------------------------------------------===//
|
||
|
|
//
|
||
|
|
// Table indexed with one entry per thread.
|
||
|
|
//
|
||
|
|
//===----------------------------------------------------------------------===//
|
||
|
|
|
||
|
|
#ifndef OFFLOAD_PERTHREADTABLE_H
|
||
|
|
#define OFFLOAD_PERTHREADTABLE_H
|
||
|
|
|
||
|
|
#include <list>
|
||
|
|
#include <memory>
|
||
|
|
#include <mutex>
|
||
|
|
|
||
|
|
// Using an STL container (such as std::vector) indexed by thread ID has
|
||
|
|
// too many race conditions issues so we store each thread entry into a
|
||
|
|
// thread_local variable.
|
||
|
|
// T is the container type used to store the objects, e.g., std::vector,
|
||
|
|
// std::set, etc. by each thread. O is the type of the stored objects e.g.,
|
||
|
|
// omp_interop_val_t *, ...
|
||
|
|
|
||
|
|
template <typename ContainerType, typename ObjectType> struct PerThreadTable {
|
||
|
|
using iterator = typename ContainerType::iterator;
|
||
|
|
|
||
|
|
struct PerThreadData {
|
||
|
|
size_t NElements = 0;
|
||
|
|
std::unique_ptr<ContainerType> ThEntry;
|
||
|
|
};
|
||
|
|
|
||
|
|
std::mutex Mtx;
|
||
|
|
std::list<std::shared_ptr<PerThreadData>> ThreadDataList;
|
||
|
|
|
||
|
|
// define default constructors, disable copy and move constructors
|
||
|
|
PerThreadTable() = default;
|
||
|
|
PerThreadTable(const PerThreadTable &) = delete;
|
||
|
|
PerThreadTable(PerThreadTable &&) = delete;
|
||
|
|
PerThreadTable &operator=(const PerThreadTable &) = delete;
|
||
|
|
PerThreadTable &operator=(PerThreadTable &&) = delete;
|
||
|
|
~PerThreadTable() {
|
||
|
|
std::lock_guard<std::mutex> Lock(Mtx);
|
||
|
|
ThreadDataList.clear();
|
||
|
|
}
|
||
|
|
|
||
|
|
private:
|
||
|
|
PerThreadData &getThreadData() {
|
||
|
|
static thread_local std::shared_ptr<PerThreadData> ThData = nullptr;
|
||
|
|
if (!ThData) {
|
||
|
|
ThData = std::make_shared<PerThreadData>();
|
||
|
|
std::lock_guard<std::mutex> Lock(Mtx);
|
||
|
|
ThreadDataList.push_back(ThData);
|
||
|
|
}
|
||
|
|
return *ThData;
|
||
|
|
}
|
||
|
|
|
||
|
|
protected:
|
||
|
|
ContainerType &getThreadEntry() {
|
||
|
|
auto &ThData = getThreadData();
|
||
|
|
if (ThData.ThEntry)
|
||
|
|
return *ThData.ThEntry;
|
||
|
|
ThData.ThEntry = std::make_unique<ContainerType>();
|
||
|
|
return *ThData.ThEntry;
|
||
|
|
}
|
||
|
|
|
||
|
|
size_t &getThreadNElements() {
|
||
|
|
auto &ThData = getThreadData();
|
||
|
|
return ThData.NElements;
|
||
|
|
}
|
||
|
|
|
||
|
|
public:
|
||
|
|
void add(ObjectType obj) {
|
||
|
|
auto &Entry = getThreadEntry();
|
||
|
|
auto &NElements = getThreadNElements();
|
||
|
|
NElements++;
|
||
|
|
Entry.add(obj);
|
||
|
|
}
|
||
|
|
|
||
|
|
iterator erase(iterator it) {
|
||
|
|
auto &Entry = getThreadEntry();
|
||
|
|
auto &NElements = getThreadNElements();
|
||
|
|
NElements--;
|
||
|
|
return Entry.erase(it);
|
||
|
|
}
|
||
|
|
|
||
|
|
size_t size() { return getThreadNElements(); }
|
||
|
|
|
||
|
|
// Iterators to traverse objects owned by
|
||
|
|
// the current thread
|
||
|
|
iterator begin() {
|
||
|
|
auto &Entry = getThreadEntry();
|
||
|
|
return Entry.begin();
|
||
|
|
}
|
||
|
|
iterator end() {
|
||
|
|
auto &Entry = getThreadEntry();
|
||
|
|
return Entry.end();
|
||
|
|
}
|
||
|
|
|
||
|
|
template <class F> void clear(F f) {
|
||
|
|
std::lock_guard<std::mutex> Lock(Mtx);
|
||
|
|
for (auto ThData : ThreadDataList) {
|
||
|
|
if (!ThData->ThEntry || ThData->NElements == 0)
|
||
|
|
continue;
|
||
|
|
ThData->ThEntry->clear(f);
|
||
|
|
ThData->NElements = 0;
|
||
|
|
}
|
||
|
|
ThreadDataList.clear();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
#endif
|