rpcsx/rpcs3/Emu/IdManager.cpp

88 lines
2 KiB
C++
Raw Normal View History

2020-12-05 13:08:24 +01:00
#include "stdafx.h"
#include "IdManager.h"
#include "Utilities/Thread.h"
2017-01-25 18:50:30 +01:00
shared_mutex id_manager::g_mutex;
2016-05-13 16:01:48 +02:00
namespace id_manager
{
thread_local u32 g_id = 0;
}
template <>
bool serialize<std::shared_ptr<utils::serial>>(utils::serial& ar, std::shared_ptr<utils::serial>& o)
{
if (!o)
{
o = std::make_shared<utils::serial>();
}
if (!ar.is_writing())
{
o->set_reading_state();
}
ar(o->data);
return true;
}
std::vector<std::pair<u128, id_manager::typeinfo>>& id_manager::get_typeinfo_map()
{
// Magic static
static std::vector<std::pair<u128, id_manager::typeinfo>> s_map;
2023-02-13 11:33:06 +01:00
return s_map;
}
2016-05-13 16:01:48 +02:00
2024-12-22 19:59:48 +01:00
id_manager::id_key* idm::allocate_id(std::span<id_manager::id_key> keys, usz& highest_index, u32 type_id, u32 dst_id, u32 base, u32 step, u32 count, bool uses_lowest_id, std::pair<u32, u32> invl_range)
{
2023-12-28 18:37:24 +01:00
if (dst_id != (base ? 0 : u32{umax}))
{
// Fixed position construction
2023-12-28 18:37:24 +01:00
const u32 index = id_manager::get_index(dst_id, base, step, count, invl_range);
ensure(index < count);
2024-12-22 19:59:48 +01:00
highest_index = std::max<usz>(highest_index, index + 1);
2024-12-22 19:59:48 +01:00
if (keys[index].type() != umax)
{
return nullptr;
}
id_manager::g_id = dst_id;
2024-12-22 19:59:48 +01:00
keys[index] = id_manager::id_key(dst_id, type_id);
return &keys[index];
}
2022-09-04 14:29:35 +02:00
if (uses_lowest_id)
{
// Disable the optimization below (hurts accuracy for known cases)
2024-12-22 19:59:48 +01:00
highest_index = count;
2022-09-04 14:29:35 +02:00
}
2024-12-22 19:59:48 +01:00
else if (highest_index < count)
{
// Try to emplace back
2024-12-22 19:59:48 +01:00
const u32 _next = base + step * highest_index;
id_manager::g_id = _next;
2024-12-22 19:59:48 +01:00
return &(keys[highest_index++] = (id_manager::id_key(_next, type_id)));
2017-01-25 18:50:30 +01:00
}
// Check all IDs starting from "next id" (TODO)
for (u32 i = 0, next = base; i < count; i++, next += step)
2017-01-25 18:50:30 +01:00
{
2024-12-22 19:59:48 +01:00
const auto ptr = &keys[i];
// Look for free ID
2024-12-22 19:59:48 +01:00
if (ptr->type() == umax)
{
// Incremenet ID invalidation counter
2024-12-22 19:59:48 +01:00
const u32 id = next | ((ptr->value() + (1u << invl_range.first)) & (invl_range.second ? (((1u << invl_range.second) - 1) << invl_range.first) : 0));
id_manager::g_id = id;
2024-12-22 19:59:48 +01:00
*ptr = id_manager::id_key(id, type_id);
return ptr;
}
}
// Out of IDs
2017-01-26 02:03:03 +01:00
return nullptr;
}