sipxportlib  Version 3.3
OsTaskLinux.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2004-2006 SIPfoundry Inc.
3 // Licensed by SIPfoundry under the LGPL license.
4 //
5 // Copyright (C) 2004-2006 Pingtel Corp. All rights reserved.
6 // Licensed to SIPfoundry under a Contributor Agreement.
7 //
8 // $$
10 
11 #ifndef _OsTaskLinux_h_
12 #define _OsTaskLinux_h_
13 
14 // SYSTEM INCLUDES
15 
16 // APPLICATION INCLUDES
17 #include "os/OsDefs.h"
18 #include "os/OsMutex.h"
19 #include "os/OsRWMutex.h"
20 #include "os/OsStatus.h"
21 #include "os/OsTask.h"
22 
23 // DEFINES
24 // MACROS
25 // EXTERNAL FUNCTIONS
26 // EXTERNAL VARIABLES
27 // CONSTANTS
28 // STRUCTS
29 // TYPEDEFS
30 // FORWARD DECLARATIONS
31 class OsTime;
32 
33 //:Task abstraction for Linux
34 // A task represents a thread of execution. All tasks run within the same
35 // address space but have their own stack and program counter. Tasks may be
36 // created and deleted dynamically.
37 //
38 // Users create tasks by:
39 // 1) Deriving a new class based on OsTask or one of its descendants,
40 // and overriding the run() method in the derived class.
41 // 2) Calling the constructor for the derived class.
42 // 3) Invoking the start() method for the derived class. This creates the
43 // corresponding low-level OS task and associates it with the class.
44 //
45 // Note: Many of the methods in this class are only applicable once the
46 // start() method for the object has been called and the corresponding
47 // low-level task has been created. Accordingly, before a successful call
48 // to start(), most of the methods in this class return the
49 // OS_TASK_NOT_STARTED status.
50 class OsTaskLinux : public OsTaskBase
51 {
52 /* //////////////////////////// PUBLIC //////////////////////////////////// */
53 public:
54 
56  {
57  RT_NO = 0, // Non-realtime priority, does not use realtime scheduling
58  RT_LOW = 1, // Lowest realtime priority
59  RT_NORMAL = 2,
60  RT_HIGH = 3,
61  RT_HIGHEST = 4 // Highest realtime priority
62  };
63 
64 /* ============================ CREATORS ================================== */
65 
66  OsTaskLinux(const UtlString& name="",
67  void* pArg=NULL,
68  const int priority=DEF_PRIO,
69  const int options=DEF_OPTIONS,
70  const int stackSize=DEF_STACKSIZE);
71  //:Constructor
72 
73  virtual
74  ~OsTaskLinux();
75  //:Destructor -- delete the task
76 
77  virtual OsStatus deleteForce(void);
78  //:Delete the task even if the task is protected from deletion
79  // After calling this method, the user will still need to delete the
80  // corresponding OsTask object to reclaim its storage.
81 
82 /* ============================ MANIPULATORS ============================== */
83 
84  virtual UtlBoolean restart(void);
85  //:Restart the task
86  // The task is first terminated, and then reinitialized with the same
87  // name, priority, options, stack size, original entry point, and
88  // parameters it had when it was terminated.
89  // Return TRUE if the restart of the task is successful.
90 
91  virtual OsStatus resume(void);
92  //:Resume the task
93  // This routine resumes the task. The task suspension is cleared, and
94  // the task operates in the remaining state.
95 
96  virtual int run(void* pArg) = 0;
97  //:The entry point for the task.
98  // Derive new tasks as subclasses of OsTask, overriding this method.
99 
100  virtual UtlBoolean start(void);
101  //:Spawn a new task and invoke its run() method.
102  // Return TRUE if the spawning of the new task is successful.
103  // Return FALSE if the task spawn fails or if the task has already
104  // been started.
105 
106  virtual OsStatus suspend(void);
107  //:Suspend the task
108  // This routine suspends the task. Suspension is additive: thus, tasks
109  // can be delayed and suspended, or pended and suspended. Suspended,
110  // delayed tasks whose delays expire remain suspended. Likewise,
111  // suspended, pended tasks that unblock remain suspended only.
112 
113  virtual OsStatus setErrno(int errno);
114  //:Set the errno status for the task
115 
116  virtual OsStatus setOptions(int options);
117  //:Set the execution options for the task
118  // The only option that can be changed after a task has been created
119  // is whether to allow breakpoint debugging.
120 
121  virtual OsStatus setPriority(int priority);
122  //:Set the priority of the task
123  // Priorities range from 0, the highest priority, to 255, the lowest
124  // priority.
125 
126  virtual OsStatus varAdd(int* pVar);
127  //:Add a task variable to the task
128  // This routine adds a specified variable pVar (4-byte memory
129  // location) to its task's context. After calling this routine, the
130  // variable is private to the task. The task can access and modify
131  // the variable, but the modifications are not visible to other tasks,
132  // and other tasks' modifications to that variable do not affect the
133  // value seen by the task. This is accomplished by saving and restoring
134  // the variable's value each time a task switch occurs to or from the
135  // calling task.
136 
137  virtual OsStatus varDelete(int* pVar);
138  //:Remove a task variable from the task
139  // This routine removes a specified task variable, pVar, from its
140  // task's context. The private value of that variable is lost.
141 
142  virtual OsStatus varSet(int* pVar, int value);
143  //:Set the value of a private task variable
144  // This routine sets the private value of the task variable for a
145  // specified task. The specified task is usually not the calling task,
146  // which can set its private value by directly modifying the variable.
147  // This routine is provided primarily for debugging purposes.
148 
149  static OsStatus delay(const int milliSecs);
150  //:Delay a task from executing for the specified number of milliseconds
151  // This routine causes the calling task to relinquish the CPU for the
152  // duration specified. This is commonly referred to as manual
153  // rescheduling, but it is also useful when waiting for some external
154  // condition that does not have an interrupt associated with it.
155 
156  static OsStatus safe(void);
157  //:Make the calling task safe from deletion
158  // This routine protects the calling task from deletion. Tasks that
159  // attempt to delete a protected task will block until the task is
160  // made unsafe, using unsafe(). When a task becomes unsafe, the
161  // deleter will be unblocked and allowed to delete the task.
162  // The safe() primitive utilizes a count to keep track of
163  // nested calls for task protection. When nesting occurs,
164  // the task becomes unsafe only after the outermost unsafe()
165  // is executed.
166 
167  static OsStatus unsafe(void);
168  //:Make the calling task unsafe from deletion
169  // This routine removes the calling task's protection from deletion.
170  // Tasks that attempt to delete a protected task will block until the
171  // task is unsafe. When a task becomes unsafe, the deleter will be
172  // unblocked and allowed to delete the task.
173  // The unsafe() primitive utilizes a count to keep track of nested
174  // calls for task protection. When nesting occurs, the task becomes
175  // unsafe only after the outermost unsafe() is executed.
176 
177  static void yield(void);
178  //:Yield the CPU if a task of equal or higher priority is ready to run.
179 
180 /* ============================ ACCESSORS ================================= */
181 
182  static OsTaskLinux* getCurrentTask(void);
183  //:Return a pointer to the OsTask object for the currently executing task
184  // Return NULL if none exists.
185 
186  static OsStatus getCurrentTaskId(OsTaskId_t &rid);
187  //:Return an Id of the currently executing task
188 
189  static OsTaskLinux* getTaskByName(const UtlString& taskName);
190  //:Return a pointer to the OsTask object corresponding to the named task
191  // Return NULL if there is no task object with that name.
192 
193  static OsTaskLinux* getTaskById(const pthread_t taskId);
194  //:Return a pointer to the OsTask object corresponding to taskId
195  // Return NULL is there is no task object with that id.
196 
197  virtual OsStatus getErrno(int& rErrno);
198  //:Get the errno status for the task
199 
200  virtual int getOptions(void);
201  //:Return the execution options for the task
202 
203  virtual OsStatus getPriority(int& rPriority);
204  //:Return the priority of the task
205 
206  virtual OsStatus varGet(void);
207  //:Get the value of a task variable
208  // This routine returns the private value of a task variable for its
209  // task. The task is usually not the calling task, which can get its
210  // private value by directly accessing the variable. This routine is
211  // provided primarily for debugging purposes.
212 
213  static void getIdString_d(UtlString&, OsTaskId_t);
214  static void getIdString_x(UtlString&, OsTaskId_t);
215  static void getIdString_X(UtlString&, OsTaskId_t);
216  //: Relatively portable way to do what was being done wrong before.
217 
218 /* ============================ INQUIRY =================================== */
219 
220  virtual OsStatus id(OsTaskId_t &rId);
221  //:Get the task ID for this task
222 
223  virtual UtlBoolean isSuspended(void);
224  //:Check if the task is suspended
225  // Return TRUE is the task is suspended, otherwise FALSE.
226 
227 /* //////////////////////////// PROTECTED ///////////////////////////////// */
228 protected:
229 
230 /* //////////////////////////// PRIVATE /////////////////////////////////// */
231 private:
232  OsTaskId_t mTaskId; // Linux unique ID for task
233  OsRWMutex mDeleteGuard; // RWMutex guard to prevent unwanted task deletion
234  int mSuspendCnt; // Counts the nesting level of suspend() calls
235 
236  pthread_mutex_t mStartupSyncMutex; // Mutex, used with next two conditional
237  // variables to synchronize thread startup.
238  pthread_cond_t mTaskInitializedEvent; // Conditional variable, signaling
239  // that this OsTask object initialization is completed
240  // and thread could go on.
241  pthread_cond_t mTaskStartedEvent; // Conditional variable, signaling
242  // that thread is started and doLinuxCreateTask() could
243  // return to caller.
244 
245  enum {
246  OS_TASK_THREAD_STARTUP_TIMEOUT=5 // Time to wait for thread startup
247  // (in seconds).
248  };
249 
250  // saved initialization information (used for task restarts)
251  int mOptions;
252  int mPriority;
253  int mStackSize;
254 
255  UtlBoolean doLinuxCreateTask(const char* pTaskName);
256  //:Do the real work associated with creating a new Linux task.
257  // The mDataGuard lock should be held upon entry into this method.
258  //
259  // This method is blocking. It finishes only when thread is really
260  // started up. This is needed to avoid bad racing conditions. E.g.
261  // when thread may be stopped before really started, causing deadlock.
262 
263  void doLinuxTerminateTask(UtlBoolean doForce);
264  //:Do the real work associated with terminating a Linux task.
265  // The mDataGuard lock should be held upon entry into this method.
266 
271  void taskUnregister(void);
272 
273  static void * taskEntry(void* arg);
274  //:Function that serves as the starting address for a Linux task
275 
276  OsTaskLinux(const OsTaskLinux& rOsTaskLinux);
277  //:Copy constructor (not implemented for this class)
278 
279  OsTaskLinux& operator=(const OsTaskLinux& rhs);
280  //:Assignment operator (not implemented for this class)
281 
282 };
283 
284 /* ============================ INLINE METHODS ============================ */
285 
286 #endif // _OsTaskLinux_h_
287 
virtual OsStatus suspend(void)
Definition: OsTaskLinux.cpp:152
static OsTaskLinux * getCurrentTask(void)
Definition: OsTaskLinux.cpp:379
Definition: OsTaskLinux.h:61
Definition: OsTaskLinux.h:58
virtual UtlBoolean restart(void)
Definition: OsTaskLinux.cpp:107
virtual OsStatus setPriority(int priority)
Definition: OsTaskLinux.cpp:183
OsTaskLinux(const UtlString &name="", void *pArg=NULL, const int priority=DEF_PRIO, const int options=DEF_OPTIONS, const int stackSize=DEF_STACKSIZE)
Definition: OsTaskLinux.cpp:64
static OsStatus getCurrentTaskId(OsTaskId_t &rid)
Definition: OsTaskLinux.cpp:404
virtual OsStatus getErrno(int &rErrno)
Definition: OsTaskLinux.cpp:456
virtual OsStatus resume(void)
Definition: OsTaskLinux.cpp:118
OsStatus
Definition: OsStatus.h:27
#define NULL
Definition: UtlDefs.h:29
static const int DEF_PRIO
Definition: OsTask.h:65
static OsStatus unsafe(void)
Definition: OsTaskLinux.cpp:357
Definition: OsTaskLinux.h:57
virtual OsStatus varAdd(int *pVar)
Definition: OsTaskLinux.cpp:247
virtual int run(void *pArg)=0
static OsStatus delay(const int milliSecs)
Definition: OsTaskLinux.cpp:284
Definition: OsTask.h:59
static OsTaskLinux * getTaskByName(const UtlString &taskName)
Definition: OsTaskLinux.cpp:412
Definition: OsTaskLinux.h:50
virtual OsStatus getPriority(int &rPriority)
Definition: OsTaskLinux.cpp:473
virtual OsStatus varGet(void)
Definition: OsTaskLinux.cpp:496
Definition: UtlString.h:48
static void getIdString_x(UtlString &, OsTaskId_t)
Definition: OsTaskLinux.cpp:392
virtual UtlBoolean start(void)
Definition: OsTaskLinux.cpp:137
virtual OsStatus setOptions(int options)
Definition: OsTaskLinux.cpp:176
int errno
static void getIdString_d(UtlString &, OsTaskId_t)
Definition: OsTaskLinux.cpp:386
virtual int getOptions(void)
Definition: OsTaskLinux.cpp:467
static void yield(void)
Definition: OsTaskLinux.cpp:370
static const int DEF_OPTIONS
Definition: OsTask.h:64
Definition: OsTaskLinux.h:60
static void getIdString_X(UtlString &, OsTaskId_t)
Definition: OsTaskLinux.cpp:398
virtual UtlBoolean isSuspended(void)
Definition: OsTaskLinux.cpp:526
Definition: OsTime.h:37
virtual OsStatus id(OsTaskId_t &rId)
Definition: OsTaskLinux.cpp:507
virtual ~OsTaskLinux()
Definition: OsTaskLinux.cpp:83
virtual OsStatus varDelete(int *pVar)
Definition: OsTaskLinux.cpp:258
Definition: OsTaskLinux.h:59
int UtlBoolean
Definition: UtlDefs.h:41
static const int DEF_STACKSIZE
Definition: OsTask.h:66
static OsTaskLinux * getTaskById(const pthread_t taskId)
Definition: OsTaskLinux.cpp:431
LinuxPriorities
Definition: OsTaskLinux.h:55
virtual OsStatus setErrno(int errno)
Definition: OsTaskLinux.cpp:165
static OsStatus safe(void)
Definition: OsTaskLinux.cpp:337
virtual OsStatus varSet(int *pVar, int value)
Definition: OsTaskLinux.cpp:271
virtual OsStatus deleteForce(void)
enumcode: UNINITIALIZED - no low-level task, no name DB entries enumcode: STARTED - low-level task an...
Definition: OsTaskLinux.cpp:92