mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-20 00:51:42 +00:00
[ntcore] Match standard handle layout, only allow 16 instances (#3577)
Now that there are only 16 instances, store them all statically. Make tests more reliable by using different ports for each connection in listener tests.
This commit is contained in:
@@ -10,8 +10,8 @@
|
||||
namespace nt {
|
||||
|
||||
// Handle data layout:
|
||||
// Bits 30-28: Type
|
||||
// Bits 27-20: Instance index
|
||||
// Bits 30-24: Type
|
||||
// Bits 23-20: Instance index
|
||||
// Bits 19-0: Handle index (0/unused for instance handles)
|
||||
|
||||
class Handle {
|
||||
@@ -40,15 +40,15 @@ class Handle {
|
||||
m_handle = 0;
|
||||
return;
|
||||
}
|
||||
m_handle = ((static_cast<int>(type) & 0xf) << 27) | ((inst & 0x7f) << 20) |
|
||||
m_handle = ((static_cast<int>(type) & 0x7f) << 24) | ((inst & 0xf) << 20) |
|
||||
(index & 0xfffff);
|
||||
}
|
||||
|
||||
int GetIndex() const { return static_cast<int>(m_handle) & 0xfffff; }
|
||||
Type GetType() const {
|
||||
return static_cast<Type>((static_cast<int>(m_handle) >> 27) & 0xf);
|
||||
return static_cast<Type>((static_cast<int>(m_handle) >> 24) & 0x7f);
|
||||
}
|
||||
int GetInst() const { return (static_cast<int>(m_handle) >> 20) & 0x7f; }
|
||||
int GetInst() const { return (static_cast<int>(m_handle) >> 20) & 0xf; }
|
||||
bool IsType(Type type) const { return type == GetType(); }
|
||||
int GetTypedIndex(Type type) const { return IsType(type) ? GetIndex() : -1; }
|
||||
int GetTypedInst(Type type) const { return IsType(type) ? GetInst() : -1; }
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
using namespace nt;
|
||||
|
||||
std::atomic<int> InstanceImpl::s_default{-1};
|
||||
std::atomic<InstanceImpl*> InstanceImpl::s_fast_instances[10];
|
||||
wpi::UidVector<InstanceImpl*, 10> InstanceImpl::s_instances;
|
||||
std::atomic<InstanceImpl*> InstanceImpl::s_instances[kNumInstances];
|
||||
wpi::mutex InstanceImpl::s_mutex;
|
||||
|
||||
using namespace std::placeholders;
|
||||
@@ -35,36 +34,10 @@ InstanceImpl* InstanceImpl::GetDefault() {
|
||||
}
|
||||
|
||||
InstanceImpl* InstanceImpl::Get(int inst) {
|
||||
if (inst < 0) {
|
||||
if (inst < 0 || inst >= kNumInstances) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// fast path, just an atomic read
|
||||
if (static_cast<unsigned int>(inst) <
|
||||
(sizeof(s_fast_instances) / sizeof(s_fast_instances[0]))) {
|
||||
InstanceImpl* ptr = s_fast_instances[inst];
|
||||
if (ptr) {
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
// slow path
|
||||
std::scoped_lock lock(s_mutex);
|
||||
|
||||
// static fast-path block
|
||||
if (static_cast<unsigned int>(inst) <
|
||||
(sizeof(s_fast_instances) / sizeof(s_fast_instances[0]))) {
|
||||
// double-check
|
||||
return s_fast_instances[inst];
|
||||
}
|
||||
|
||||
// vector
|
||||
if (static_cast<unsigned int>(inst) < s_instances.size()) {
|
||||
return s_instances[inst];
|
||||
}
|
||||
|
||||
// doesn't exist
|
||||
return nullptr;
|
||||
return s_instances[inst];
|
||||
}
|
||||
|
||||
int InstanceImpl::GetDefaultIndex() {
|
||||
@@ -94,28 +67,23 @@ int InstanceImpl::Alloc() {
|
||||
}
|
||||
|
||||
int InstanceImpl::AllocImpl() {
|
||||
unsigned int inst = s_instances.emplace_back(nullptr);
|
||||
InstanceImpl* ptr = new InstanceImpl(inst);
|
||||
s_instances[inst] = ptr;
|
||||
|
||||
if (inst < (sizeof(s_fast_instances) / sizeof(s_fast_instances[0]))) {
|
||||
s_fast_instances[inst] = ptr;
|
||||
int inst = 0;
|
||||
for (; inst < kNumInstances; ++inst) {
|
||||
if (!s_instances[inst]) {
|
||||
s_instances[inst] = new InstanceImpl(inst);
|
||||
return inst;
|
||||
}
|
||||
}
|
||||
|
||||
return static_cast<int>(inst);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void InstanceImpl::Destroy(int inst) {
|
||||
std::scoped_lock lock(s_mutex);
|
||||
if (inst < 0 || static_cast<unsigned int>(inst) >= s_instances.size()) {
|
||||
if (inst < 0 || inst >= kNumInstances) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (static_cast<unsigned int>(inst) <
|
||||
(sizeof(s_fast_instances) / sizeof(s_fast_instances[0]))) {
|
||||
s_fast_instances[inst] = nullptr;
|
||||
}
|
||||
|
||||
delete s_instances[inst];
|
||||
s_instances.erase(inst);
|
||||
InstanceImpl* ptr = nullptr;
|
||||
s_instances[inst].exchange(ptr);
|
||||
delete ptr;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
#include <wpi/UidVector.h>
|
||||
#include <wpi/mutex.h>
|
||||
|
||||
#include "ConnectionNotifier.h"
|
||||
@@ -47,8 +46,8 @@ class InstanceImpl {
|
||||
static int AllocImpl();
|
||||
|
||||
static std::atomic<int> s_default;
|
||||
static std::atomic<InstanceImpl*> s_fast_instances[10];
|
||||
static wpi::UidVector<InstanceImpl*, 10> s_instances;
|
||||
static constexpr int kNumInstances = 16;
|
||||
static std::atomic<InstanceImpl*> s_instances[kNumInstances];
|
||||
static wpi::mutex s_mutex;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user