Remove mutex from SmallStack/StationIDStack.
It is only ever used from the main thread.
This commit is contained in:
@@ -13,7 +13,6 @@
|
|||||||
#define SMALLSTACK_TYPE_HPP
|
#define SMALLSTACK_TYPE_HPP
|
||||||
|
|
||||||
#include "smallvec_type.hpp"
|
#include "smallvec_type.hpp"
|
||||||
#include "../thread/thread.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simplified pool which stores values instead of pointers and doesn't
|
* A simplified pool which stores values instead of pointers and doesn't
|
||||||
@@ -23,15 +22,7 @@
|
|||||||
template<typename Titem, typename Tindex, Tindex Tgrowth_step, Tindex Tmax_size>
|
template<typename Titem, typename Tindex, Tindex Tgrowth_step, Tindex Tmax_size>
|
||||||
class SimplePool {
|
class SimplePool {
|
||||||
public:
|
public:
|
||||||
inline SimplePool() : first_unused(0), first_free(0), mutex(ThreadMutex::New()) {}
|
inline SimplePool() : first_unused(0), first_free(0) {}
|
||||||
inline ~SimplePool() { delete this->mutex; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the mutex. We don't lock the mutex in the pool methods as the
|
|
||||||
* SmallStack isn't necessarily in a consistent state after each method.
|
|
||||||
* @return Mutex.
|
|
||||||
*/
|
|
||||||
inline ThreadMutex *GetMutex() { return this->mutex; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the item at position index.
|
* Get the item at position index.
|
||||||
@@ -86,7 +77,6 @@ private:
|
|||||||
Tindex first_unused;
|
Tindex first_unused;
|
||||||
Tindex first_free;
|
Tindex first_free;
|
||||||
|
|
||||||
ThreadMutex *mutex;
|
|
||||||
SmallVector<SimplePoolPoolItem, Tgrowth_step> data;
|
SmallVector<SimplePoolPoolItem, Tgrowth_step> data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -124,10 +114,8 @@ struct SmallStackItem {
|
|||||||
* 5. You can choose your own index type, so that you can align it with your
|
* 5. You can choose your own index type, so that you can align it with your
|
||||||
* value type. E.G. value types of 16 bits length like to be combined with
|
* value type. E.G. value types of 16 bits length like to be combined with
|
||||||
* index types of the same length.
|
* index types of the same length.
|
||||||
* 6. All accesses to the underlying pool are guarded by a mutex and atomic in
|
* 6. This data structure is only ever used from the main thread, so
|
||||||
* the sense that the mutex stays locked until the pool has reacquired a
|
* accesses to the underlying pool are not guarded by locks.
|
||||||
* consistent state. This means that even though a common data structure is
|
|
||||||
* used the SmallStack is still reentrant.
|
|
||||||
* @tparam Titem Value type to be used.
|
* @tparam Titem Value type to be used.
|
||||||
* @tparam Tindex Index type to use for the pool.
|
* @tparam Tindex Index type to use for the pool.
|
||||||
* @tparam Tinvalid Invalid item to keep at the bottom of each stack.
|
* @tparam Tinvalid Invalid item to keep at the bottom of each stack.
|
||||||
@@ -195,7 +183,6 @@ public:
|
|||||||
inline void Push(const Titem &item)
|
inline void Push(const Titem &item)
|
||||||
{
|
{
|
||||||
if (this->value != Tinvalid) {
|
if (this->value != Tinvalid) {
|
||||||
ThreadMutexLocker lock(_pool.GetMutex());
|
|
||||||
Tindex new_item = _pool.Create();
|
Tindex new_item = _pool.Create();
|
||||||
if (new_item != Tmax_size) {
|
if (new_item != Tmax_size) {
|
||||||
PooledSmallStack &pushed = _pool.Get(new_item);
|
PooledSmallStack &pushed = _pool.Get(new_item);
|
||||||
@@ -218,17 +205,13 @@ public:
|
|||||||
if (this->next == Tmax_size) {
|
if (this->next == Tmax_size) {
|
||||||
this->value = Tinvalid;
|
this->value = Tinvalid;
|
||||||
} else {
|
} else {
|
||||||
ThreadMutexLocker lock(_pool.GetMutex());
|
|
||||||
PooledSmallStack &popped = _pool.Get(this->next);
|
PooledSmallStack &popped = _pool.Get(this->next);
|
||||||
this->value = popped.value;
|
this->value = popped.value;
|
||||||
if (popped.branch_count == 0) {
|
if (popped.branch_count == 0) {
|
||||||
_pool.Destroy(this->next);
|
_pool.Destroy(this->next);
|
||||||
} else {
|
} else {
|
||||||
--popped.branch_count;
|
--popped.branch_count;
|
||||||
/* We can't use Branch() here as we already have the mutex.*/
|
this->Branch();
|
||||||
if (popped.next != Tmax_size) {
|
|
||||||
++(_pool.Get(popped.next).branch_count);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* Accessing popped here is no problem as the pool will only set
|
/* Accessing popped here is no problem as the pool will only set
|
||||||
* the validity flag, not actually delete the item, on Destroy().
|
* the validity flag, not actually delete the item, on Destroy().
|
||||||
@@ -257,7 +240,6 @@ public:
|
|||||||
{
|
{
|
||||||
if (item == Tinvalid || item == this->value) return true;
|
if (item == Tinvalid || item == this->value) return true;
|
||||||
if (this->next != Tmax_size) {
|
if (this->next != Tmax_size) {
|
||||||
ThreadMutexLocker lock(_pool.GetMutex());
|
|
||||||
const SmallStack *in_list = this;
|
const SmallStack *in_list = this;
|
||||||
do {
|
do {
|
||||||
in_list = static_cast<const SmallStack *>(
|
in_list = static_cast<const SmallStack *>(
|
||||||
@@ -277,7 +259,6 @@ protected:
|
|||||||
inline void Branch()
|
inline void Branch()
|
||||||
{
|
{
|
||||||
if (this->next != Tmax_size) {
|
if (this->next != Tmax_size) {
|
||||||
ThreadMutexLocker lock(_pool.GetMutex());
|
|
||||||
++(_pool.Get(this->next).branch_count);
|
++(_pool.Get(this->next).branch_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user