Remove mutex from SmallStack/StationIDStack.

It is only ever used from the main thread.
This commit is contained in:
Jonathan G Rennison
2016-09-04 10:29:20 +01:00
parent e6c7134935
commit 8deac54c9f

View File

@@ -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);
} }
} }