mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-28 02:11:43 +00:00
Change HAL notifier to polling. (#627)
This moves the thread code to the WPILib layer, fixing various potential races and significantly simplifying the HAL implementation.
This commit is contained in:
@@ -15,16 +15,16 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*HAL_NotifierProcessFunction)(uint64_t currentTime,
|
||||
HAL_NotifierHandle handle);
|
||||
|
||||
HAL_NotifierHandle HAL_InitializeNotifier(HAL_NotifierProcessFunction process,
|
||||
void* param, int32_t* status);
|
||||
HAL_NotifierHandle HAL_InitializeNotifier(int32_t* status);
|
||||
void HAL_StopNotifier(HAL_NotifierHandle notifierHandle, int32_t* status);
|
||||
void HAL_CleanNotifier(HAL_NotifierHandle notifierHandle, int32_t* status);
|
||||
void* HAL_GetNotifierParam(HAL_NotifierHandle notifierHandle, int32_t* status);
|
||||
void HAL_UpdateNotifierAlarm(HAL_NotifierHandle notifierHandle,
|
||||
uint64_t triggerTime, int32_t* status);
|
||||
void HAL_StopNotifierAlarm(HAL_NotifierHandle notifierHandle, int32_t* status);
|
||||
void HAL_CancelNotifierAlarm(HAL_NotifierHandle notifierHandle,
|
||||
int32_t* status);
|
||||
uint64_t HAL_WaitForNotifierAlarm(HAL_NotifierHandle notifierHandle,
|
||||
int32_t* status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Copyright (c) 2017 FIRST. All Rights Reserved. */
|
||||
/* Open Source Software - may be modified and shared by FRC teams. The code */
|
||||
/* must be accompanied by the FIRST BSD license file in the root directory of */
|
||||
/* the project. */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "HAL/Types.h"
|
||||
|
||||
extern "C" {
|
||||
HAL_NotifierHandle HAL_InitializeNotifierNonThreadedUnsafe(
|
||||
HAL_NotifierProcessFunction process, void* param, int32_t* status);
|
||||
} // extern "C"
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <support/mutex.h>
|
||||
@@ -44,9 +45,16 @@ class UnlimitedHandleResource : public HandleBase {
|
||||
|
||||
THandle Allocate(std::shared_ptr<TStruct> structure);
|
||||
std::shared_ptr<TStruct> Get(THandle handle);
|
||||
void Free(THandle handle);
|
||||
/* Returns structure previously at that handle (or nullptr if none) */
|
||||
std::shared_ptr<TStruct> Free(THandle handle);
|
||||
void ResetHandles() override;
|
||||
|
||||
/* Calls func(THandle, TStruct*) for each handle. Note this holds the
|
||||
* global lock for the entirety of execution.
|
||||
*/
|
||||
template <typename Functor>
|
||||
void ForEach(Functor func);
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<TStruct>> m_structures;
|
||||
wpi::mutex m_handleMutex;
|
||||
@@ -81,12 +89,13 @@ UnlimitedHandleResource<THandle, TStruct, enumValue>::Get(THandle handle) {
|
||||
}
|
||||
|
||||
template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
|
||||
void UnlimitedHandleResource<THandle, TStruct, enumValue>::Free(
|
||||
THandle handle) {
|
||||
std::shared_ptr<TStruct>
|
||||
UnlimitedHandleResource<THandle, TStruct, enumValue>::Free(THandle handle) {
|
||||
int16_t index = getHandleTypedIndex(handle, enumValue, m_version);
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutex);
|
||||
if (index < 0 || index >= static_cast<int16_t>(m_structures.size())) return;
|
||||
m_structures[index].reset();
|
||||
if (index < 0 || index >= static_cast<int16_t>(m_structures.size()))
|
||||
return nullptr;
|
||||
return std::move(m_structures[index]);
|
||||
}
|
||||
|
||||
template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
|
||||
@@ -99,4 +108,19 @@ void UnlimitedHandleResource<THandle, TStruct, enumValue>::ResetHandles() {
|
||||
}
|
||||
HandleBase::ResetHandles();
|
||||
}
|
||||
|
||||
template <typename THandle, typename TStruct, HAL_HandleEnum enumValue>
|
||||
template <typename Functor>
|
||||
void UnlimitedHandleResource<THandle, TStruct, enumValue>::ForEach(
|
||||
Functor func) {
|
||||
std::lock_guard<wpi::mutex> sync(m_handleMutex);
|
||||
size_t i;
|
||||
for (i = 0; i < m_structures.size(); i++) {
|
||||
if (m_structures[i] != nullptr) {
|
||||
func(static_cast<THandle>(createHandle(i, enumValue, m_version)),
|
||||
m_structures[i].get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace hal
|
||||
|
||||
Reference in New Issue
Block a user