1
0
Fork 0
mirror of https://github.com/VSadov/Satori.git synced 2025-06-09 17:44:48 +09:00

SatoriQueue

This commit is contained in:
vsadov 2020-07-31 12:07:12 -07:00
parent 6ad95a46f6
commit dc7a03e2c5
6 changed files with 149 additions and 138 deletions

View file

@ -110,6 +110,7 @@ if (CLR_CMAKE_TARGET_WIN32)
satori/SatoriRegion.inl
satori/SatoriObject.h
satori/SatoriObject.inl
satori/SatoriQueue.h
satori/SatoriRegionQueue.h
satori/SatoriAllocator.h
satori/SatoriRecycler.h

View file

@ -0,0 +1,144 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// TQueue.h
//
#ifndef __SATORI_QUEUE_H__
#define __SATORI_QUEUE_H__
#include "common.h"
#include "../gc.h"
#include "SatoriLock.h"
template<class T>
class SatoriQueue
{
public:
SatoriQueue() :
m_lock(), m_head(), m_tail()
{
m_lock.Initialize();
};
void Push(T* item)
{
SatoriLockHolder<SatoriLock> holder(&m_lock);
item->m_containingQueue = this;
if (m_head == nullptr)
{
_ASSERTE(m_tail == nullptr);
m_head = m_tail = item;
}
else
{
item->m_next = m_head;
m_head->m_prev = item;
m_head = item;
}
}
T* TryPop()
{
T* result;
{
SatoriLockHolder<SatoriLock> holder(&m_lock);
result = m_head;
if (result == nullptr)
{
return nullptr;
}
result->m_containingQueue = nullptr;
m_head = result->m_next;
if (m_head == nullptr)
{
m_tail = nullptr;
}
else
{
m_head->m_prev = nullptr;
}
}
_ASSERTE(result->m_prev == nullptr);
result->m_next = nullptr;
return result;
}
void Enqueue(T* item)
{
SatoriLockHolder<SatoriLock> holder(&m_lock);
item->m_containingQueue = this;
if (m_tail == nullptr)
{
_ASSERTE(m_head == nullptr);
m_head = m_tail = item;
}
else
{
item->m_prev = m_tail;
m_tail->m_next = item;
m_tail = item;
}
}
bool TryRemove(T* item)
{
{
SatoriLockHolder<SatoriLock> holder(&m_lock);
if (!Contains(item))
{
return false;
}
item->m_containingQueue = nullptr;
if (item->m_prev == nullptr)
{
m_head = item->m_next;
}
else
{
item->m_prev->m_next = item->m_next;
}
if (item->m_next == nullptr)
{
m_tail = item->m_prev;
}
else
{
item->m_next->m_prev = item->m_prev;
}
}
item->m_next = nullptr;
item->m_prev = nullptr;
return true;
}
bool Contains(T* item)
{
return item->m_containingQueue == this;
}
bool CanPop()
{
return m_head != nullptr;
}
bool CanDequeue()
{
return m_tail != nullptr;
}
protected:
SatoriLock m_lock;
T* m_head;
T* m_tail;
};
#endif

View file

@ -90,7 +90,7 @@ private:
SatoriRegion* m_prev;
SatoriRegion* m_next;
SatoriRegionQueue* m_containingQueue;
SatoriQueue<SatoriRegion>* m_containingQueue;
// active allocation may happen in the following range.
// the range may not be parseable as sequence of objects

View file

@ -15,74 +15,6 @@
#include "SatoriRegion.h"
#include "SatoriRegion.inl"
void SatoriRegionQueue::Push(SatoriRegion* region)
{
_ASSERTE(region->ValidateBlank());
SatoriLockHolder<SatoriLock> holder(&m_lock);
region->m_containingQueue = this;
if (m_head == nullptr)
{
_ASSERTE(m_tail == nullptr);
m_head = m_tail = region;
}
else
{
region->m_next = m_head;
m_head->m_prev = region;
m_head = region;
}
}
void SatoriRegionQueue::Enqueue(SatoriRegion* region)
{
_ASSERTE(region->ValidateBlank());
SatoriLockHolder<SatoriLock> holder(&m_lock);
region->m_containingQueue = this;
if (m_tail == nullptr)
{
_ASSERTE(m_head == nullptr);
m_head = m_tail = region;
}
else
{
region->m_prev = m_tail;
m_tail->m_next = region;
m_tail = region;
}
}
SatoriRegion* SatoriRegionQueue::TryPop()
{
SatoriRegion* result;
{
SatoriLockHolder<SatoriLock> holder(&m_lock);
result = m_head;
if (result == nullptr)
{
return nullptr;
}
result->m_containingQueue = nullptr;
m_head = result->m_next;
if (m_head == nullptr)
{
m_tail = nullptr;
}
else
{
m_head->m_prev = nullptr;
}
}
_ASSERTE(result->m_prev == nullptr);
result->m_next = nullptr;
_ASSERTE(result->ValidateBlank());
return result;
}
SatoriRegion* SatoriRegionQueue::TryPop(size_t regionSize, SatoriRegion*& putBack)
{
m_lock.Enter();
@ -218,42 +150,3 @@ SatoriRegion* SatoriRegionQueue::TryRemove(size_t regionSize, SatoriRegion*& put
return result;
}
bool SatoriRegionQueue::Contains(SatoriRegion* region)
{
return region->m_containingQueue == this;
}
bool SatoriRegionQueue::TryRemove(SatoriRegion* region)
{
{
SatoriLockHolder<SatoriLock> holder(&m_lock);
if (!Contains(region))
{
return false;
}
region->m_containingQueue = nullptr;
if (region->m_prev == nullptr)
{
m_head = region->m_next;
}
else
{
region->m_prev->m_next = region->m_next;
}
if (region->m_next == nullptr)
{
m_tail = region->m_prev;
}
else
{
region->m_next->m_prev = region->m_prev;
}
}
region->m_next = nullptr;
region->m_prev = nullptr;
return true;
}

View file

@ -10,43 +10,15 @@
#include "common.h"
#include "../gc.h"
#include "SatoriLock.h"
#include "SatoriQueue.h"
class SatoriRegion;
class SatoriRegionQueue
class SatoriRegionQueue : public SatoriQueue<SatoriRegion>
{
public:
SatoriRegion* TryPop();
SatoriRegion* TryPop(size_t regionSize, SatoriRegion* &putBack);
bool TryRemove(SatoriRegion* region);
SatoriRegion* TryRemove(size_t regionSize, SatoriRegion*& putBack);
void Push(SatoriRegion* region);
void Enqueue(SatoriRegion* region);
bool Contains(SatoriRegion* region);
SatoriRegionQueue() :
m_lock(), m_head(), m_tail()
{
m_lock.Initialize();
};
bool CanPop()
{
return m_head != nullptr;
}
bool CanDequeue()
{
return m_tail != nullptr;
}
private:
SatoriLock m_lock;
SatoriRegion* m_head;
SatoriRegion* m_tail;
};
#endif

View file

@ -547,6 +547,7 @@ set(GC_HEADERS_WKS
../gc/satori/SatoriRegion.inl
../gc/satori/SatoriObject.h
../gc/satori/SatoriObject.inl
../gc/satori/SatoriQueue.h
../gc/satori/SatoriRegionQueue.h
../gc/satori/SatoriAllocator.h
../gc/satori/SatoriRecycler.h