mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-01 02:41:48 +00:00
[wpiutil] Split C++ header files
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "wpi/util/SmallVector.hpp"
|
||||
#include "wpi/util/Synchronization.h"
|
||||
#include "wpi/util/Synchronization.hpp"
|
||||
#include "wpi/util/mutex.hpp"
|
||||
|
||||
namespace wpi::util {
|
||||
|
||||
@@ -4,22 +4,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <concepts>
|
||||
#include <cstddef>
|
||||
#else
|
||||
|
||||
#include <stddef.h> // NOLINT
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef WPI_RAWFRAME_JNI
|
||||
#include "wpi/util/jni_util.hpp"
|
||||
#endif
|
||||
|
||||
// NOLINT
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -85,79 +71,3 @@ void WPI_SetRawFrameData(WPI_RawFrame* frame, void* data, size_t size,
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace wpi::util {
|
||||
struct RawFrame : public WPI_RawFrame {
|
||||
RawFrame() {
|
||||
data = nullptr;
|
||||
freeFunc = nullptr;
|
||||
freeCbData = nullptr;
|
||||
capacity = 0;
|
||||
size = 0;
|
||||
pixelFormat = WPI_PIXFMT_UNKNOWN;
|
||||
width = 0;
|
||||
height = 0;
|
||||
timestamp = 0;
|
||||
timestampSrc = WPI_TIMESRC_UNKNOWN;
|
||||
}
|
||||
RawFrame(const RawFrame&) = delete;
|
||||
RawFrame& operator=(const RawFrame&) = delete;
|
||||
RawFrame(RawFrame&& rhs) noexcept : WPI_RawFrame{rhs} {
|
||||
rhs.data = nullptr;
|
||||
rhs.freeFunc = nullptr;
|
||||
rhs.freeCbData = nullptr;
|
||||
rhs.capacity = 0;
|
||||
rhs.size = 0;
|
||||
}
|
||||
RawFrame& operator=(RawFrame&& rhs) noexcept {
|
||||
*static_cast<WPI_RawFrame*>(this) = rhs;
|
||||
rhs.data = nullptr;
|
||||
rhs.freeFunc = nullptr;
|
||||
rhs.freeCbData = nullptr;
|
||||
rhs.capacity = 0;
|
||||
rhs.size = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SetData(void* data, size_t size, size_t capacity, void* cbdata,
|
||||
void (*freeFunc)(void* cbdata, void* data, size_t capacity)) {
|
||||
WPI_SetRawFrameData(this, data, size, capacity, cbdata, freeFunc);
|
||||
}
|
||||
|
||||
// returns true if the frame data was allocated/reallocated
|
||||
bool Reserve(size_t size) {
|
||||
return WPI_AllocateRawFrameData(this, size) != 0;
|
||||
}
|
||||
|
||||
~RawFrame() { WPI_FreeRawFrameData(this); }
|
||||
};
|
||||
|
||||
#ifdef WPI_RAWFRAME_JNI
|
||||
template <std::same_as<wpi::util::RawFrame> T>
|
||||
void SetFrameData(JNIEnv* env, jclass rawFrameCls, jobject jframe,
|
||||
const T& frame, bool newData) {
|
||||
if (newData) {
|
||||
static jmethodID setData = env->GetMethodID(
|
||||
rawFrameCls, "setDataJNI", "(Ljava/nio/ByteBuffer;IIIIJI)V");
|
||||
env->CallVoidMethod(
|
||||
jframe, setData, env->NewDirectByteBuffer(frame.data, frame.size),
|
||||
static_cast<jint>(frame.width), static_cast<jint>(frame.height),
|
||||
static_cast<jint>(frame.stride), static_cast<jint>(frame.pixelFormat),
|
||||
static_cast<jlong>(frame.timestamp),
|
||||
static_cast<jint>(frame.timestampSrc));
|
||||
} else {
|
||||
static jmethodID setInfo =
|
||||
env->GetMethodID(rawFrameCls, "setInfoJNI", "(IIIIJI)V");
|
||||
env->CallVoidMethod(jframe, setInfo, static_cast<jint>(frame.width),
|
||||
static_cast<jint>(frame.height),
|
||||
static_cast<jint>(frame.stride),
|
||||
static_cast<jint>(frame.pixelFormat),
|
||||
static_cast<jlong>(frame.timestamp),
|
||||
static_cast<jint>(frame.timestampSrc));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace wpi::util
|
||||
#endif
|
||||
|
||||
90
wpiutil/src/main/native/include/wpi/util/RawFrame.hpp
Normal file
90
wpiutil/src/main/native/include/wpi/util/RawFrame.hpp
Normal file
@@ -0,0 +1,90 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "wpi/util/RawFrame.h"
|
||||
|
||||
#ifdef WPI_RAWFRAME_JNI
|
||||
#include <concepts>
|
||||
#endif
|
||||
#include <cstddef>
|
||||
|
||||
#ifdef WPI_RAWFRAME_JNI
|
||||
#include "wpi/util/jni_util.hpp"
|
||||
#endif
|
||||
|
||||
namespace wpi::util {
|
||||
struct RawFrame : public WPI_RawFrame {
|
||||
RawFrame() {
|
||||
data = nullptr;
|
||||
freeFunc = nullptr;
|
||||
freeCbData = nullptr;
|
||||
capacity = 0;
|
||||
size = 0;
|
||||
pixelFormat = WPI_PIXFMT_UNKNOWN;
|
||||
width = 0;
|
||||
height = 0;
|
||||
timestamp = 0;
|
||||
timestampSrc = WPI_TIMESRC_UNKNOWN;
|
||||
}
|
||||
RawFrame(const RawFrame&) = delete;
|
||||
RawFrame& operator=(const RawFrame&) = delete;
|
||||
RawFrame(RawFrame&& rhs) noexcept : WPI_RawFrame{rhs} {
|
||||
rhs.data = nullptr;
|
||||
rhs.freeFunc = nullptr;
|
||||
rhs.freeCbData = nullptr;
|
||||
rhs.capacity = 0;
|
||||
rhs.size = 0;
|
||||
}
|
||||
RawFrame& operator=(RawFrame&& rhs) noexcept {
|
||||
*static_cast<WPI_RawFrame*>(this) = rhs;
|
||||
rhs.data = nullptr;
|
||||
rhs.freeFunc = nullptr;
|
||||
rhs.freeCbData = nullptr;
|
||||
rhs.capacity = 0;
|
||||
rhs.size = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void SetData(void* data, size_t size, size_t capacity, void* cbdata,
|
||||
void (*freeFunc)(void* cbdata, void* data, size_t capacity)) {
|
||||
WPI_SetRawFrameData(this, data, size, capacity, cbdata, freeFunc);
|
||||
}
|
||||
|
||||
// returns true if the frame data was allocated/reallocated
|
||||
bool Reserve(size_t size) {
|
||||
return WPI_AllocateRawFrameData(this, size) != 0;
|
||||
}
|
||||
|
||||
~RawFrame() { WPI_FreeRawFrameData(this); }
|
||||
};
|
||||
|
||||
#ifdef WPI_RAWFRAME_JNI
|
||||
template <std::same_as<wpi::util::RawFrame> T>
|
||||
void SetFrameData(JNIEnv* env, jclass rawFrameCls, jobject jframe,
|
||||
const T& frame, bool newData) {
|
||||
if (newData) {
|
||||
static jmethodID setData = env->GetMethodID(
|
||||
rawFrameCls, "setDataJNI", "(Ljava/nio/ByteBuffer;IIIIJI)V");
|
||||
env->CallVoidMethod(
|
||||
jframe, setData, env->NewDirectByteBuffer(frame.data, frame.size),
|
||||
static_cast<jint>(frame.width), static_cast<jint>(frame.height),
|
||||
static_cast<jint>(frame.stride), static_cast<jint>(frame.pixelFormat),
|
||||
static_cast<jlong>(frame.timestamp),
|
||||
static_cast<jint>(frame.timestampSrc));
|
||||
} else {
|
||||
static jmethodID setInfo =
|
||||
env->GetMethodID(rawFrameCls, "setInfoJNI", "(IIIIJI)V");
|
||||
env->CallVoidMethod(jframe, setInfo, static_cast<jint>(frame.width),
|
||||
static_cast<jint>(frame.height),
|
||||
static_cast<jint>(frame.stride),
|
||||
static_cast<jint>(frame.pixelFormat),
|
||||
static_cast<jlong>(frame.timestamp),
|
||||
static_cast<jint>(frame.timestampSrc));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace wpi::util
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
|
||||
#include "wpi/util/Synchronization.h"
|
||||
#include "wpi/util/Synchronization.hpp"
|
||||
#include "wpi/util/condition_variable.hpp"
|
||||
#include "wpi/util/mutex.hpp"
|
||||
|
||||
|
||||
@@ -4,12 +4,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <climits>
|
||||
#include <initializer_list>
|
||||
#include <span>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Generic handle for all WPI handle-based interfaces.
|
||||
*
|
||||
@@ -27,425 +21,8 @@ typedef WPI_Handle WPI_EventHandle; // NOLINT
|
||||
typedef WPI_Handle WPI_SemaphoreHandle; // NOLINT
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace wpi::util {
|
||||
|
||||
/** Constant representing an invalid handle. */
|
||||
constexpr unsigned int kInvalidHandle = 0;
|
||||
|
||||
/**
|
||||
* Standard types for handles.
|
||||
* @{
|
||||
*/
|
||||
constexpr int kHandleTypeEvent = 1;
|
||||
constexpr int kHandleTypeSemaphore = 2;
|
||||
constexpr int kHandleTypeCSBase = 3;
|
||||
constexpr int kHandleTypeNTBase = 16;
|
||||
constexpr int kHandleTypeHALBase = 48;
|
||||
constexpr int kHandleTypeUserBase = 80;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Creates an event. Events have binary state (signaled or not signaled) and
|
||||
* may be either automatically reset or manually reset. Automatic-reset events
|
||||
* go to non-signaled state when a WaitForObject is woken up by the event;
|
||||
* manual-reset events require ResetEvent() to be called to set the event to
|
||||
* non-signaled state; if ResetEvent() is not called, any waiter on that event
|
||||
* will immediately wake when called.
|
||||
*
|
||||
* @param manualReset true for manual reset, false for automatic reset
|
||||
* @param initialState true to make the event initially in signaled state
|
||||
* @return Event handle
|
||||
*/
|
||||
WPI_EventHandle CreateEvent(bool manualReset = false,
|
||||
bool initialState = false);
|
||||
|
||||
/**
|
||||
* Destroys an event. Destruction wakes up any waiters.
|
||||
*
|
||||
* @param handle event handle
|
||||
*/
|
||||
void DestroyEvent(WPI_EventHandle handle);
|
||||
|
||||
/**
|
||||
* Sets an event to signaled state.
|
||||
*
|
||||
* @param handle event handle
|
||||
*/
|
||||
void SetEvent(WPI_EventHandle handle);
|
||||
|
||||
/**
|
||||
* Sets an event to non-signaled state.
|
||||
*
|
||||
* @param handle event handle
|
||||
*/
|
||||
void ResetEvent(WPI_EventHandle handle);
|
||||
|
||||
/**
|
||||
* Creates a semaphore. Semaphores keep an internal counter. Releasing the
|
||||
* semaphore increases the count. A semaphore with a non-zero count is
|
||||
* considered signaled. When a waiter wakes up it atomically decrements the
|
||||
* count by 1. This is generally useful in a single-supplier,
|
||||
* multiple-consumer scenario.
|
||||
*
|
||||
* @param initialCount initial value for the semaphore's internal counter
|
||||
* @param maximumCount maximum value for the semaphore's internal counter
|
||||
* @return Semaphore handle
|
||||
*/
|
||||
WPI_SemaphoreHandle CreateSemaphore(int initialCount = 0,
|
||||
int maximumCount = INT_MAX);
|
||||
|
||||
/**
|
||||
* Destroys a semaphore. Destruction wakes up any waiters.
|
||||
*
|
||||
* @param handle semaphore handle
|
||||
*/
|
||||
void DestroySemaphore(WPI_SemaphoreHandle handle);
|
||||
|
||||
/**
|
||||
* Releases N counts of a semaphore.
|
||||
*
|
||||
* @param handle semaphore handle
|
||||
* @param releaseCount amount to add to semaphore's internal counter;
|
||||
* must be positive
|
||||
* @param prevCount if non-null, previous count (output parameter)
|
||||
* @return True on successful release, false on failure (e.g. release count
|
||||
* would exceed maximum value, or handle invalid)
|
||||
*/
|
||||
bool ReleaseSemaphore(WPI_SemaphoreHandle handle, int releaseCount = 1,
|
||||
int* prevCount = nullptr);
|
||||
|
||||
/**
|
||||
* Waits for an handle to be signaled.
|
||||
*
|
||||
* @param handle handle to wait on
|
||||
* @return True if handle was signaled, false otherwise (e.g. object was
|
||||
* destroyed)
|
||||
*/
|
||||
bool WaitForObject(WPI_Handle handle);
|
||||
|
||||
/**
|
||||
* Waits for an handle to be signaled, with timeout.
|
||||
*
|
||||
* @param handle handle to wait on
|
||||
* @param timeout timeout in seconds
|
||||
* @param timedOut if non-null, set to true if timeout reached without handle
|
||||
* being signaled; set to false otherwise (output)
|
||||
* @return True if handle was signaled, false otherwise (e.g. object was
|
||||
* destroyed or timed out)
|
||||
*/
|
||||
bool WaitForObject(WPI_Handle handle, double timeout, bool* timedOut);
|
||||
|
||||
/**
|
||||
* Waits for one or more handles to be signaled.
|
||||
*
|
||||
* Invalid handles are treated as signaled; the returned array will have the
|
||||
* handle error bit set for any invalid handles.
|
||||
*
|
||||
* @param handles array of handles to wait on
|
||||
* @param signaled output array for storage of signaled handles; must be at
|
||||
* least the size of the handles input array
|
||||
* @return array of signaled handles (points into signaled array)
|
||||
*/
|
||||
std::span<WPI_Handle> WaitForObjects(std::span<const WPI_Handle> handles,
|
||||
std::span<WPI_Handle> signaled);
|
||||
|
||||
/**
|
||||
* Waits for one or more handles to be signaled.
|
||||
*
|
||||
* Invalid handles are treated as signaled; the returned array will have the
|
||||
* handle error bit set for any invalid handles.
|
||||
*
|
||||
* @param handles array of handles to wait on
|
||||
* @param signaled output array for storage of signaled handles; must be at
|
||||
* least the size of the handles input array
|
||||
* @return array of signaled handles (points into signaled array)
|
||||
*/
|
||||
inline std::span<WPI_Handle> WaitForObjects(
|
||||
std::initializer_list<WPI_Handle> handles, std::span<WPI_Handle> signaled) {
|
||||
return WaitForObjects(std::span{handles.begin(), handles.size()}, signaled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for one or more handles to be signaled, with timeout.
|
||||
*
|
||||
* Invalid handles are treated as signaled; the returned array will have the
|
||||
* handle error bit set for any invalid handles.
|
||||
*
|
||||
* @param handles array of handles to wait on
|
||||
* @param signaled output array for storage of signaled handles; must be at
|
||||
* least the size of the handles input array
|
||||
* @param timeout timeout in seconds
|
||||
* @param timedOut if non-null, set to true if timeout reached without any
|
||||
* handle being signaled; set to false otherwise (output)
|
||||
* @return array of signaled handles (points into signaled array)
|
||||
*/
|
||||
std::span<WPI_Handle> WaitForObjects(std::span<const WPI_Handle> handles,
|
||||
std::span<WPI_Handle> signaled,
|
||||
double timeout, bool* timedOut);
|
||||
/**
|
||||
* Waits for one or more handles to be signaled, with timeout.
|
||||
*
|
||||
* Invalid handles are treated as signaled; the returned array will have the
|
||||
* handle error bit set for any invalid handles.
|
||||
*
|
||||
* @param handles array of handles to wait on
|
||||
* @param signaled output array for storage of signaled handles; must be at
|
||||
* least the size of the handles input array
|
||||
* @param timeout timeout in seconds
|
||||
* @param timedOut if non-null, set to true if timeout reached without any
|
||||
* handle being signaled; set to false otherwise (output)
|
||||
* @return array of signaled handles (points into signaled array)
|
||||
*/
|
||||
inline std::span<WPI_Handle> WaitForObjects(
|
||||
std::initializer_list<WPI_Handle> handles, std::span<WPI_Handle> signaled,
|
||||
double timeout, bool* timedOut) {
|
||||
return WaitForObjects(std::span{handles.begin(), handles.size()}, signaled,
|
||||
timeout, timedOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up signaling for an arbitrary handle. With this function, any handle
|
||||
* can operate like an event handle.
|
||||
*
|
||||
* @param handle Event handle
|
||||
* @param manualReset true for manual reset, false for automatic reset
|
||||
* @param initialState true to make the handle initially in signaled state
|
||||
*/
|
||||
void CreateSignalObject(WPI_Handle handle, bool manualReset = false,
|
||||
bool initialState = false);
|
||||
|
||||
/**
|
||||
* Sets a handle to signaled state.
|
||||
*
|
||||
* @param handle handle
|
||||
*/
|
||||
void SetSignalObject(WPI_Handle handle);
|
||||
|
||||
/**
|
||||
* Sets a handle to non-signaled state.
|
||||
*
|
||||
* @param handle handle
|
||||
*/
|
||||
void ResetSignalObject(WPI_Handle handle);
|
||||
|
||||
/**
|
||||
* Cleans up signaling for a handle. Destruction wakes up any waiters.
|
||||
*
|
||||
* @param handle handle
|
||||
*/
|
||||
void DestroySignalObject(WPI_Handle handle);
|
||||
|
||||
/**
|
||||
* An atomic signaling event for synchronization.
|
||||
*
|
||||
* Events have binary state (signaled or not signaled) and may be either
|
||||
* automatically reset or manually reset. Automatic-reset events go to
|
||||
* non-signaled state when a WaitForObject is woken up by the event;
|
||||
* manual-reset events require Reset() to be called to set the event to
|
||||
* non-signaled state; if Reset() is not called, any waiter on that event
|
||||
* will immediately wake when called.
|
||||
*/
|
||||
class Event final {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param manualReset true for manual reset, false for automatic reset
|
||||
* @param initialState true to make the event initially in signaled state
|
||||
*/
|
||||
explicit Event(bool manualReset = false, bool initialState = false)
|
||||
: m_handle{CreateEvent(manualReset, initialState)} {}
|
||||
~Event() {
|
||||
if (m_handle != 0) {
|
||||
DestroyEvent(m_handle);
|
||||
}
|
||||
}
|
||||
|
||||
Event(const Event&) = delete;
|
||||
Event& operator=(const Event&) = delete;
|
||||
|
||||
Event(Event&& rhs) : m_handle{rhs.m_handle} { rhs.m_handle = 0; }
|
||||
Event& operator=(Event&& rhs) {
|
||||
if (m_handle != 0) {
|
||||
DestroyEvent(m_handle);
|
||||
}
|
||||
m_handle = rhs.m_handle;
|
||||
rhs.m_handle = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the event handle (e.g. for WaitForObject).
|
||||
*
|
||||
* @return handle
|
||||
*/
|
||||
explicit operator WPI_Handle() const { return m_handle; }
|
||||
|
||||
/**
|
||||
* Gets the event handle (e.g. for WaitForObject).
|
||||
*
|
||||
* @return handle
|
||||
*/
|
||||
WPI_EventHandle GetHandle() const { return m_handle; }
|
||||
|
||||
/**
|
||||
* Sets the event to signaled state.
|
||||
*/
|
||||
void Set() { SetEvent(m_handle); }
|
||||
|
||||
/**
|
||||
* Sets the event to non-signaled state.
|
||||
*/
|
||||
void Reset() { ResetEvent(m_handle); }
|
||||
|
||||
private:
|
||||
WPI_EventHandle m_handle;
|
||||
};
|
||||
|
||||
/**
|
||||
* A semaphore for synchronization.
|
||||
*
|
||||
* Semaphores keep an internal counter. Releasing the semaphore increases
|
||||
* the count. A semaphore with a non-zero count is considered signaled.
|
||||
* When a waiter wakes up it atomically decrements the count by 1. This
|
||||
* is generally useful in a single-supplier, multiple-consumer scenario.
|
||||
*/
|
||||
class Semaphore final {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param initialCount initial value for the semaphore's internal counter
|
||||
* @param maximumCount maximum value for the semaphore's internal counter
|
||||
*/
|
||||
explicit Semaphore(int initialCount = 0, int maximumCount = INT_MAX)
|
||||
: m_handle{CreateSemaphore(initialCount, maximumCount)} {}
|
||||
~Semaphore() {
|
||||
if (m_handle != 0) {
|
||||
DestroySemaphore(m_handle);
|
||||
}
|
||||
}
|
||||
|
||||
Semaphore(const Semaphore&) = delete;
|
||||
Semaphore& operator=(const Semaphore&) = delete;
|
||||
|
||||
Semaphore(Semaphore&& rhs) : m_handle{rhs.m_handle} { rhs.m_handle = 0; }
|
||||
Semaphore& operator=(Semaphore&& rhs) {
|
||||
if (m_handle != 0) {
|
||||
DestroySemaphore(m_handle);
|
||||
}
|
||||
m_handle = rhs.m_handle;
|
||||
rhs.m_handle = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the semaphore handle (e.g. for WaitForObject).
|
||||
*
|
||||
* @return handle
|
||||
*/
|
||||
explicit operator WPI_Handle() const { return m_handle; }
|
||||
|
||||
/**
|
||||
* Gets the semaphore handle (e.g. for WaitForObject).
|
||||
*
|
||||
* @return handle
|
||||
*/
|
||||
WPI_SemaphoreHandle GetHandle() const { return m_handle; }
|
||||
|
||||
/**
|
||||
* Releases N counts of the semaphore.
|
||||
*
|
||||
* @param releaseCount amount to add to semaphore's internal counter;
|
||||
* must be positive
|
||||
* @param prevCount if non-null, previous count (output parameter)
|
||||
* @return True on successful release, false on failure (e.g. release count
|
||||
* would exceed maximum value, or handle invalid)
|
||||
*/
|
||||
bool Release(int releaseCount = 1, int* prevCount = nullptr) {
|
||||
return ReleaseSemaphore(m_handle, releaseCount, prevCount);
|
||||
}
|
||||
|
||||
private:
|
||||
WPI_SemaphoreHandle m_handle;
|
||||
};
|
||||
|
||||
/**
|
||||
* RAII wrapper for signaling handles.
|
||||
*
|
||||
* Sets up signaling for an arbitrary handle. This enables any handle
|
||||
* to operate like an event handle.
|
||||
*/
|
||||
template <typename T>
|
||||
class SignalObject final {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param handle handle
|
||||
* @param manualReset true for manual reset, false for automatic reset
|
||||
* @param initialState true to make the handle initially in signaled state
|
||||
*/
|
||||
explicit SignalObject(T handle = 0, bool manualReset = false,
|
||||
bool initialState = false)
|
||||
: m_handle{handle} {
|
||||
CreateSignalObject(handle, manualReset, initialState);
|
||||
}
|
||||
~SignalObject() {
|
||||
if (m_handle != 0) {
|
||||
DestroySignalObject(m_handle);
|
||||
}
|
||||
}
|
||||
|
||||
SignalObject(const SignalObject&) = delete;
|
||||
SignalObject& operator=(const SignalObject&) = delete;
|
||||
|
||||
SignalObject(SignalObject&& rhs) : m_handle{rhs.m_handle} {
|
||||
rhs.m_handle = 0;
|
||||
}
|
||||
SignalObject& operator=(SignalObject&& rhs) {
|
||||
if (m_handle != 0) {
|
||||
DestroySignalObject(m_handle);
|
||||
}
|
||||
m_handle = rhs.m_handle;
|
||||
rhs.m_handle = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the handle.
|
||||
*
|
||||
* @return handle
|
||||
*/
|
||||
/*implicit*/ operator T() const { return m_handle; } // NOLINT
|
||||
|
||||
/**
|
||||
* Gets the handle (e.g. for WaitForObject).
|
||||
*
|
||||
* @return handle
|
||||
*/
|
||||
T GetHandle() const { return m_handle; }
|
||||
|
||||
/**
|
||||
* Sets the handle to signaled state.
|
||||
*/
|
||||
void Set() { SetSignalObject(m_handle); }
|
||||
|
||||
/**
|
||||
* Sets the handle to non-signaled state.
|
||||
*/
|
||||
void Reset() { ResetSignalObject(m_handle); }
|
||||
|
||||
private:
|
||||
T m_handle;
|
||||
};
|
||||
|
||||
} // namespace wpi::util
|
||||
|
||||
extern "C" {
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Creates an event. Events have binary state (signaled or not signaled) and
|
||||
|
||||
426
wpiutil/src/main/native/include/wpi/util/Synchronization.hpp
Normal file
426
wpiutil/src/main/native/include/wpi/util/Synchronization.hpp
Normal file
@@ -0,0 +1,426 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <climits>
|
||||
#include <initializer_list>
|
||||
#include <span>
|
||||
|
||||
#include "wpi/util/Synchronization.h"
|
||||
|
||||
namespace wpi::util {
|
||||
|
||||
/** Constant representing an invalid handle. */
|
||||
constexpr unsigned int kInvalidHandle = 0;
|
||||
|
||||
/**
|
||||
* Standard types for handles.
|
||||
* @{
|
||||
*/
|
||||
constexpr int kHandleTypeEvent = 1;
|
||||
constexpr int kHandleTypeSemaphore = 2;
|
||||
constexpr int kHandleTypeCSBase = 3;
|
||||
constexpr int kHandleTypeNTBase = 16;
|
||||
constexpr int kHandleTypeHALBase = 48;
|
||||
constexpr int kHandleTypeUserBase = 80;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* Creates an event. Events have binary state (signaled or not signaled) and
|
||||
* may be either automatically reset or manually reset. Automatic-reset events
|
||||
* go to non-signaled state when a WaitForObject is woken up by the event;
|
||||
* manual-reset events require ResetEvent() to be called to set the event to
|
||||
* non-signaled state; if ResetEvent() is not called, any waiter on that event
|
||||
* will immediately wake when called.
|
||||
*
|
||||
* @param manualReset true for manual reset, false for automatic reset
|
||||
* @param initialState true to make the event initially in signaled state
|
||||
* @return Event handle
|
||||
*/
|
||||
WPI_EventHandle CreateEvent(bool manualReset = false,
|
||||
bool initialState = false);
|
||||
|
||||
/**
|
||||
* Destroys an event. Destruction wakes up any waiters.
|
||||
*
|
||||
* @param handle event handle
|
||||
*/
|
||||
void DestroyEvent(WPI_EventHandle handle);
|
||||
|
||||
/**
|
||||
* Sets an event to signaled state.
|
||||
*
|
||||
* @param handle event handle
|
||||
*/
|
||||
void SetEvent(WPI_EventHandle handle);
|
||||
|
||||
/**
|
||||
* Sets an event to non-signaled state.
|
||||
*
|
||||
* @param handle event handle
|
||||
*/
|
||||
void ResetEvent(WPI_EventHandle handle);
|
||||
|
||||
/**
|
||||
* Creates a semaphore. Semaphores keep an internal counter. Releasing the
|
||||
* semaphore increases the count. A semaphore with a non-zero count is
|
||||
* considered signaled. When a waiter wakes up it atomically decrements the
|
||||
* count by 1. This is generally useful in a single-supplier,
|
||||
* multiple-consumer scenario.
|
||||
*
|
||||
* @param initialCount initial value for the semaphore's internal counter
|
||||
* @param maximumCount maximum value for the semaphore's internal counter
|
||||
* @return Semaphore handle
|
||||
*/
|
||||
WPI_SemaphoreHandle CreateSemaphore(int initialCount = 0,
|
||||
int maximumCount = INT_MAX);
|
||||
|
||||
/**
|
||||
* Destroys a semaphore. Destruction wakes up any waiters.
|
||||
*
|
||||
* @param handle semaphore handle
|
||||
*/
|
||||
void DestroySemaphore(WPI_SemaphoreHandle handle);
|
||||
|
||||
/**
|
||||
* Releases N counts of a semaphore.
|
||||
*
|
||||
* @param handle semaphore handle
|
||||
* @param releaseCount amount to add to semaphore's internal counter;
|
||||
* must be positive
|
||||
* @param prevCount if non-null, previous count (output parameter)
|
||||
* @return True on successful release, false on failure (e.g. release count
|
||||
* would exceed maximum value, or handle invalid)
|
||||
*/
|
||||
bool ReleaseSemaphore(WPI_SemaphoreHandle handle, int releaseCount = 1,
|
||||
int* prevCount = nullptr);
|
||||
|
||||
/**
|
||||
* Waits for an handle to be signaled.
|
||||
*
|
||||
* @param handle handle to wait on
|
||||
* @return True if handle was signaled, false otherwise (e.g. object was
|
||||
* destroyed)
|
||||
*/
|
||||
bool WaitForObject(WPI_Handle handle);
|
||||
|
||||
/**
|
||||
* Waits for an handle to be signaled, with timeout.
|
||||
*
|
||||
* @param handle handle to wait on
|
||||
* @param timeout timeout in seconds
|
||||
* @param timedOut if non-null, set to true if timeout reached without handle
|
||||
* being signaled; set to false otherwise (output)
|
||||
* @return True if handle was signaled, false otherwise (e.g. object was
|
||||
* destroyed or timed out)
|
||||
*/
|
||||
bool WaitForObject(WPI_Handle handle, double timeout, bool* timedOut);
|
||||
|
||||
/**
|
||||
* Waits for one or more handles to be signaled.
|
||||
*
|
||||
* Invalid handles are treated as signaled; the returned array will have the
|
||||
* handle error bit set for any invalid handles.
|
||||
*
|
||||
* @param handles array of handles to wait on
|
||||
* @param signaled output array for storage of signaled handles; must be at
|
||||
* least the size of the handles input array
|
||||
* @return array of signaled handles (points into signaled array)
|
||||
*/
|
||||
std::span<WPI_Handle> WaitForObjects(std::span<const WPI_Handle> handles,
|
||||
std::span<WPI_Handle> signaled);
|
||||
|
||||
/**
|
||||
* Waits for one or more handles to be signaled.
|
||||
*
|
||||
* Invalid handles are treated as signaled; the returned array will have the
|
||||
* handle error bit set for any invalid handles.
|
||||
*
|
||||
* @param handles array of handles to wait on
|
||||
* @param signaled output array for storage of signaled handles; must be at
|
||||
* least the size of the handles input array
|
||||
* @return array of signaled handles (points into signaled array)
|
||||
*/
|
||||
inline std::span<WPI_Handle> WaitForObjects(
|
||||
std::initializer_list<WPI_Handle> handles, std::span<WPI_Handle> signaled) {
|
||||
return WaitForObjects(std::span{handles.begin(), handles.size()}, signaled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for one or more handles to be signaled, with timeout.
|
||||
*
|
||||
* Invalid handles are treated as signaled; the returned array will have the
|
||||
* handle error bit set for any invalid handles.
|
||||
*
|
||||
* @param handles array of handles to wait on
|
||||
* @param signaled output array for storage of signaled handles; must be at
|
||||
* least the size of the handles input array
|
||||
* @param timeout timeout in seconds
|
||||
* @param timedOut if non-null, set to true if timeout reached without any
|
||||
* handle being signaled; set to false otherwise (output)
|
||||
* @return array of signaled handles (points into signaled array)
|
||||
*/
|
||||
std::span<WPI_Handle> WaitForObjects(std::span<const WPI_Handle> handles,
|
||||
std::span<WPI_Handle> signaled,
|
||||
double timeout, bool* timedOut);
|
||||
/**
|
||||
* Waits for one or more handles to be signaled, with timeout.
|
||||
*
|
||||
* Invalid handles are treated as signaled; the returned array will have the
|
||||
* handle error bit set for any invalid handles.
|
||||
*
|
||||
* @param handles array of handles to wait on
|
||||
* @param signaled output array for storage of signaled handles; must be at
|
||||
* least the size of the handles input array
|
||||
* @param timeout timeout in seconds
|
||||
* @param timedOut if non-null, set to true if timeout reached without any
|
||||
* handle being signaled; set to false otherwise (output)
|
||||
* @return array of signaled handles (points into signaled array)
|
||||
*/
|
||||
inline std::span<WPI_Handle> WaitForObjects(
|
||||
std::initializer_list<WPI_Handle> handles, std::span<WPI_Handle> signaled,
|
||||
double timeout, bool* timedOut) {
|
||||
return WaitForObjects(std::span{handles.begin(), handles.size()}, signaled,
|
||||
timeout, timedOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up signaling for an arbitrary handle. With this function, any handle
|
||||
* can operate like an event handle.
|
||||
*
|
||||
* @param handle Event handle
|
||||
* @param manualReset true for manual reset, false for automatic reset
|
||||
* @param initialState true to make the handle initially in signaled state
|
||||
*/
|
||||
void CreateSignalObject(WPI_Handle handle, bool manualReset = false,
|
||||
bool initialState = false);
|
||||
|
||||
/**
|
||||
* Sets a handle to signaled state.
|
||||
*
|
||||
* @param handle handle
|
||||
*/
|
||||
void SetSignalObject(WPI_Handle handle);
|
||||
|
||||
/**
|
||||
* Sets a handle to non-signaled state.
|
||||
*
|
||||
* @param handle handle
|
||||
*/
|
||||
void ResetSignalObject(WPI_Handle handle);
|
||||
|
||||
/**
|
||||
* Cleans up signaling for a handle. Destruction wakes up any waiters.
|
||||
*
|
||||
* @param handle handle
|
||||
*/
|
||||
void DestroySignalObject(WPI_Handle handle);
|
||||
|
||||
/**
|
||||
* An atomic signaling event for synchronization.
|
||||
*
|
||||
* Events have binary state (signaled or not signaled) and may be either
|
||||
* automatically reset or manually reset. Automatic-reset events go to
|
||||
* non-signaled state when a WaitForObject is woken up by the event;
|
||||
* manual-reset events require Reset() to be called to set the event to
|
||||
* non-signaled state; if Reset() is not called, any waiter on that event
|
||||
* will immediately wake when called.
|
||||
*/
|
||||
class Event final {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param manualReset true for manual reset, false for automatic reset
|
||||
* @param initialState true to make the event initially in signaled state
|
||||
*/
|
||||
explicit Event(bool manualReset = false, bool initialState = false)
|
||||
: m_handle{CreateEvent(manualReset, initialState)} {}
|
||||
~Event() {
|
||||
if (m_handle != 0) {
|
||||
DestroyEvent(m_handle);
|
||||
}
|
||||
}
|
||||
|
||||
Event(const Event&) = delete;
|
||||
Event& operator=(const Event&) = delete;
|
||||
|
||||
Event(Event&& rhs) : m_handle{rhs.m_handle} { rhs.m_handle = 0; }
|
||||
Event& operator=(Event&& rhs) {
|
||||
if (m_handle != 0) {
|
||||
DestroyEvent(m_handle);
|
||||
}
|
||||
m_handle = rhs.m_handle;
|
||||
rhs.m_handle = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the event handle (e.g. for WaitForObject).
|
||||
*
|
||||
* @return handle
|
||||
*/
|
||||
explicit operator WPI_Handle() const { return m_handle; }
|
||||
|
||||
/**
|
||||
* Gets the event handle (e.g. for WaitForObject).
|
||||
*
|
||||
* @return handle
|
||||
*/
|
||||
WPI_EventHandle GetHandle() const { return m_handle; }
|
||||
|
||||
/**
|
||||
* Sets the event to signaled state.
|
||||
*/
|
||||
void Set() { SetEvent(m_handle); }
|
||||
|
||||
/**
|
||||
* Sets the event to non-signaled state.
|
||||
*/
|
||||
void Reset() { ResetEvent(m_handle); }
|
||||
|
||||
private:
|
||||
WPI_EventHandle m_handle;
|
||||
};
|
||||
|
||||
/**
|
||||
* A semaphore for synchronization.
|
||||
*
|
||||
* Semaphores keep an internal counter. Releasing the semaphore increases
|
||||
* the count. A semaphore with a non-zero count is considered signaled.
|
||||
* When a waiter wakes up it atomically decrements the count by 1. This
|
||||
* is generally useful in a single-supplier, multiple-consumer scenario.
|
||||
*/
|
||||
class Semaphore final {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param initialCount initial value for the semaphore's internal counter
|
||||
* @param maximumCount maximum value for the semaphore's internal counter
|
||||
*/
|
||||
explicit Semaphore(int initialCount = 0, int maximumCount = INT_MAX)
|
||||
: m_handle{CreateSemaphore(initialCount, maximumCount)} {}
|
||||
~Semaphore() {
|
||||
if (m_handle != 0) {
|
||||
DestroySemaphore(m_handle);
|
||||
}
|
||||
}
|
||||
|
||||
Semaphore(const Semaphore&) = delete;
|
||||
Semaphore& operator=(const Semaphore&) = delete;
|
||||
|
||||
Semaphore(Semaphore&& rhs) : m_handle{rhs.m_handle} { rhs.m_handle = 0; }
|
||||
Semaphore& operator=(Semaphore&& rhs) {
|
||||
if (m_handle != 0) {
|
||||
DestroySemaphore(m_handle);
|
||||
}
|
||||
m_handle = rhs.m_handle;
|
||||
rhs.m_handle = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the semaphore handle (e.g. for WaitForObject).
|
||||
*
|
||||
* @return handle
|
||||
*/
|
||||
explicit operator WPI_Handle() const { return m_handle; }
|
||||
|
||||
/**
|
||||
* Gets the semaphore handle (e.g. for WaitForObject).
|
||||
*
|
||||
* @return handle
|
||||
*/
|
||||
WPI_SemaphoreHandle GetHandle() const { return m_handle; }
|
||||
|
||||
/**
|
||||
* Releases N counts of the semaphore.
|
||||
*
|
||||
* @param releaseCount amount to add to semaphore's internal counter;
|
||||
* must be positive
|
||||
* @param prevCount if non-null, previous count (output parameter)
|
||||
* @return True on successful release, false on failure (e.g. release count
|
||||
* would exceed maximum value, or handle invalid)
|
||||
*/
|
||||
bool Release(int releaseCount = 1, int* prevCount = nullptr) {
|
||||
return ReleaseSemaphore(m_handle, releaseCount, prevCount);
|
||||
}
|
||||
|
||||
private:
|
||||
WPI_SemaphoreHandle m_handle;
|
||||
};
|
||||
|
||||
/**
|
||||
* RAII wrapper for signaling handles.
|
||||
*
|
||||
* Sets up signaling for an arbitrary handle. This enables any handle
|
||||
* to operate like an event handle.
|
||||
*/
|
||||
template <typename T>
|
||||
class SignalObject final {
|
||||
public:
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param handle handle
|
||||
* @param manualReset true for manual reset, false for automatic reset
|
||||
* @param initialState true to make the handle initially in signaled state
|
||||
*/
|
||||
explicit SignalObject(T handle = 0, bool manualReset = false,
|
||||
bool initialState = false)
|
||||
: m_handle{handle} {
|
||||
CreateSignalObject(handle, manualReset, initialState);
|
||||
}
|
||||
~SignalObject() {
|
||||
if (m_handle != 0) {
|
||||
DestroySignalObject(m_handle);
|
||||
}
|
||||
}
|
||||
|
||||
SignalObject(const SignalObject&) = delete;
|
||||
SignalObject& operator=(const SignalObject&) = delete;
|
||||
|
||||
SignalObject(SignalObject&& rhs) : m_handle{rhs.m_handle} {
|
||||
rhs.m_handle = 0;
|
||||
}
|
||||
SignalObject& operator=(SignalObject&& rhs) {
|
||||
if (m_handle != 0) {
|
||||
DestroySignalObject(m_handle);
|
||||
}
|
||||
m_handle = rhs.m_handle;
|
||||
rhs.m_handle = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the handle.
|
||||
*
|
||||
* @return handle
|
||||
*/
|
||||
/*implicit*/ operator T() const { return m_handle; } // NOLINT
|
||||
|
||||
/**
|
||||
* Gets the handle (e.g. for WaitForObject).
|
||||
*
|
||||
* @return handle
|
||||
*/
|
||||
T GetHandle() const { return m_handle; }
|
||||
|
||||
/**
|
||||
* Sets the handle to signaled state.
|
||||
*/
|
||||
void Set() { SetSignalObject(m_handle); }
|
||||
|
||||
/**
|
||||
* Sets the handle to non-signaled state.
|
||||
*/
|
||||
void Reset() { ResetSignalObject(m_handle); }
|
||||
|
||||
private:
|
||||
T m_handle;
|
||||
};
|
||||
|
||||
} // namespace wpi::util
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "wpi/util/mutex.hpp"
|
||||
#include "wpi/util/print.hpp"
|
||||
#include "wpi/util/raw_ostream.hpp"
|
||||
#include "wpi/util/string.h"
|
||||
#include "wpi/util/string.hpp"
|
||||
|
||||
/** Java Native Interface (JNI) utility functions */
|
||||
namespace wpi::util::java {
|
||||
|
||||
@@ -4,10 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <cstring>
|
||||
#include <string_view>
|
||||
#endif
|
||||
#include <stddef.h> // NOLINT
|
||||
|
||||
/**
|
||||
* A const UTF8 string.
|
||||
@@ -19,27 +16,9 @@ struct WPI_String {
|
||||
size_t len;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace wpi::util {
|
||||
/** Converts a WPI_String to a string_view */
|
||||
constexpr std::string_view to_string_view(const struct WPI_String* str) {
|
||||
if (str) {
|
||||
return {str->str, str->len};
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/** Converts a string_view to a WPI_String */
|
||||
constexpr WPI_String make_string(std::string_view view) {
|
||||
return WPI_String{view.data(), view.size()};
|
||||
}
|
||||
} // namespace wpi::util
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initializes a WPI_String from a null terminated UTF-8 string.
|
||||
@@ -106,25 +85,4 @@ void WPI_FreeStringArray(const struct WPI_String* wpiStringArray,
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace wpi::util {
|
||||
|
||||
/** Allocates a copy of a string_view and stores the result into a WPI_String */
|
||||
inline WPI_String alloc_wpi_string(std::string_view view) {
|
||||
WPI_String out;
|
||||
size_t len = view.size();
|
||||
std::memcpy(WPI_AllocateString(&out, len), view.data(), len);
|
||||
return out;
|
||||
}
|
||||
|
||||
/** Allocates a copy of a WPI_String */
|
||||
inline WPI_String copy_wpi_string(const WPI_String& str) {
|
||||
if (str.str == nullptr || str.len == 0) {
|
||||
return WPI_String{nullptr, 0};
|
||||
}
|
||||
return alloc_wpi_string(to_string_view(&str));
|
||||
}
|
||||
} // namespace wpi::util
|
||||
#endif
|
||||
|
||||
44
wpiutil/src/main/native/include/wpi/util/string.hpp
Normal file
44
wpiutil/src/main/native/include/wpi/util/string.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstring>
|
||||
#include <string_view>
|
||||
|
||||
#include "wpi/util/string.h"
|
||||
|
||||
namespace wpi::util {
|
||||
|
||||
/** Converts a WPI_String to a string_view */
|
||||
constexpr std::string_view to_string_view(const struct WPI_String* str) {
|
||||
if (str) {
|
||||
return {str->str, str->len};
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/** Converts a string_view to a WPI_String */
|
||||
constexpr WPI_String make_string(std::string_view view) {
|
||||
return WPI_String{view.data(), view.size()};
|
||||
}
|
||||
|
||||
/** Allocates a copy of a string_view and stores the result into a WPI_String */
|
||||
inline WPI_String alloc_wpi_string(std::string_view view) {
|
||||
WPI_String out;
|
||||
size_t len = view.size();
|
||||
std::memcpy(WPI_AllocateString(&out, len), view.data(), len);
|
||||
return out;
|
||||
}
|
||||
|
||||
/** Allocates a copy of a WPI_String */
|
||||
inline WPI_String copy_wpi_string(const WPI_String& str) {
|
||||
if (str.str == nullptr || str.len == 0) {
|
||||
return WPI_String{nullptr, 0};
|
||||
}
|
||||
return alloc_wpi_string(to_string_view(&str));
|
||||
}
|
||||
|
||||
} // namespace wpi::util
|
||||
@@ -6,11 +6,6 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <memory> // NOLINT
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -48,39 +43,3 @@ uint64_t WPI_GetSystemTime(void);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace wpi::util {
|
||||
|
||||
/**
|
||||
* The default implementation used for Now().
|
||||
* In general this is the time returned by the operating system.
|
||||
* @return Time in microseconds.
|
||||
*/
|
||||
uint64_t NowDefault();
|
||||
|
||||
/**
|
||||
* Set the implementation used by Now().
|
||||
* The implementation must return monotonic time in microseconds to maintain
|
||||
* the contract of Now().
|
||||
* @param func Function called by Now() to return the time.
|
||||
*/
|
||||
void SetNowImpl(uint64_t (*func)());
|
||||
|
||||
/**
|
||||
* Return a value representing the current time in microseconds.
|
||||
* This is a monotonic clock with an undefined epoch.
|
||||
* @return Time in microseconds.
|
||||
*/
|
||||
uint64_t Now();
|
||||
|
||||
/**
|
||||
* Return the current system time in microseconds since the Unix epoch
|
||||
* (January 1st, 1970 00:00 UTC).
|
||||
*
|
||||
* @return Time in microseconds.
|
||||
*/
|
||||
uint64_t GetSystemTime();
|
||||
|
||||
} // namespace wpi::util
|
||||
#endif
|
||||
|
||||
41
wpiutil/src/main/native/include/wpi/util/timestamp.hpp
Normal file
41
wpiutil/src/main/native/include/wpi/util/timestamp.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) FIRST and other WPILib contributors.
|
||||
// Open Source Software; you can modify and/or share it under the terms of
|
||||
// the WPILib BSD license file in the root directory of this project.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace wpi::util {
|
||||
|
||||
/**
|
||||
* The default implementation used for Now().
|
||||
* In general this is the time returned by the operating system.
|
||||
* @return Time in microseconds.
|
||||
*/
|
||||
uint64_t NowDefault();
|
||||
|
||||
/**
|
||||
* Set the implementation used by Now().
|
||||
* The implementation must return monotonic time in microseconds to maintain
|
||||
* the contract of Now().
|
||||
* @param func Function called by Now() to return the time.
|
||||
*/
|
||||
void SetNowImpl(uint64_t (*func)());
|
||||
|
||||
/**
|
||||
* Return a value representing the current time in microseconds.
|
||||
* This is a monotonic clock with an undefined epoch.
|
||||
* @return Time in microseconds.
|
||||
*/
|
||||
uint64_t Now();
|
||||
|
||||
/**
|
||||
* Return the current system time in microseconds since the Unix epoch
|
||||
* (January 1st, 1970 00:00 UTC).
|
||||
*
|
||||
* @return Time in microseconds.
|
||||
*/
|
||||
uint64_t GetSystemTime();
|
||||
|
||||
} // namespace wpi::util
|
||||
Reference in New Issue
Block a user