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:
Peter Johnson
2017-11-19 17:58:40 -08:00
committed by GitHub
parent 4a07f0380f
commit d214b36786
12 changed files with 461 additions and 587 deletions

View File

@@ -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

View File

@@ -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"

View File

@@ -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