diff --git a/hal/include/HAL/Analog.hpp b/hal/include/HAL/Analog.hpp index 981aa9e17c..17523683aa 100644 --- a/hal/include/HAL/Analog.hpp +++ b/hal/include/HAL/Analog.hpp @@ -1,10 +1,6 @@ #pragma once -#ifdef __vxworks -#include -#else #include -#endif enum AnalogTriggerType { diff --git a/hal/include/HAL/Compressor.hpp b/hal/include/HAL/Compressor.hpp index 5c222ebc63..465a63ba64 100644 --- a/hal/include/HAL/Compressor.hpp +++ b/hal/include/HAL/Compressor.hpp @@ -3,11 +3,7 @@ * Methods for interacting with a compressor with the CAN PCM device */ -#ifdef __vxworks -#include -#else #include -#endif #ifndef __HAL_COMPRESSOR_H__ #define __HAL_COMPRESSOR_H__ diff --git a/hal/include/HAL/Digital.hpp b/hal/include/HAL/Digital.hpp index b167728754..caf93c86a6 100644 --- a/hal/include/HAL/Digital.hpp +++ b/hal/include/HAL/Digital.hpp @@ -1,9 +1,5 @@ #pragma once -#ifdef __vxworks -#include -#else #include -#endif #include "HAL/cpp/priority_mutex.h" diff --git a/hal/include/HAL/HAL.hpp b/hal/include/HAL/HAL.hpp index ea5ff402f7..01698642a7 100644 --- a/hal/include/HAL/HAL.hpp +++ b/hal/include/HAL/HAL.hpp @@ -5,11 +5,7 @@ /*----------------------------------------------------------------------------*/ #pragma once -#ifdef __vxworks -#include -#else #include -#endif #include #include "Accelerometer.hpp" diff --git a/hal/include/HAL/Interrupts.hpp b/hal/include/HAL/Interrupts.hpp index 636e809036..a41ca6be0e 100644 --- a/hal/include/HAL/Interrupts.hpp +++ b/hal/include/HAL/Interrupts.hpp @@ -1,10 +1,6 @@ #pragma once -#ifdef __vxworks -#include -#else #include -#endif #include #include "errno.h" diff --git a/hal/include/HAL/Notifier.hpp b/hal/include/HAL/Notifier.hpp index 987686caca..7eae360071 100644 --- a/hal/include/HAL/Notifier.hpp +++ b/hal/include/HAL/Notifier.hpp @@ -1,10 +1,6 @@ #pragma once -#ifdef __vxworks -#include -#else #include -#endif extern "C" { diff --git a/hal/include/HAL/PDP.hpp b/hal/include/HAL/PDP.hpp index 5988702f80..eb0a903906 100644 --- a/hal/include/HAL/PDP.hpp +++ b/hal/include/HAL/PDP.hpp @@ -1,10 +1,6 @@ #pragma once -#ifdef __vxworks -#include -#else #include -#endif extern "C" { diff --git a/hal/include/HAL/Semaphore.hpp b/hal/include/HAL/Semaphore.hpp index 8b81c9526c..e9bb8ba6f9 100644 --- a/hal/include/HAL/Semaphore.hpp +++ b/hal/include/HAL/Semaphore.hpp @@ -1,22 +1,12 @@ #pragma once -#ifdef __vxworks -#include -#else #include #include #include -#endif -#ifdef __vxworks -typedef SEM_ID MUTEX_ID; -typedef SEM_ID SEMAPHORE_ID; -typedef SEM_ID MULTIWAIT_ID; -#else typedef pthread_mutex_t* MUTEX_ID; typedef sem_t* SEMAPHORE_ID; typedef pthread_cond_t* MULTIWAIT_ID; -#endif extern "C" { diff --git a/hal/include/HAL/SerialPort.hpp b/hal/include/HAL/SerialPort.hpp index 07079f9a31..89f1817660 100644 --- a/hal/include/HAL/SerialPort.hpp +++ b/hal/include/HAL/SerialPort.hpp @@ -1,10 +1,6 @@ #pragma once -#ifdef __vxworks -#include -#else #include -#endif extern "C" { @@ -26,4 +22,4 @@ extern "C" void serialFlush(uint8_t port, int32_t *status); void serialClear(uint8_t port, int32_t *status); void serialClose(uint8_t port, int32_t *status); -} \ No newline at end of file +} diff --git a/hal/include/HAL/Solenoid.hpp b/hal/include/HAL/Solenoid.hpp index 06114e36b8..df06a33b77 100644 --- a/hal/include/HAL/Solenoid.hpp +++ b/hal/include/HAL/Solenoid.hpp @@ -1,10 +1,6 @@ #pragma once -#ifdef __vxworks -#include -#else #include -#endif extern "C" { diff --git a/hal/include/HAL/Task.hpp b/hal/include/HAL/Task.hpp index 1c8c690b3f..3feeec8fc2 100644 --- a/hal/include/HAL/Task.hpp +++ b/hal/include/HAL/Task.hpp @@ -1,11 +1,7 @@ #pragma once -#ifdef __vxworks -#include -#else #include #include -#endif #ifndef _FUNCPTR_DEFINED #define _FUNCPTR_DEFINED @@ -22,36 +18,23 @@ typedef int (*FUNCPTR) (); /* ptr to function returning int */ typedef int STATUS; #endif /* _STATUS_DEFINED */ -#ifdef __vxworks -#define NULL_TASK -1 -typedef int32_t TASK; -#else +#ifndef OK +#define OK 0 +#endif /* OK */ +#ifndef ERROR +#define ERROR (-1) +#endif /* ERROR */ + #define NULL_TASK NULL typedef pthread_t* TASK; -#endif extern "C" { // Note: These constants used to be declared extern and were defined in // Task.cpp. This caused issues with the JNI bindings for java, and so the // instantiations were moved here. - const uint32_t VXWORKS_FP_TASK = 0x01000000; - const int32_t HAL_objLib_OBJ_ID_ERROR = -1; // TODO: update to relevant TaskIDError - const int32_t HAL_objLib_OBJ_DELETED = -1; // TODO: update to relevant TaskDeletedError - const int32_t HAL_taskLib_ILLEGAL_OPTIONS = -1; // TODO: update to relevant TaskOptionsError - const int32_t HAL_memLib_NOT_ENOUGH_MEMORY = -1; // TODO: update to relevant TaskMemoryError - const int32_t HAL_taskLib_ILLEGAL_PRIORITY = -1; // TODO: update to relevant TaskPriorityError - - TASK spawnTask(char * name, int priority, int options, int stackSize, FUNCPTR entryPt, - uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, - uint32_t arg5, uint32_t arg6, uint32_t arg7, uint32_t arg8, uint32_t arg9); - STATUS restartTask(TASK task); - STATUS deleteTask(TASK task); - STATUS isTaskReady(TASK task); - STATUS isTaskSuspended(TASK task); - STATUS suspendTask(TASK task); - STATUS resumeTask(TASK task); - STATUS verifyTaskID(TASK task); - STATUS setTaskPriority(TASK task, int priority); - STATUS getTaskPriority(TASK task, int* priority); + const int32_t HAL_taskLib_ILLEGAL_PRIORITY = 22; // 22 is EINVAL + STATUS verifyTaskID(TASK task); + STATUS setTaskPriority(TASK task, int priority); // valid priority [1..99] + STATUS getTaskPriority(TASK task, int* priority); } diff --git a/hal/include/HAL/Utilities.hpp b/hal/include/HAL/Utilities.hpp index b24cd29776..df8ff5e83e 100644 --- a/hal/include/HAL/Utilities.hpp +++ b/hal/include/HAL/Utilities.hpp @@ -1,10 +1,6 @@ #pragma once -#ifdef __vxworks -#include -#else #include -#endif extern "C" { diff --git a/hal/include/HAL/cpp/Resource.hpp b/hal/include/HAL/cpp/Resource.hpp index b40a0f611b..999c4b62c1 100644 --- a/hal/include/HAL/cpp/Resource.hpp +++ b/hal/include/HAL/cpp/Resource.hpp @@ -6,12 +6,8 @@ #pragma once #include "../Errors.hpp" -#ifdef __vxworks -#include -#else -#include -#endif #include "HAL/cpp/priority_mutex.h" +#include /** * The Resource class is a convenient way to track allocated resources. diff --git a/hal/lib/Athena/NetworkCommunication/CANSessionMux.h b/hal/lib/Athena/NetworkCommunication/CANSessionMux.h index 3f8a6f192f..aa56a63b3c 100644 --- a/hal/lib/Athena/NetworkCommunication/CANSessionMux.h +++ b/hal/lib/Athena/NetworkCommunication/CANSessionMux.h @@ -8,11 +8,7 @@ #ifndef __CANSessionMux_h__ #define __CANSessionMux_h__ -#if defined(__vxworks) -#include -#else #include -#endif #define CAN_SEND_PERIOD_NO_REPEAT 0 #define CAN_SEND_PERIOD_STOP_REPEATING -1 diff --git a/hal/lib/Athena/NetworkCommunication/FRCComm.h b/hal/lib/Athena/NetworkCommunication/FRCComm.h index 26df7e18e1..ed094aa7c8 100644 --- a/hal/lib/Athena/NetworkCommunication/FRCComm.h +++ b/hal/lib/Athena/NetworkCommunication/FRCComm.h @@ -22,15 +22,10 @@ #define EXPORT_FUNC __declspec(dllexport) __cdecl #endif #else -#if defined(__vxworks) -#include -#define EXPORT_FUNC -#else #include #include #define EXPORT_FUNC #endif -#endif #define ERR_FRCSystem_NetCommNotResponding -44049 #define ERR_FRCSystem_NoDSConnection -44018 @@ -52,7 +47,6 @@ enum MatchType_t { }; struct ControlWord_t { -#ifndef __vxworks uint32_t enabled : 1; uint32_t autonomous : 1; uint32_t test :1; @@ -60,15 +54,6 @@ struct ControlWord_t { uint32_t fmsAttached:1; uint32_t dsAttached:1; uint32_t control_reserved : 26; -#else - uint32_t control_reserved : 26; - uint32_t dsAttached:1; - uint32_t fmsAttached:1; - uint32_t eStop : 1; - uint32_t test :1; - uint32_t autonomous : 1; - uint32_t enabled : 1; -#endif }; struct JoystickAxes_t { @@ -96,11 +81,7 @@ extern "C" { #ifdef SIMULATION void EXPORT_FUNC setNewDataSem(HANDLE); #else -# if defined (__vxworks) - void EXPORT_FUNC setNewDataSem(SEM_ID); -# else void EXPORT_FUNC setNewDataSem(pthread_cond_t *); -# endif #endif // this uint32_t is really a LVRefNum diff --git a/hal/lib/Athena/NetworkCommunication/LoadOut.h b/hal/lib/Athena/NetworkCommunication/LoadOut.h index fce88a28e2..5f43f21b14 100644 --- a/hal/lib/Athena/NetworkCommunication/LoadOut.h +++ b/hal/lib/Athena/NetworkCommunication/LoadOut.h @@ -5,9 +5,6 @@ #ifdef SIMULATION #include #define EXPORT_FUNC __declspec(dllexport) __cdecl -#elif defined (__vxworks) -#include -#define EXPORT_FUNC #else #include #define EXPORT_FUNC @@ -16,7 +13,7 @@ #define kMaxModuleNumber 2 namespace nLoadOut { -#if defined(__vxworks) || defined(SIMULATION) +#if defined(SIMULATION) typedef enum { kModuleType_Unknown = 0x00, kModuleType_Analog = 0x01, @@ -31,7 +28,7 @@ namespace nLoadOut kTargetClass_FRC2 = 0x20, kTargetClass_FRC3 = 0x30, kTargetClass_RoboRIO = 0x40, -#if defined(__vxworks) || defined(SIMULATION) +#if defined(SIMULATION) kTargetClass_FRC2_Analog = kTargetClass_FRC2 | kModuleType_Analog, kTargetClass_FRC2_Digital = kTargetClass_FRC2 | kModuleType_Digital, kTargetClass_FRC2_Solenoid = kTargetClass_FRC2 | kModuleType_Solenoid, @@ -46,7 +43,7 @@ namespace nLoadOut extern "C" { #endif -#if defined(__vxworks) || defined(SIMULATION) +#if defined(SIMULATION) uint32_t EXPORT_FUNC FRC_NetworkCommunication_nLoadOut_getModulePresence(uint32_t moduleType, uint8_t moduleNumber); #endif uint32_t EXPORT_FUNC FRC_NetworkCommunication_nLoadOut_getTargetClass(); diff --git a/hal/lib/Athena/NetworkCommunication/UsageReporting.h b/hal/lib/Athena/NetworkCommunication/UsageReporting.h index 0ec2a3a4ea..267e006665 100644 --- a/hal/lib/Athena/NetworkCommunication/UsageReporting.h +++ b/hal/lib/Athena/NetworkCommunication/UsageReporting.h @@ -5,9 +5,6 @@ #ifdef SIMULATION #include #define EXPORT_FUNC __declspec(dllexport) __cdecl -#elif defined (__vxworks) -#include -#define EXPORT_FUNC #else #include #include diff --git a/hal/lib/Athena/Task.cpp b/hal/lib/Athena/Task.cpp index 688e3732ad..9e4b2e9ac0 100644 --- a/hal/lib/Athena/Task.cpp +++ b/hal/lib/Athena/Task.cpp @@ -1,4 +1,3 @@ - #include "HAL/Task.hpp" #ifndef OK @@ -8,86 +7,10 @@ #define ERROR (-1) #endif /* ERROR */ -#include #include - -struct TaskArgs { - FUNCPTR fun; - char* name; - pthread_t** task; - uint32_t arg0, arg1, arg2, arg3, arg4, - arg5, arg6, arg7, arg8, arg9; -}; - -void* startRoutine(void* data) { - TaskArgs* args = (TaskArgs*) data; - printf("[HAL] Starting task %s...\n", args->name); - int val = args->fun(args->arg0, args->arg1, args->arg2, args->arg3, args->arg4, - args->arg5, args->arg6, args->arg7, args->arg8, args->arg9); - printf("[HAL] Exited task %s with code %i\n", args->name, val); - *args->task = NULL; - int* ret = new int(); *ret = val; - return ret; -} - -/** - * @param priority Not implemented. - * @param options Not implemented. - * @param stackSize Not implemented. - */ -TASK spawnTask(char * name, int priority, int options, int stackSize, - FUNCPTR entryPt, uint32_t arg0, uint32_t arg1, uint32_t arg2, - uint32_t arg3, uint32_t arg4, uint32_t arg5, uint32_t arg6, - uint32_t arg7, uint32_t arg8, uint32_t arg9) { - printf("[HAL] Spawning task %s...\n", name); - pthread_t* task = new pthread_t; - pthread_attr_t* attr = new pthread_attr_t; - pthread_attr_init(attr); - TaskArgs* args = new TaskArgs(); - args->fun = entryPt; - args->name = name; - args->task = new pthread_t*; - *args->task = task; - args->arg0 = arg0; args->arg1 = arg1; args->arg2 = arg2; args->arg3 = arg3; args->arg4 = arg4; - args->arg5 = arg5; args->arg6 = arg6; args->arg7 = arg7; args->arg8 = arg8; args->arg9 = arg9; - if (pthread_create(task, attr, startRoutine, args) == 0) { - printf("[HAL] Success\n"); - pthread_detach(*task); - } else { - printf("[HAL] Failure\n"); - task = NULL; - } - pthread_attr_destroy(attr); - return task; -} - -STATUS restartTask(TASK task) { - return ERROR; // TODO: implement; -} - -STATUS deleteTask(TASK task) { - return ERROR; // TODO: implement -} - -STATUS isTaskReady(TASK task) { - return ERROR; // TODO: implement -} - -STATUS isTaskSuspended(TASK task) { - return ERROR; // TODO: implement -} - -STATUS suspendTask(TASK task) { - return ERROR; // TODO: implement -} - -STATUS resumeTask(TASK task) { - return ERROR; // TODO: implement -} - STATUS verifyTaskID(TASK task) { - if (task != NULL && pthread_kill(*task, 0) == 0) { + if (task != nullptr && pthread_kill(*task, 0) == 0) { return OK; } else { return ERROR; @@ -95,9 +18,34 @@ STATUS verifyTaskID(TASK task) { } STATUS setTaskPriority(TASK task, int priority) { - return ERROR; // TODO: implement + int policy = 0; + struct sched_param param; + + if (verifyTaskID(task) == OK && + pthread_getschedparam(*task, &policy, ¶m) == 0) { + param.sched_priority = priority; + if (pthread_setschedparam(*task, SCHED_FIFO, ¶m) == 0) { + return OK; + } + else { + return ERROR; + } + } + else { + return ERROR; + } } STATUS getTaskPriority(TASK task, int* priority) { - return ERROR; // TODO: implement + int policy = 0; + struct sched_param param; + + if (verifyTaskID(task) == OK && + pthread_getschedparam(*task, &policy, ¶m) == 0) { + *priority = param.sched_priority; + return OK; + } + else { + return ERROR; + } } diff --git a/networktables/cpp/include/NTErrorBase.h b/networktables/cpp/include/NTErrorBase.h index e76388f50b..0f28a9b660 100644 --- a/networktables/cpp/include/NTErrorBase.h +++ b/networktables/cpp/include/NTErrorBase.h @@ -7,11 +7,8 @@ #ifndef _ERROR_BASE_H #define _ERROR_BASE_H -#if (defined __vxworks || defined WIN32) +#if defined WIN32 #include -#ifdef __vxworks -#include -#endif #define DISALLOW_COPY_AND_ASSIGN(ErrorBase) @@ -44,4 +41,4 @@ public: }; #endif -#endif // __vxworks +#endif // WIN32 diff --git a/networktables/cpp/include/OSAL/Synchronized.h b/networktables/cpp/include/OSAL/Synchronized.h index bcf463412b..15deb2b2e8 100644 --- a/networktables/cpp/include/OSAL/Synchronized.h +++ b/networktables/cpp/include/OSAL/Synchronized.h @@ -10,11 +10,8 @@ #define NT_CRITICAL_REGION(s) { NTSynchronized _sync(s); #define NT_END_REGION } -#if (defined __vxworks || defined WIN32) +#if defined WIN32 -#ifdef __vxworks -#include -#endif #include class NTReentrantSemaphore @@ -62,7 +59,7 @@ private: pthread_mutexattr_t mta; pthread_mutex_t m_semaphore; }; -#endif // __vxworks +#endif // WIN32 /** * Provide easy support for critical regions. @@ -79,12 +76,12 @@ class NTSynchronized public: explicit NTSynchronized(NTReentrantSemaphore&); //TODO remove vxworks SEM_ID support -#if (defined __vxworks || defined WIN32) +#if defined WIN32 explicit NTSynchronized(SEM_ID); #endif virtual ~NTSynchronized(); private: -#if (defined __vxworks || defined WIN32) +#if defined WIN32 bool usingSem; NTReentrantSemaphore* m_sem; SEM_ID m_semaphore; diff --git a/networktables/cpp/include/OSAL/Task.h b/networktables/cpp/include/OSAL/Task.h index 65620300a4..8e5b991af0 100644 --- a/networktables/cpp/include/OSAL/Task.h +++ b/networktables/cpp/include/OSAL/Task.h @@ -7,12 +7,9 @@ #ifndef __NTTASK_H__ #define __NTTASK_H__ -#if (defined __vxworks || defined WIN32) +#if defined WIN32 #include "NTErrorBase.h" -#ifdef __vxworks -#include -#endif /** * WPI task is a wrapper for the native Task object. @@ -72,5 +69,5 @@ private: DISALLOW_COPY_AND_ASSIGN(NTTask); }; -#endif // __vxworks +#endif // WIN32 #endif // __TASK_H__ diff --git a/networktables/cpp/include/networktables2/thread/DefaultThreadManager.h b/networktables/cpp/include/networktables2/thread/DefaultThreadManager.h index 9519a7ab67..a4394d44b2 100644 --- a/networktables/cpp/include/networktables2/thread/DefaultThreadManager.h +++ b/networktables/cpp/include/networktables2/thread/DefaultThreadManager.h @@ -17,7 +17,7 @@ class PeriodicNTThread; #include "networktables2/thread/NTThreadManager.h" #include "networktables2/thread/NTThread.h" -#if (defined __vxworks || defined WIN32) +#if defined WIN32 #include "OSAL/Task.h" #else #include @@ -30,7 +30,7 @@ public: class PeriodicNTThread : public NTThread { private: -#if (defined __vxworks || defined WIN32) +#if defined WIN32 const char* name; NTTask* thread; #else @@ -38,7 +38,7 @@ private: #endif PeriodicRunnable* r; bool run; -#if (defined __vxworks || defined WIN32) +#if defined WIN32 int _taskMain(); static int taskMain(PeriodicNTThread* o); #else//TODO make return int for pthread as well diff --git a/wpilibc/wpilibC++/include/Error.h b/wpilibc/wpilibC++/include/Error.h index 9b804ff174..828dfca2e5 100644 --- a/wpilibc/wpilibC++/include/Error.h +++ b/wpilibc/wpilibC++/include/Error.h @@ -33,9 +33,6 @@ class Error { void Set(Code code, const char* contextMessage, const char* filename, const char* function, uint32_t lineNumber, const ErrorBase* originatingObject); - static void EnableSuspendOnError(bool enable) { - m_suspendOnErrorEnabled = enable; - } private: void Report(); @@ -48,6 +45,5 @@ class Error { const ErrorBase* m_originatingObject = nullptr; double m_timestamp = 0.0; - static bool m_suspendOnErrorEnabled; DISALLOW_COPY_AND_ASSIGN(Error); }; diff --git a/wpilibc/wpilibC++/include/Task.h b/wpilibc/wpilibC++/include/Task.h index a394d46d1d..5a8e9f5a57 100644 --- a/wpilibc/wpilibC++/include/Task.h +++ b/wpilibc/wpilibC++/include/Task.h @@ -8,6 +8,9 @@ #include "ErrorBase.h" #include "HAL/Task.hpp" +#include +#include +#include /** * WPI task is a wrapper for the native Task object. @@ -15,38 +18,40 @@ **/ class Task : public ErrorBase { public: - static const uint32_t kDefaultPriority = 101; + static const uint32_t kDefaultPriority = 60; + + Task() = default; + Task(const Task&) = delete; + Task& operator=(const Task&) = delete; + Task& operator=(Task&& task); + + template + Task(const char* name, Function&& function, Args&&... args); - Task(const char* name, FUNCPTR function, int32_t priority = kDefaultPriority, - uint32_t stackSize = 20000); virtual ~Task(); - bool Start(uint32_t arg0 = 0, uint32_t arg1 = 0, uint32_t arg2 = 0, - uint32_t arg3 = 0, uint32_t arg4 = 0, uint32_t arg5 = 0, - uint32_t arg6 = 0, uint32_t arg7 = 0, uint32_t arg8 = 0, - uint32_t arg9 = 0); - bool Restart(); - bool Stop(); + bool joinable() const noexcept; + void join(); + void detach(); + std::thread::id get_id() const noexcept; + std::thread::native_handle_type native_handle(); - bool IsReady() const; - bool IsSuspended() const; - - bool Suspend(); - bool Resume(); - - bool Verify() const; + bool Verify(); int32_t GetPriority(); + + /** + * @param priority The priority at which the internal thread should run. + * Must be within range 1 to 99 inclusive for pthreads. + */ bool SetPriority(int32_t priority); - const char* GetName() const; - TASK GetID() const; + + std::string GetName() const; private: - FUNCPTR m_function; - char* m_taskName; - TASK m_taskID = NULL_TASK; - uint32_t m_stackSize; - int m_priority; + std::thread m_thread; + std::string m_taskName; bool HandleError(STATUS results); - DISALLOW_COPY_AND_ASSIGN(Task); }; + +#include "Task.inc" diff --git a/wpilibc/wpilibC++/include/Task.inc b/wpilibc/wpilibC++/include/Task.inc new file mode 100644 index 0000000000..26277ab359 --- /dev/null +++ b/wpilibc/wpilibC++/include/Task.inc @@ -0,0 +1,25 @@ +#include "HAL/HAL.hpp" +#include + +/** + * Create and launch a task. + * @param name The name of the task. "FRC_" will be prepended to the task name. + * @param function The address of the function to run as the new task. + * @param args A parameter pack of arguments to pass to the function. + * @param priority The VxWorks priority for the task. + * @param stackSize The size of the stack for the task + */ +template +Task::Task(const char* name, Function&& function, Args&&... args) { + m_taskName = "FRC_"; + m_taskName += name; + + std::cout << "[HAL] Starting task " << m_taskName << "..." << std::endl; + + m_thread = std::thread(function, args...); + SetPriority(kDefaultPriority); + + static std::atomic instances{0}; + instances++; + HALReport(HALUsageReporting::kResourceType_Task, instances, 0, m_taskName.c_str()); +} diff --git a/wpilibc/wpilibC++/src/Error.cpp b/wpilibc/wpilibC++/src/Error.cpp index 4b109d1820..0f566c2397 100644 --- a/wpilibc/wpilibC++/src/Error.cpp +++ b/wpilibc/wpilibC++/src/Error.cpp @@ -16,7 +16,6 @@ #include "DriverStation.h" #include "Timer.h" #include "Utility.h" -bool Error::m_suspendOnErrorEnabled = false; Error::Error() {} diff --git a/wpilibc/wpilibC++Devices/include/DriverStation.h b/wpilibc/wpilibC++Devices/include/DriverStation.h index 96338cde64..ce278f49ac 100644 --- a/wpilibc/wpilibC++Devices/include/DriverStation.h +++ b/wpilibc/wpilibC++Devices/include/DriverStation.h @@ -13,6 +13,7 @@ #include "HAL/cpp/priority_mutex.h" #include "HAL/cpp/priority_condition_variable.h" #include +#include struct HALControlWord; class AnalogInput; @@ -92,7 +93,6 @@ class DriverStation : public SensorBase, public RobotStateInterface { void GetData(); private: - static void InitTask(DriverStation *ds); static DriverStation *m_instance; void ReportJoystickUnpluggedError(std::string message); void Run(); @@ -102,7 +102,8 @@ class DriverStation : public SensorBase, public RobotStateInterface { HALJoystickButtons m_joystickButtons[kJoystickPorts]; HALJoystickDescriptor m_joystickDescriptor[kJoystickPorts]; #ifndef FRC_SIMULATOR - Task m_task{"DriverStation", (FUNCPTR)DriverStation::InitTask}; + Task m_task; + std::atomic m_isRunning{false}; #endif mutable Semaphore m_newControlData{Semaphore::kEmpty}; mutable priority_condition_variable m_packetDataAvailableCond; diff --git a/wpilibc/wpilibC++Devices/include/NetworkCommunication/CANSessionMux.h b/wpilibc/wpilibC++Devices/include/NetworkCommunication/CANSessionMux.h index 5ee4046adf..75afad964e 100644 --- a/wpilibc/wpilibC++Devices/include/NetworkCommunication/CANSessionMux.h +++ b/wpilibc/wpilibC++Devices/include/NetworkCommunication/CANSessionMux.h @@ -8,11 +8,7 @@ #ifndef __CANSessionMux_h__ #define __CANSessionMux_h__ -#if defined(__vxworks) -#include -#else #include -#endif #define CAN_SEND_PERIOD_NO_REPEAT 0 #define CAN_SEND_PERIOD_STOP_REPEATING -1 diff --git a/wpilibc/wpilibC++Devices/include/NetworkCommunication/FRCComm.h b/wpilibc/wpilibC++Devices/include/NetworkCommunication/FRCComm.h index d7eb65c45d..f58fc7e210 100644 --- a/wpilibc/wpilibC++Devices/include/NetworkCommunication/FRCComm.h +++ b/wpilibc/wpilibC++Devices/include/NetworkCommunication/FRCComm.h @@ -22,15 +22,10 @@ #define EXPORT_FUNC __declspec(dllexport) __cdecl #endif #else -#if defined(__vxworks) -#include -#define EXPORT_FUNC -#else #include #include #define EXPORT_FUNC #endif -#endif #define ERR_FRCSystem_NetCommNotResponding -44049 #define ERR_FRCSystem_NoDSConnection -44018 @@ -52,7 +47,6 @@ enum MatchType_t { }; struct ControlWord_t { -#ifndef __vxworks uint32_t enabled : 1; uint32_t autonomous : 1; uint32_t test : 1; @@ -60,15 +54,6 @@ struct ControlWord_t { uint32_t fmsAttached : 1; uint32_t dsAttached : 1; uint32_t control_reserved : 26; -#else - uint32_t control_reserved : 26; - uint32_t dsAttached : 1; - uint32_t fmsAttached : 1; - uint32_t eStop : 1; - uint32_t test : 1; - uint32_t autonomous : 1; - uint32_t enabled : 1; -#endif }; struct JoystickAxes_t { @@ -98,12 +83,8 @@ int EXPORT_FUNC setErrorData(const char *errors, int errorsLength, int wait_ms); #ifdef SIMULATION void EXPORT_FUNC setNewDataSem(HANDLE); #else -#if defined(__vxworks) -void EXPORT_FUNC setNewDataSem(SEM_ID); -#else void EXPORT_FUNC setNewDataSem(pthread_cond_t *); #endif -#endif // this uint32_t is really a LVRefNum int EXPORT_FUNC setNewDataOccurRef(uint32_t refnum); diff --git a/wpilibc/wpilibC++Devices/include/NetworkCommunication/LoadOut.h b/wpilibc/wpilibC++Devices/include/NetworkCommunication/LoadOut.h index c9dad8bcc6..11b0637bec 100644 --- a/wpilibc/wpilibC++Devices/include/NetworkCommunication/LoadOut.h +++ b/wpilibc/wpilibC++Devices/include/NetworkCommunication/LoadOut.h @@ -5,9 +5,6 @@ #ifdef SIMULATION #include #define EXPORT_FUNC __declspec(dllexport) __cdecl -#elif defined(__vxworks) -#include -#define EXPORT_FUNC #else #include #define EXPORT_FUNC @@ -15,7 +12,7 @@ #define kMaxModuleNumber 2 namespace nLoadOut { -#if defined(__vxworks) || defined(SIMULATION) +#if defined(SIMULATION) typedef enum { kModuleType_Unknown = 0x00, kModuleType_Analog = 0x01, @@ -31,7 +28,7 @@ typedef enum { kTargetClass_FRC2 = 0x20, kTargetClass_FRC3 = 0x30, kTargetClass_RoboRIO = 0x40, -#if defined(__vxworks) || defined(SIMULATION) +#if defined(SIMULATION) kTargetClass_FRC2_Analog = kTargetClass_FRC2 | kModuleType_Analog, kTargetClass_FRC2_Digital = kTargetClass_FRC2 | kModuleType_Digital, kTargetClass_FRC2_Solenoid = kTargetClass_FRC2 | kModuleType_Solenoid, @@ -46,7 +43,7 @@ tTargetClass EXPORT_FUNC getTargetClass(); extern "C" { #endif -#if defined(__vxworks) || defined(SIMULATION) +#if defined(SIMULATION) uint32_t EXPORT_FUNC FRC_NetworkCommunication_nLoadOut_getModulePresence(uint32_t moduleType, uint8_t moduleNumber); diff --git a/wpilibc/wpilibC++Devices/include/NetworkCommunication/UsageReporting.h b/wpilibc/wpilibC++Devices/include/NetworkCommunication/UsageReporting.h index 693d0dc9c1..ac31d75474 100644 --- a/wpilibc/wpilibC++Devices/include/NetworkCommunication/UsageReporting.h +++ b/wpilibc/wpilibC++Devices/include/NetworkCommunication/UsageReporting.h @@ -5,9 +5,6 @@ #ifdef SIMULATION #include #define EXPORT_FUNC __declspec(dllexport) __cdecl -#elif defined(__vxworks) -#include -#define EXPORT_FUNC #else #include #include diff --git a/wpilibc/wpilibC++Devices/include/Preferences.h b/wpilibc/wpilibC++Devices/include/Preferences.h index 82afa02a2e..927af5f8c0 100644 --- a/wpilibc/wpilibC++Devices/include/Preferences.h +++ b/wpilibc/wpilibC++Devices/include/Preferences.h @@ -73,15 +73,6 @@ class Preferences : public ErrorBase, public ITableListener { void ReadTaskRun(); void WriteTaskRun(); - static int InitReadTask(Preferences *obj) { - obj->ReadTaskRun(); - return 0; - } - static int InitWriteTask(Preferences *obj) { - obj->WriteTaskRun(); - return 0; - } - /** The semaphore for accessing the file */ priority_recursive_mutex m_fileLock; /** The semaphore for beginning reads and writes to the file */ diff --git a/wpilibc/wpilibC++Devices/include/Ultrasonic.h b/wpilibc/wpilibC++Devices/include/Ultrasonic.h index 620d57b89d..420fadf5f2 100644 --- a/wpilibc/wpilibC++Devices/include/Ultrasonic.h +++ b/wpilibc/wpilibC++Devices/include/Ultrasonic.h @@ -10,6 +10,7 @@ #include "Task.h" #include "PIDSource.h" #include "LiveWindow/LiveWindowSendable.h" +#include #include "HAL/cpp/priority_mutex.h" @@ -74,14 +75,14 @@ class Ultrasonic : public SensorBase, static constexpr double kPingTime = 10 * 1e-6; ///< Time (sec) for the ping trigger pulse. static const uint32_t kPriority = - 90; ///< Priority that the ultrasonic round robin task runs. + 64; ///< Priority that the ultrasonic round robin task runs. static constexpr double kMaxUltrasonicTime = 0.1; ///< Max time (ms) between readings. static constexpr double kSpeedOfSoundInchesPerSec = 1130.0 * 12.0; static Task m_task; // task doing the round-robin automatic sensing static Ultrasonic *m_firstSensor; // head of the ultrasonic sensor list - static bool m_automaticEnabled; // automatic round robin mode + static std::atomic m_automaticEnabled; // automatic round robin mode static priority_mutex m_mutex; // synchronize access to the list of sensors DigitalInput *m_echoChannel; diff --git a/wpilibc/wpilibC++Devices/src/DriverStation.cpp b/wpilibc/wpilibC++Devices/src/DriverStation.cpp index a72944bf6a..ce40bd70c6 100644 --- a/wpilibc/wpilibC++Devices/src/DriverStation.cpp +++ b/wpilibc/wpilibC++Devices/src/DriverStation.cpp @@ -50,28 +50,21 @@ DriverStation::DriverStation() { AddToSingletonList(); - // They need to be identical or it could lead to runtime stack corruption if - // the caller and callee push and pop different amounts of data on the stack. - static_assert(sizeof(this) == sizeof(uint32_t), - "We are passing a pointer through a uint32_t"); - if (!m_task.Start((uint32_t) this)) { - wpi_setWPIError(DriverStationTaskError); - } + m_task = Task("DriverStation", &DriverStation::Run, this); } DriverStation::~DriverStation() { - m_task.Stop(); + m_isRunning = false; + m_task.join(); + // Unregister our semaphore. HALSetNewDataSem(nullptr); } -// XXX: This assumes that the calling convention treats pointers and uint32_ts -// identical, which is not necessarily true. -void DriverStation::InitTask(DriverStation* ds) { ds->Run(); } - void DriverStation::Run() { + m_isRunning = true; int period = 0; - while (true) { + while (m_isRunning) { { std::unique_lock lock(m_packetDataAvailableMutex); m_packetDataAvailableCond.wait(lock); diff --git a/wpilibc/wpilibC++Devices/src/Preferences.cpp b/wpilibc/wpilibC++Devices/src/Preferences.cpp index 9284bb56a6..a9255d598e 100644 --- a/wpilibc/wpilibC++Devices/src/Preferences.cpp +++ b/wpilibc/wpilibC++Devices/src/Preferences.cpp @@ -24,11 +24,9 @@ static const char *kValuePrefix = "=\""; /** The characters to put after the value */ static const char *kValueSuffix = "\"\n"; -Preferences::Preferences() - : m_readTask("PreferencesReadTask", (FUNCPTR)Preferences::InitReadTask), - m_writeTask("PreferencesWriteTask", (FUNCPTR)Preferences::InitWriteTask) { +Preferences::Preferences() { std::unique_lock sync(m_fileLock); - m_readTask.Start((uint32_t) this); + m_readTask = Task("PreferencesReadTask", &Preferences::ReadTaskRun, this); /* The main thread initially blocks on the semaphore. The read task signals * the main thread to continue after it has locked the table mutex (so the @@ -293,7 +291,7 @@ void Preferences::PutLong(const char *key, int64_t value) { */ void Preferences::Save() { std::unique_lock sync(m_fileLock); - m_writeTask.Start((uint32_t) this); + m_writeTask = Task("PreferencesWriteTask", &Preferences::WriteTaskRun, this); m_fileOpStarted.take(); } diff --git a/wpilibc/wpilibC++Devices/src/RobotBase.cpp b/wpilibc/wpilibC++Devices/src/RobotBase.cpp index 36488e4447..fd1fc4ee99 100644 --- a/wpilibc/wpilibC++Devices/src/RobotBase.cpp +++ b/wpilibc/wpilibC++Devices/src/RobotBase.cpp @@ -19,13 +19,6 @@ #include "HAL/HAL.hpp" #include -#ifdef __vxworks -// VXWorks needs som special unloading code -#include -#include -#include -#endif - RobotBase *RobotBase::m_instance = nullptr; void RobotBase::setInstance(RobotBase *robot) { diff --git a/wpilibc/wpilibC++Devices/src/Task.cpp b/wpilibc/wpilibC++Devices/src/Task.cpp index 2c8bf2d2f9..2a802dfc5a 100644 --- a/wpilibc/wpilibC++Devices/src/Task.cpp +++ b/wpilibc/wpilibC++Devices/src/Task.cpp @@ -12,7 +12,6 @@ #include #include #include -#include "HAL/HAL.hpp" #ifndef OK #define OK 0 @@ -23,115 +22,57 @@ const uint32_t Task::kDefaultPriority; -/** - * Create but don't launch a task. - * @param name The name of the task. "FRC_" will be prepended to the task name. - * @param function The address of the function to run as the new task. - * @param priority The VxWorks priority for the task. - * @param stackSize The size of the stack for the task - */ -Task::Task(const char* name, FUNCPTR function, int32_t priority, - uint32_t stackSize) { - m_function = function; - m_priority = priority; - m_stackSize = stackSize; - m_taskName = new char[strlen(name) + 5]; - strcpy(m_taskName, "FRC_"); - strcpy(m_taskName + 4, name); +Task& Task::operator=(Task&& task) { + m_thread.swap(task.m_thread); + m_taskName = std::move(task.m_taskName); - static int32_t instances = 0; - instances++; - HALReport(HALUsageReporting::kResourceType_Task, instances, 0, m_taskName); + return *this; } Task::~Task() { - if (m_taskID != NULL_TASK) Stop(); - delete[] m_taskName; - m_taskName = nullptr; -} - -/** - * Starts this task. - * If it is already running or unable to start, it fails and returns false. - */ -bool Task::Start(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, - uint32_t arg4, uint32_t arg5, uint32_t arg6, uint32_t arg7, - uint32_t arg8, uint32_t arg9) { - m_taskID = spawnTask( - m_taskName, m_priority, - VXWORKS_FP_TASK, // options - m_stackSize, // stack size - m_function, // function to start - arg0, arg1, arg2, arg3, arg4, // parameter 1 - pointer to this class - arg5, arg6, arg7, arg8, arg9); // additional unused parameters - if (m_taskID == NULL_TASK) { - HandleError(ERROR); - return false; + if (m_thread.joinable()) { + std::cout << "[HAL] Exited task " << m_taskName << std::endl; } - return true; } -/** - * Restarts a running task. - * If the task isn't started, it starts it. - * @return false if the task is running and we are unable to kill the previous - * instance - */ -bool Task::Restart() { return HandleError(restartTask(m_taskID)); } - -/** - * Kills the running task. - * @returns true on success false if the task doesn't exist or we are unable to - * kill it. - */ -bool Task::Stop() { - bool ok = true; - if (Verify()) { - ok = HandleError(deleteTask(m_taskID)); - } - m_taskID = NULL_TASK; - return ok; +bool Task::joinable() const noexcept { + return m_thread.joinable(); } -/** - * Returns true if the task is ready to execute (i.e. not suspended, delayed, or - * blocked). - * @return true if ready, false if not ready. - */ -bool Task::IsReady() const { return isTaskReady(m_taskID); } +void Task::join() { + m_thread.join(); +} -/** - * Returns true if the task was explicitly suspended by calling Suspend() - * @return true if suspended, false if not suspended. - */ -bool Task::IsSuspended() const { return isTaskSuspended(m_taskID); } +void Task::detach() { + m_thread.detach(); +} -/** - * Pauses a running task. - * Returns true on success, false if unable to pause or the task isn't running. - */ -bool Task::Suspend() { return HandleError(suspendTask(m_taskID)); } +std::thread::id Task::get_id() const noexcept { + return m_thread.get_id(); +} -/** - * Resumes a paused task. - * Returns true on success, false if unable to resume or if the task isn't - * running/paused. - */ -bool Task::Resume() { return HandleError(resumeTask(m_taskID)); } +std::thread::native_handle_type Task::native_handle() { + return m_thread.native_handle(); +} /** * Verifies a task still exists. * @returns true on success. */ -bool Task::Verify() const { return verifyTaskID(m_taskID) == OK; } +bool Task::Verify() { + TASK id = (TASK)m_thread.native_handle(); + return verifyTaskID(id) == OK; +} /** * Gets the priority of a task. * @returns task priority or 0 if an error occured */ int32_t Task::GetPriority() { - if (HandleError(getTaskPriority(m_taskID, &m_priority))) - return m_priority; + int priority; + auto id = m_thread.native_handle(); + if (HandleError(getTaskPriority(&id, &priority))) + return priority; else return 0; } @@ -144,25 +85,15 @@ int32_t Task::GetPriority() { * @returns true on success. */ bool Task::SetPriority(int32_t priority) { - m_priority = priority; - return HandleError(setTaskPriority(m_taskID, m_priority)); + auto id = m_thread.native_handle(); + return HandleError(setTaskPriority(&id, priority)); } /** * Returns the name of the task. * @returns Pointer to the name of the task or nullptr if not allocated */ -const char* Task::GetName() const { return m_taskName; } - -/** - * Get the ID of a task - * @returns Task ID of this task. Task::kInvalidTaskID (-1) if the task has not - * been started or has already exited. - */ -TASK Task::GetID() const { - if (Verify()) return m_taskID; - return NULL_TASK; -} +std::string Task::GetName() const { return m_taskName; } /** * Handles errors generated by task related code. @@ -170,19 +101,11 @@ TASK Task::GetID() const { bool Task::HandleError(STATUS results) { if (results != ERROR) return true; int errsv = errno; - if (errsv == HAL_objLib_OBJ_ID_ERROR) { - wpi_setWPIErrorWithContext(TaskIDError, m_taskName); - } else if (errsv == HAL_objLib_OBJ_DELETED) { - wpi_setWPIErrorWithContext(TaskDeletedError, m_taskName); - } else if (errsv == HAL_taskLib_ILLEGAL_OPTIONS) { - wpi_setWPIErrorWithContext(TaskOptionsError, m_taskName); - } else if (errsv == HAL_memLib_NOT_ENOUGH_MEMORY) { - wpi_setWPIErrorWithContext(TaskMemoryError, m_taskName); - } else if (errsv == HAL_taskLib_ILLEGAL_PRIORITY) { - wpi_setWPIErrorWithContext(TaskPriorityError, m_taskName); + if (errsv == HAL_taskLib_ILLEGAL_PRIORITY) { + wpi_setWPIErrorWithContext(TaskPriorityError, m_taskName.c_str()); } else { printf("ERROR: errno=%i", errsv); - wpi_setWPIErrorWithContext(TaskError, m_taskName); + wpi_setWPIErrorWithContext(TaskError, m_taskName.c_str()); } return false; } diff --git a/wpilibc/wpilibC++Devices/src/Ultrasonic.cpp b/wpilibc/wpilibC++Devices/src/Ultrasonic.cpp index ca260b9f51..d228899448 100644 --- a/wpilibc/wpilibC++Devices/src/Ultrasonic.cpp +++ b/wpilibc/wpilibC++Devices/src/Ultrasonic.cpp @@ -23,13 +23,10 @@ const uint32_t Ultrasonic::kPriority; ///< Priority that the ultrasonic round constexpr double Ultrasonic::kMaxUltrasonicTime; ///< Max time (ms) between readings. constexpr double Ultrasonic::kSpeedOfSoundInchesPerSec; -Task Ultrasonic::m_task( - "UltrasonicChecker", - (FUNCPTR) - UltrasonicChecker); // task doing the round-robin automatic sensing Ultrasonic *Ultrasonic::m_firstSensor = nullptr; // head of the ultrasonic sensor list -bool Ultrasonic::m_automaticEnabled = false; // automatic round robin mode +Task Ultrasonic::m_task; +std::atomic Ultrasonic::m_automaticEnabled{false}; // automatic round robin mode priority_mutex Ultrasonic::m_mutex; /** @@ -214,7 +211,12 @@ void Ultrasonic::SetAutomaticMode(bool enabling) { // Start round robin task wpi_assert(m_task.Verify() == false); // should be false since was previously disabled - m_task.Start(); + m_task = Task("UltrasonicChecker", &Ultrasonic::UltrasonicChecker); + + // TODO: Currently, lvuser does not have permissions to set task priorities. + // Until that is the case, uncommenting this will break user code that calls + // Ultrasonic::SetAutomicMode(). + //m_task.SetPriority(kPriority); } else { // disabling automatic mode. Wait for background task to stop running. while (m_task.Verify()) @@ -225,7 +227,8 @@ void Ultrasonic::SetAutomaticMode(bool enabling) { for (Ultrasonic *u = m_firstSensor; u != nullptr; u = u->m_nextSensor) { u->m_counter->Reset(); } - m_task.Stop(); + m_automaticEnabled = false; + m_task.join(); } } diff --git a/wpilibc/wpilibC++Devices/src/Utility.cpp b/wpilibc/wpilibC++Devices/src/Utility.cpp index 73bb0ef981..1933dbcd01 100644 --- a/wpilibc/wpilibC++Devices/src/Utility.cpp +++ b/wpilibc/wpilibC++Devices/src/Utility.cpp @@ -19,19 +19,6 @@ #include #include "nivision.h" -static bool suspendOnAssertEnabled = false; - -/** - * Enable suspend on assert. - * If enabled, the user task will be suspended whenever an assert fails. This - * will allow the user to attach to the task with the debugger and examine - * variables - * around the failure. - */ -void wpi_suspendOnAssertEnabled(bool enabled) { - suspendOnAssertEnabled = enabled; -} - /** * Assert implementation. * This allows breakpoints to be set on an assert. @@ -61,8 +48,6 @@ bool wpi_assert_impl(bool conditionValue, const char *conditionText, // Print the error and send it to the DriverStation std::cout << error << std::endl; HALSetErrorData(error.c_str(), error.size(), 100); - - if (suspendOnAssertEnabled) suspendTask(nullptr); } return conditionValue; @@ -98,8 +83,6 @@ void wpi_assertEqual_common_impl(const char *valueA, const char *valueB, // Print the error and send it to the DriverStation std::cout << error << std::endl; HALSetErrorData(error.c_str(), error.size(), 100); - - if (suspendOnAssertEnabled) suspendTask(nullptr); } /** diff --git a/wpilibc/wpilibC++Sim/src/Task.cpp b/wpilibc/wpilibC++Sim/src/Task.cpp index 2af6bb293d..7cfecdd650 100644 --- a/wpilibc/wpilibC++Sim/src/Task.cpp +++ b/wpilibc/wpilibC++Sim/src/Task.cpp @@ -1,11 +1,13 @@ /*----------------------------------------------------------------------------*/ -/* Copyright (c) FIRST 2008. All Rights Reserved. */ +/* Copyright (c) FIRST 2008. 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 $(WIND_BASE)/WPILib. */ /*----------------------------------------------------------------------------*/ #include "Task.h" +//#include "NetworkCommunication/UsageReporting.h" #include "WPIErrors.h" #include #include @@ -20,135 +22,56 @@ const uint32_t Task::kDefaultPriority; -/** - * Create but don't launch a task. - * @param name The name of the task. "FRC_" will be prepended to the task name. - * @param function The address of the function to run as the new task. - * @param priority The VxWorks priority for the task. - * @param stackSize The size of the stack for the task - */ -Task::Task(const char* name, FUNCPTR function, int32_t priority, uint32_t stackSize) -{ - m_taskID = NULL_TASK; - m_function = function; - m_priority = priority; - m_stackSize = stackSize; - m_taskName = new char[strlen(name) + 5]; - strcpy(m_taskName, "FRC_"); - strcpy(m_taskName+4, name); +Task& Task::operator=(Task&& task) { + m_thread.swap(task.m_thread); + m_taskName = std::move(task.m_taskName.c_str()); - static int32_t instances = 0; - instances++; + return *this; } -Task::~Task() -{ - if (m_taskID != NULL_TASK) Stop(); - delete [] m_taskName; - m_taskName = nullptr; +Task::~Task() { + std::cout << "[HAL] Exited task " << m_taskName << std::endl; } -/** - * Starts this task. - * If it is already running or unable to start, it fails and returns false. - */ -bool Task::Start(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t arg4, - uint32_t arg5, uint32_t arg6, uint32_t arg7, uint32_t arg8, uint32_t arg9) -{ - m_taskID = spawnTask(m_taskName, - m_priority, - VXWORKS_FP_TASK, // options - m_stackSize, // stack size - m_function, // function to start - arg0, arg1, arg2, arg3, arg4, // parameter 1 - pointer to this class - arg5, arg6, arg7, arg8, arg9);// additional unused parameters - if (m_taskID == NULL_TASK) { - HandleError(ERROR); - return false; - } - return true; +bool Task::joinable() const noexcept { + return m_thread.joinable(); } -/** - * Restarts a running task. - * If the task isn't started, it starts it. - * @return false if the task is running and we are unable to kill the previous instance - */ -bool Task::Restart() -{ - return HandleError(restartTask(m_taskID)); +void Task::join() { + m_thread.join(); } -/** - * Kills the running task. - * @returns true on success false if the task doesn't exist or we are unable to kill it. - */ -bool Task::Stop() -{ - bool ok = true; - if (Verify()) - { - ok = HandleError(deleteTask(m_taskID)); - } - m_taskID = NULL_TASK; - return ok; +void Task::detach() { + m_thread.detach(); } -/** - * Returns true if the task is ready to execute (i.e. not suspended, delayed, or blocked). - * @return true if ready, false if not ready. - */ -bool Task::IsReady() const -{ - return isTaskReady(m_taskID); +std::thread::id Task::get_id() const noexcept { + return m_thread.get_id(); } -/** - * Returns true if the task was explicitly suspended by calling Suspend() - * @return true if suspended, false if not suspended. - */ -bool Task::IsSuspended() const -{ - return isTaskSuspended(m_taskID); -} - -/** - * Pauses a running task. - * Returns true on success, false if unable to pause or the task isn't running. - */ -bool Task::Suspend() -{ - return HandleError(suspendTask(m_taskID)); -} - -/** - * Resumes a paused task. - * Returns true on success, false if unable to resume or if the task isn't running/paused. - */ -bool Task::Resume() -{ - return HandleError(resumeTask(m_taskID)); +std::thread::native_handle_type Task::native_handle() { + return m_thread.native_handle(); } /** * Verifies a task still exists. * @returns true on success. */ -bool Task::Verify() const -{ - return verifyTaskID(m_taskID) == OK; -} +bool Task::Verify() { + auto id = m_thread.native_handle(); + return verifyTaskID(&id) == OK; } /** * Gets the priority of a task. * @returns task priority or 0 if an error occured */ -int32_t Task::GetPriority() -{ - if (HandleError(getTaskPriority(m_taskID, &m_priority))) - return m_priority; - else - return 0; +int32_t Task::GetPriority() { + int priority; + auto id = m_thread.native_handle(); + if (HandleError(getTaskPriority(&id, &priority))) + return priority; + else + return 0; } /** @@ -158,53 +81,28 @@ int32_t Task::GetPriority() * @param priority The priority the task should run at. * @returns true on success. */ -bool Task::SetPriority(int32_t priority) -{ - m_priority = priority; - return HandleError(setTaskPriority(m_taskID, m_priority)); +bool Task::SetPriority(int32_t priority) { + auto id = m_thread.native_handle(); + return HandleError(setTaskPriority(&id, priority)); } /** * Returns the name of the task. * @returns Pointer to the name of the task or nullptr if not allocated */ -const char* Task::GetName() const -{ - return m_taskName; -} - -/** - * Get the ID of a task - * @returns Task ID of this task. Task::kInvalidTaskID (-1) if the task has not been started or has already exited. - */ -TASK Task::GetID() const -{ - if (Verify()) - return m_taskID; - return NULL_TASK; -} +std::string Task::GetName() const { return m_taskName; } /** * Handles errors generated by task related code. */ -bool Task::HandleError(STATUS results) -{ - if (results != ERROR) return true; - int errsv = errno; - if (errsv == HAL_objLib_OBJ_ID_ERROR) { - wpi_setWPIErrorWithContext(TaskIDError, m_taskName); - } else if (errsv == HAL_objLib_OBJ_DELETED) { - wpi_setWPIErrorWithContext(TaskDeletedError, m_taskName); - } else if (errsv == HAL_taskLib_ILLEGAL_OPTIONS) { - wpi_setWPIErrorWithContext(TaskOptionsError, m_taskName); - } else if (errsv == HAL_memLib_NOT_ENOUGH_MEMORY) { - wpi_setWPIErrorWithContext(TaskMemoryError, m_taskName); - } else if (errsv == HAL_taskLib_ILLEGAL_PRIORITY) { - wpi_setWPIErrorWithContext(TaskPriorityError, m_taskName); - } else { - printf("ERROR: errno=%i", errsv); - wpi_setWPIErrorWithContext(TaskError, m_taskName); - } - return false; +bool Task::HandleError(STATUS results) { + if (results != ERROR) return true; + int errsv = errno; + if (errsv == HAL_taskLib_ILLEGAL_PRIORITY) { + wpi_setWPIErrorWithContext(TaskPriorityError, m_taskName.c_str()); + } else { + printf("ERROR: errno=%i", errsv); + wpi_setWPIErrorWithContext(TaskError, m_taskName.c_str()); + } + return false; } - diff --git a/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/hal/HALLibrary.java b/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/hal/HALLibrary.java index c82da56d35..bbef819ae6 100644 --- a/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/hal/HALLibrary.java +++ b/wpilibj/wpilibJavaDevices/src/main/java/edu/wpi/first/wpilibj/hal/HALLibrary.java @@ -712,56 +712,4 @@ public class HALLibrary /* implements Library */{ * native declaration : AthenaJava\target\native\include\HAL\HAL.h:476 */ public static native void Occur(); - /* - * public static final GlobalDouble kDefaultWatchdogExpiration = new - * GlobalDouble(HALLibrary.JNA_NATIVE_LIB, "kDefaultWatchdogExpiration"); - * public static final GlobalInt HAL_NO_WAIT = new - * GlobalInt(HALLibrary.JNA_NATIVE_LIB, "HAL_NO_WAIT"); public static final - * GlobalInt HAL_WAIT_FOREVER = new GlobalInt(HALLibrary.JNA_NATIVE_LIB, - * "HAL_WAIT_FOREVER"); public static final GlobalInt SEMAPHORE_Q_FIFO = new - * GlobalInt(HALLibrary.JNA_NATIVE_LIB, "SEMAPHORE_Q_FIFO"); - */ - /* - * public static final GlobalInt SEMAPHORE_DELETE_SAFE = new - * GlobalInt(HALLibrary.JNA_NATIVE_LIB, "SEMAPHORE_DELETE_SAFE"); public - * static final GlobalInt SEMAPHORE_INVERSION_SAFE = new - * GlobalInt(HALLibrary.JNA_NATIVE_LIB, "SEMAPHORE_INVERSION_SAFE"); public - * static final GlobalInt SEMAPHORE_NO_WAIT = new - * GlobalInt(HALLibrary.JNA_NATIVE_LIB, "SEMAPHORE_NO_WAIT"); - */ - /* - * public static final GlobalInt SEMAPHORE_EMPTY = new - * GlobalInt(HALLibrary.JNA_NATIVE_LIB, "SEMAPHORE_EMPTY"); public static - * final GlobalInt SEMAPHORE_FULL = new GlobalInt(HALLibrary.JNA_NATIVE_LIB, - * "SEMAPHORE_FULL"); public static final GlobalInt VXWORKS_FP_TASK = new - * GlobalInt(HALLibrary.JNA_NATIVE_LIB, "VXWORKS_FP_TASK"); public static - * final GlobalInt HAL_objLib_OBJ_ID_ERROR = new - * GlobalInt(HALLibrary.JNA_NATIVE_LIB, "HAL_objLib_OBJ_ID_ERROR"); public - * static final GlobalInt HAL_objLib_OBJ_DELETED = new - * GlobalInt(HALLibrary.JNA_NATIVE_LIB, "HAL_objLib_OBJ_DELETED"); public - * static final GlobalInt HAL_taskLib_ILLEGAL_OPTIONS = new - * GlobalInt(HALLibrary.JNA_NATIVE_LIB, "HAL_taskLib_ILLEGAL_OPTIONS"); public - * static final GlobalInt HAL_memLib_NOT_ENOUGH_MEMORY = new - * GlobalInt(HALLibrary.JNA_NATIVE_LIB, "HAL_memLib_NOT_ENOUGH_MEMORY"); - * public static final GlobalInt HAL_taskLib_ILLEGAL_PRIORITY = new - * GlobalInt(HALLibrary.JNA_NATIVE_LIB, "HAL_taskLib_ILLEGAL_PRIORITY"); - * public static final GlobalInt dio_kNumSystems = new - * GlobalInt(HALLibrary.JNA_NATIVE_LIB, "dio_kNumSystems"); public static - * final GlobalInt solenoid_kNumDO7_0Elements = new - * GlobalInt(HALLibrary.JNA_NATIVE_LIB, "solenoid_kNumDO7_0Elements"); public - * static final GlobalInt interrupt_kNumSystems = new - * GlobalInt(HALLibrary.JNA_NATIVE_LIB, "interrupt_kNumSystems"); public - * static final GlobalInt kSystemClockTicksPerMicrosecond = new - * GlobalInt(HALLibrary.JNA_NATIVE_LIB, "kSystemClockTicksPerMicrosecond"); - */ - /* - * public static class TASK extends PointerType { public TASK(Pointer address) - * { super(address); } public TASK() { super(); } }; public static class - * MUTEX_ID extends PointerType { public MUTEX_ID(Pointer address) { - * super(address); } public MUTEX_ID() { super(); } }; public static class - * MULTIWAIT_ID extends PointerType { public MULTIWAIT_ID(Pointer address) { - * super(address); } public MULTIWAIT_ID() { super(); } }; public static class - * SEMAPHORE_ID extends PointerType { public SEMAPHORE_ID(Pointer address) { - * super(address); } public SEMAPHORE_ID() { super(); } }; - */ }