blob: e2c53d48ff115d34fbccae00408303a8536c49d3 [file] [log] [blame]
Brian Silverman41cdd3e2019-01-19 19:48:58 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) 2008-2018 FIRST. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
8#include "frc/Resource.h"
9
10#include "frc/ErrorBase.h"
11#include "frc/WPIErrors.h"
12
13using namespace frc;
14
15wpi::mutex Resource::m_createMutex;
16
17void Resource::CreateResourceObject(std::unique_ptr<Resource>& r,
18 uint32_t elements) {
19 std::lock_guard<wpi::mutex> lock(m_createMutex);
20 if (!r) {
21 r = std::make_unique<Resource>(elements);
22 }
23}
24
25Resource::Resource(uint32_t elements) {
26 m_isAllocated = std::vector<bool>(elements, false);
27}
28
29uint32_t Resource::Allocate(const std::string& resourceDesc) {
30 std::lock_guard<wpi::mutex> lock(m_allocateMutex);
31 for (uint32_t i = 0; i < m_isAllocated.size(); i++) {
32 if (!m_isAllocated[i]) {
33 m_isAllocated[i] = true;
34 return i;
35 }
36 }
37 wpi_setWPIErrorWithContext(NoAvailableResources, resourceDesc);
38 return std::numeric_limits<uint32_t>::max();
39}
40
41uint32_t Resource::Allocate(uint32_t index, const std::string& resourceDesc) {
42 std::lock_guard<wpi::mutex> lock(m_allocateMutex);
43 if (index >= m_isAllocated.size()) {
44 wpi_setWPIErrorWithContext(ChannelIndexOutOfRange, resourceDesc);
45 return std::numeric_limits<uint32_t>::max();
46 }
47 if (m_isAllocated[index]) {
48 wpi_setWPIErrorWithContext(ResourceAlreadyAllocated, resourceDesc);
49 return std::numeric_limits<uint32_t>::max();
50 }
51 m_isAllocated[index] = true;
52 return index;
53}
54
55void Resource::Free(uint32_t index) {
56 std::unique_lock<wpi::mutex> lock(m_allocateMutex);
57 if (index == std::numeric_limits<uint32_t>::max()) return;
58 if (index >= m_isAllocated.size()) {
59 wpi_setWPIError(NotAllocated);
60 return;
61 }
62 if (!m_isAllocated[index]) {
63 wpi_setWPIError(NotAllocated);
64 return;
65 }
66 m_isAllocated[index] = false;
67}