blob: 18e5d05d358cf7c87936e0a9b72e9d79f0d98a06 [file] [log] [blame]
jerrymf1579332013-02-07 01:56:28 +00001/*----------------------------------------------------------------------------*/
2/* Copyright (c) FIRST 2008. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
5/*----------------------------------------------------------------------------*/
6
7#include "Task.h"
8
9#include "NetworkCommunication/UsageReporting.h"
10#include "WPIErrors.h"
11#include <errnoLib.h>
12#include <string.h>
13#include <taskLib.h>
14#include <usrLib.h>
15
16const UINT32 Task::kDefaultPriority;
17const INT32 Task::kInvalidTaskID;
18
19/**
20 * Create but don't launch a task.
21 * @param name The name of the task. "FRC_" will be prepended to the task name.
22 * @param function The address of the function to run as the new task.
23 * @param priority The VxWorks priority for the task.
24 * @param stackSize The size of the stack for the task
25 */
26Task::Task(const char* name, FUNCPTR function, INT32 priority, UINT32 stackSize)
27{
28 m_taskID = kInvalidTaskID;
29 m_function = function;
30 m_priority = priority;
31 m_stackSize = stackSize;
32 m_taskName = new char[strlen(name) + 5];
33 strcpy(m_taskName, "FRC_");
34 strcpy(m_taskName+4, name);
35
36 static INT32 instances = 0;
37 instances++;
38 nUsageReporting::report(nUsageReporting::kResourceType_Task, instances, 0, m_taskName);
39}
40
41Task::~Task()
42{
43 if (m_taskID != kInvalidTaskID) Stop();
44 delete [] m_taskName;
45 m_taskName = NULL;
46}
47
48/**
49 * Starts this task.
50 * If it is already running or unable to start, it fails and returns false.
51 */
52bool Task::Start(UINT32 arg0, UINT32 arg1, UINT32 arg2, UINT32 arg3, UINT32 arg4,
53 UINT32 arg5, UINT32 arg6, UINT32 arg7, UINT32 arg8, UINT32 arg9)
54{
55 m_taskID = taskSpawn(m_taskName,
56 m_priority,
57 VX_FP_TASK, // options
58 m_stackSize, // stack size
59 m_function, // function to start
60 arg0, arg1, arg2, arg3, arg4, // parameter 1 - pointer to this class
61 arg5, arg6, arg7, arg8, arg9);// additional unused parameters
62 bool ok = HandleError(m_taskID);
63 if (!ok) m_taskID = kInvalidTaskID;
64 return ok;
65}
66
67/**
68 * Restarts a running task.
69 * If the task isn't started, it starts it.
70 * @return false if the task is running and we are unable to kill the previous instance
71 */
72bool Task::Restart()
73{
74 return HandleError(taskRestart(m_taskID));
75}
76
77/**
78 * Kills the running task.
79 * @returns true on success false if the task doesn't exist or we are unable to kill it.
80 */
81bool Task::Stop()
82{
83 bool ok = true;
84 if (Verify())
85 {
86 ok = HandleError(taskDelete(m_taskID));
87 }
88 m_taskID = kInvalidTaskID;
89 return ok;
90}
91
92/**
93 * Returns true if the task is ready to execute (i.e. not suspended, delayed, or blocked).
94 * @return true if ready, false if not ready.
95 */
96bool Task::IsReady()
97{
98 return taskIsReady(m_taskID);
99}
100
101/**
102 * Returns true if the task was explicitly suspended by calling Suspend()
103 * @return true if suspended, false if not suspended.
104 */
105bool Task::IsSuspended()
106{
107 return taskIsSuspended(m_taskID);
108}
109
110/**
111 * Pauses a running task.
112 * Returns true on success, false if unable to pause or the task isn't running.
113 */
114bool Task::Suspend()
115{
116 return HandleError(taskSuspend(m_taskID));
117}
118
119/**
120 * Resumes a paused task.
121 * Returns true on success, false if unable to resume or if the task isn't running/paused.
122 */
123bool Task::Resume()
124{
125 return HandleError(taskResume(m_taskID));
126}
127
128/**
129 * Verifies a task still exists.
130 * @returns true on success.
131 */
132bool Task::Verify()
133{
134 return taskIdVerify(m_taskID) == OK;
135}
136
137/**
138 * Gets the priority of a task.
139 * @returns task priority or 0 if an error occured
140 */
141INT32 Task::GetPriority()
142{
143 if (HandleError(taskPriorityGet(m_taskID, &m_priority)))
144 return m_priority;
145 else
146 return 0;
147}
148
149/**
150 * This routine changes a task's priority to a specified priority.
151 * Priorities range from 0, the highest priority, to 255, the lowest priority.
152 * Default task priority is 100.
153 * @param priority The priority the task should run at.
154 * @returns true on success.
155 */
156bool Task::SetPriority(INT32 priority)
157{
158 m_priority = priority;
159 return HandleError(taskPrioritySet(m_taskID, m_priority));
160}
161
162/**
163 * Returns the name of the task.
164 * @returns Pointer to the name of the task or NULL if not allocated
165 */
166const char* Task::GetName()
167{
168 return m_taskName;
169}
170
171/**
172 * Get the ID of a task
173 * @returns Task ID of this task. Task::kInvalidTaskID (-1) if the task has not been started or has already exited.
174 */
175INT32 Task::GetID()
176{
177 if (Verify())
178 return m_taskID;
179 return kInvalidTaskID;
180}
181
182/**
183 * Handles errors generated by task related code.
184 */
185bool Task::HandleError(STATUS results)
186{
187 if (results != ERROR) return true;
188 switch(errnoGet())
189 {
190 case S_objLib_OBJ_ID_ERROR:
191 wpi_setWPIErrorWithContext(TaskIDError, m_taskName);
192 break;
193
194 case S_objLib_OBJ_DELETED:
195 wpi_setWPIErrorWithContext(TaskDeletedError, m_taskName);
196 break;
197
198 case S_taskLib_ILLEGAL_OPTIONS:
199 wpi_setWPIErrorWithContext(TaskOptionsError, m_taskName);
200 break;
201
202 case S_memLib_NOT_ENOUGH_MEMORY:
203 wpi_setWPIErrorWithContext(TaskMemoryError, m_taskName);
204 break;
205
206 case S_taskLib_ILLEGAL_PRIORITY:
207 wpi_setWPIErrorWithContext(TaskPriorityError, m_taskName);
208 break;
209
210 default:
211 printErrno(errnoGet());
212 wpi_setWPIErrorWithContext(TaskError, m_taskName);
213 }
214 return false;
215}
216