Optimize thread ready queue pop_front().
This commit is contained in:
parent
04d4022c73
commit
543dfcd4d8
1 changed files with 46 additions and 10 deletions
|
@ -431,30 +431,38 @@ public:
|
||||||
u32 stackBlock;
|
u32 stackBlock;
|
||||||
};
|
};
|
||||||
|
|
||||||
// std::vector<SceUID> with push_front(), remove(), etc.
|
|
||||||
struct ThreadList
|
struct ThreadList
|
||||||
{
|
{
|
||||||
|
static const int START_PAD = 0x10;
|
||||||
|
size_t start;
|
||||||
std::vector<SceUID> list;
|
std::vector<SceUID> list;
|
||||||
|
|
||||||
|
ThreadList() : start(START_PAD)
|
||||||
|
{
|
||||||
|
list.resize(START_PAD);
|
||||||
|
}
|
||||||
|
|
||||||
inline bool empty() const
|
inline bool empty() const
|
||||||
{
|
{
|
||||||
return list.empty();
|
return start == list.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t size() const
|
inline size_t size() const
|
||||||
{
|
{
|
||||||
return list.size();
|
return list.size() - start;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline SceUID &front()
|
inline SceUID &front()
|
||||||
{
|
{
|
||||||
return list.front();
|
return list[start];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void push_front(const SceUID threadID)
|
inline void push_front(const SceUID threadID)
|
||||||
{
|
{
|
||||||
if (empty())
|
if (empty())
|
||||||
push_back(threadID);
|
push_back(threadID);
|
||||||
|
else if (start > 0)
|
||||||
|
list[--start] = threadID;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
size_t oldSize = list.size();
|
size_t oldSize = list.size();
|
||||||
|
@ -470,25 +478,53 @@ struct ThreadList
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void pop_front()
|
inline void pop_front()
|
||||||
|
{
|
||||||
|
if (start < START_PAD)
|
||||||
|
++start;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
size_t newSize = list.size() - 1;
|
size_t newSize = list.size() - 1;
|
||||||
list.resize(newSize);
|
list.resize(newSize);
|
||||||
if (newSize > 0)
|
if (newSize > 0)
|
||||||
memmove(&list[0], &list[1], newSize * sizeof(SceUID));
|
memmove(&list[0], &list[1], newSize * sizeof(SceUID));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline void pop_back()
|
inline void pop_back()
|
||||||
{
|
{
|
||||||
|
if (list.size() > START_PAD)
|
||||||
list.pop_back();
|
list.pop_back();
|
||||||
|
else
|
||||||
|
start = START_PAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void remove(const SceUID threadID)
|
inline void remove(const SceUID threadID)
|
||||||
{
|
{
|
||||||
list.erase(std::remove(list.begin(), list.end(), threadID), list.end());
|
if (empty())
|
||||||
|
return;
|
||||||
|
if (front() == threadID)
|
||||||
|
{
|
||||||
|
++start;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto new_end = std::remove(list.begin(), list.end(), threadID);
|
||||||
|
if (new_end - list.begin() >= START_PAD)
|
||||||
|
list.erase(new_end, list.end());
|
||||||
|
// TODO: Probably not efficient, but probably won't hit often hopefully?
|
||||||
|
else if (new_end != list.end())
|
||||||
|
{
|
||||||
|
++start;
|
||||||
|
size_t oldSize = list.size();
|
||||||
|
list.resize(START_PAD);
|
||||||
|
if (oldSize > 0)
|
||||||
|
memmove(&list[0], &list[1], oldSize * sizeof(SceUID));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DoState(PointerWrap &p)
|
void DoState(PointerWrap &p)
|
||||||
{
|
{
|
||||||
|
p.Do(start);
|
||||||
p.Do(list);
|
p.Do(list);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue