blob: 1f0e3486eb5f79927354663782b2d666854c1fa1 [file] [log] [blame]
Austin Schuh812d0d12021-11-04 20:16:48 -07001// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
Brian Silverman8fce7482020-01-05 13:18:21 -08004
5#include "frc/Resource.h"
6
Austin Schuh812d0d12021-11-04 20:16:48 -07007#include "frc/Errors.h"
Brian Silverman8fce7482020-01-05 13:18:21 -08008
9using namespace frc;
10
11wpi::mutex Resource::m_createMutex;
12
13void Resource::CreateResourceObject(std::unique_ptr<Resource>& r,
14 uint32_t elements) {
15 std::scoped_lock lock(m_createMutex);
16 if (!r) {
17 r = std::make_unique<Resource>(elements);
18 }
19}
20
21Resource::Resource(uint32_t elements) {
22 m_isAllocated = std::vector<bool>(elements, false);
23}
24
25uint32_t Resource::Allocate(const std::string& resourceDesc) {
26 std::scoped_lock lock(m_allocateMutex);
27 for (uint32_t i = 0; i < m_isAllocated.size(); i++) {
28 if (!m_isAllocated[i]) {
29 m_isAllocated[i] = true;
30 return i;
31 }
32 }
Austin Schuh812d0d12021-11-04 20:16:48 -070033 throw FRC_MakeError(err::NoAvailableResources, "{}", resourceDesc);
Brian Silverman8fce7482020-01-05 13:18:21 -080034}
35
36uint32_t Resource::Allocate(uint32_t index, const std::string& resourceDesc) {
37 std::scoped_lock lock(m_allocateMutex);
38 if (index >= m_isAllocated.size()) {
Austin Schuh812d0d12021-11-04 20:16:48 -070039 throw FRC_MakeError(err::ChannelIndexOutOfRange, "{}", resourceDesc);
Brian Silverman8fce7482020-01-05 13:18:21 -080040 }
41 if (m_isAllocated[index]) {
Austin Schuh812d0d12021-11-04 20:16:48 -070042 throw FRC_MakeError(err::ResourceAlreadyAllocated, "{}", resourceDesc);
Brian Silverman8fce7482020-01-05 13:18:21 -080043 }
44 m_isAllocated[index] = true;
45 return index;
46}
47
48void Resource::Free(uint32_t index) {
49 std::unique_lock lock(m_allocateMutex);
Austin Schuh812d0d12021-11-04 20:16:48 -070050 if (index == std::numeric_limits<uint32_t>::max()) {
Brian Silverman8fce7482020-01-05 13:18:21 -080051 return;
52 }
Austin Schuh812d0d12021-11-04 20:16:48 -070053 if (index >= m_isAllocated.size()) {
54 throw FRC_MakeError(err::NotAllocated, "index {}", index);
55 }
Brian Silverman8fce7482020-01-05 13:18:21 -080056 if (!m_isAllocated[index]) {
Austin Schuh812d0d12021-11-04 20:16:48 -070057 throw FRC_MakeError(err::NotAllocated, "index {}", index);
Brian Silverman8fce7482020-01-05 13:18:21 -080058 }
59 m_isAllocated[index] = false;
60}