• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 // -*- c++ -*-
19 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
20 
21 //                  OSCL_T H R E A D (T H R E A D  I M P L E M E N T A T I O N)
22 
23 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
24 
25 /*! \file oscl_thread.cpp .This file provides THREAD implementation that can be ported
26 to three OS LINUX, SYMBIAN, WIN32
27 */
28 
29 
30 
31 // Implementation file for OSCL threads
32 #include "oscl_thread.h"
33 
34 
35 
36 /*
37  * Class contructor
38  */
OsclThread()39 OSCL_EXPORT_REF OsclThread::OsclThread()
40 {
41     bCreated = false;
42     iJoined = false;
43 }
44 
45 
46 
47 /*
48  * Class destructor
49  */
~OsclThread()50 OSCL_EXPORT_REF OsclThread::~OsclThread()
51 {
52 
53     ;
54 
55 }
56 
57 
58 /**
59  * OSCL Proc layer function
60  * Input Argument:
61  * function_name  =  Name of the thread Function
62  * stack_size  =  Size of the thread stack
63  * argument = Argument to be passed to thread function
64  * Thread_State = Enumeration which specifies the state of the thread on creation
65  *        with values Running and Suspend
66  * Return value : eOsclProcError
67  */
Create(TOsclThreadFuncPtr function_name,int32 stack_size,TOsclThreadFuncArg argument,OsclThread_State state,bool oIsJoinable)68 OSCL_EXPORT_REF OsclProcStatus::eOsclProcError OsclThread::Create(TOsclThreadFuncPtr function_name,
69         int32 stack_size,
70         TOsclThreadFuncArg argument,
71         OsclThread_State state,
72         bool oIsJoinable)
73 {
74     if (stack_size < 0)
75         return OsclProcStatus::INVALID_PARAM_ERROR;
76 
77     if (function_name == NULL)
78         return OsclProcStatus::INVALID_PARAM_ERROR;
79 
80     //Reset thread creation state, since the thread may
81     //have exited.
82     if (bCreated)
83         bCreated = false;
84 
85 
86     switch (state)
87     {
88         case Start_on_creation:
89             break;
90         case Suspend_on_creation:
91             //can't create suspended pthread.
92             return OsclProcStatus::INVALID_PARAM_ERROR;
93     }
94     pthread_attr_t attr;
95     pthread_attr_init(&attr);
96     if (stack_size != 0)
97         pthread_attr_setstacksize(&attr, stack_size);
98 
99     // Default detachstate attribute to PTHREAD_CREATE_DETACHED state
100     int detach_ret;
101     if (oIsJoinable)
102     {
103         detach_ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
104         iJoined = true;
105     }
106     else
107     {
108         detach_ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
109     }
110     switch (detach_ret)
111     {
112         case 0: // successful, continue thread creation
113             break;
114         case EINVAL:
115         default:
116             return OsclProcStatus::PSHARED_ATTRIBUTE_SETTING_ERROR;
117     }
118 
119     int result = pthread_create(
120                      (pthread_t*) & ObjThread,
121                      &attr,
122                      function_name,
123                      (void*)argument);
124 
125     switch (result)
126     {
127         case 0:
128             bCreated = true;
129             return OsclProcStatus::SUCCESS_ERROR;
130         case EAGAIN:
131             return OsclProcStatus::NOT_ENOUGH_RESOURCES_ERROR;
132         default:
133             return OsclProcStatus::OTHER_ERROR;
134     }
135 
136 }
137 
138 
139 /**
140  * OSCL Proc layer function
141  * ExitThread is a static function which is used to end the current thread. When called it
142  * just ends the execution of the current thread.
143  * Input Argument:
144  * exitcode  =  Exitcode of the thread. This can be used by other threads to know the
145  *              exit status of this thread.
146  * Return value : None
147 */
Exit(OsclAny * exitcode)148 OSCL_EXPORT_REF void OsclThread::Exit(OsclAny* exitcode)
149 {
150     //intentionally not implemented.
151     OSCL_UNUSED_ARG(exitcode);
152 
153 }
154 
EnableKill()155 OSCL_EXPORT_REF void OsclThread::EnableKill()
156 {
157     ; //nothing needed
158 
159 }
160 
161 /**
162  * OSCL Proc layer function
163  * Suspend current thread execution for specified time.
164  * @param msec, t2: sleep time in milliseconds.
165  */
SleepMillisec(const int32 msec)166 OSCL_EXPORT_REF void OsclThread::SleepMillisec(const int32 msec)
167 {
168     struct timespec reqt, remt;
169     reqt.tv_sec = msec / 1000;
170     reqt.tv_nsec = 1000000 * (msec % 1000);
171     nanosleep(&reqt, &remt) ;
172 
173 }
174 
175 
176 /**
177 
178  * OSCL Proc layer function
179 
180  * This is used to terminate a thread other than the current thread.
181 
182  * Input Argument:
183 
184  * exitcode  =  Exitcode of the thread. This can be used by other threads to know the
185 
186  *              exit status of this thread.
187 
188  * Return value : Error code
189 
190  */
191 
Terminate(OsclAny * oscl_ExitCode)192 OSCL_EXPORT_REF OsclProcStatus::eOsclProcError OsclThread::Terminate(OsclAny* oscl_ExitCode)
193 {
194 
195 
196     if (!bCreated)
197         return OsclProcStatus::INVALID_OPERATION_ERROR;
198 
199     {
200         OSCL_UNUSED_ARG(oscl_ExitCode);
201 
202         bCreated = false;
203         if (iJoined)
204         {
205             if (pthread_join(ObjThread, NULL) == 0)
206             {
207                 return OsclProcStatus::SUCCESS_ERROR;
208             }
209             else
210             {
211                 return OsclProcStatus::OTHER_ERROR;
212             }
213         }
214         return OsclProcStatus::NOT_IMPLEMENTED;
215     }
216 }
217 
218 
219 
220 
221 
222 
223 
224 /**
225 
226  * OSCL Proc layer function
227 
228  * This API suspends the thread being referred. The thread can later be brought into execution
229 
230  * by calling OSCL_ResumeThread() on it.
231 
232  * Input Argument: None
233 
234  * Return value : Error code
235 
236  */
237 
Suspend()238 OSCL_EXPORT_REF OsclProcStatus::eOsclProcError OsclThread::Suspend()
239 
240 {
241 
242     if (!bCreated)
243         return OsclProcStatus::INVALID_OPERATION_ERROR;
244 
245 
246 
247 
248     {
249         //pthread doesn't support suspend/resume
250         return OsclProcStatus::NOT_IMPLEMENTED;
251 
252     }
253 
254 
255 }
256 
257 
258 
259 
260 
261 
262 
263 /**
264 
265  * OSCL Proc layer function
266 
267  * ResumeThread resumes the suspended thread and brings it into execution.
268 
269  * Input Argument: None
270 
271  * Return value : Error code
272 
273  */
274 
Resume()275 OSCL_EXPORT_REF OsclProcStatus::eOsclProcError OsclThread::Resume()
276 
277 {
278 
279     if (!bCreated)
280         return OsclProcStatus::INVALID_OPERATION_ERROR;
281 
282 
283 
284 
285     {
286 
287         //pthread doesn't support suspend/resume
288         return OsclProcStatus::NOT_IMPLEMENTED;
289 
290     }
291 
292 
293 }
294 
295 
296 
297 
298 
299 /**
300 
301  * OSCL Proc layer function
302 
303  * GetThreadPriority gets the priority of the thread. It takes reference of the input argument
304 
305  * and assigns priority to it from one of the already defined priorities.
306 
307  * Input Argument:
308 
309  * int16& refThreadPriority : Output Priority value
310 
311  * Return value : Error code
312 
313  */
314 
GetPriority(OsclThreadPriority & refThreadPriority)315 OSCL_EXPORT_REF OsclProcStatus::eOsclProcError OsclThread::GetPriority(OsclThreadPriority& refThreadPriority)
316 
317 {
318     if (!bCreated)
319         return OsclProcStatus::INVALID_OPERATION_ERROR;
320 
321     struct sched_param schedparam;
322     int sched_policy = 0;
323     int pri;
324     int result;
325     result = pthread_getschedparam(ObjThread, &sched_policy, &schedparam);
326     if (result != 0)
327     {
328         switch (result)
329         {
330             case ESRCH:
331                 return OsclProcStatus::INVALID_THREAD_ERROR;
332             case EFAULT:
333                 return OsclProcStatus::INVALID_PARAM_ERROR;
334             default:
335                 return OsclProcStatus::OTHER_ERROR;
336         }
337     }
338 
339     pri = schedparam.sched_priority;
340     switch (sched_policy)
341     {
342         case SCHED_RR:
343         case SCHED_FIFO:
344         {
345             //static priority is 1..99
346             if (pri < 1)
347                 return OsclProcStatus::OTHER_ERROR;
348             else if (pri == 1)
349                 refThreadPriority = ThreadPriorityLowest;
350             else if (pri <= 20)
351                 refThreadPriority = ThreadPriorityLow;
352             else if (pri <= 40)
353                 refThreadPriority = ThreadPriorityBelowNormal;
354             else if (pri <= 55)
355                 refThreadPriority = ThreadPriorityNormal;
356             else if (pri <= 75)
357                 refThreadPriority = ThreadPriorityAboveNormal;
358             else if (pri <= 98)
359                 refThreadPriority = ThreadPriorityHighest;
360             else if (pri == 99)
361                 refThreadPriority = ThreadPriorityTimeCritical;
362             else if (pri > 99)
363                 return OsclProcStatus::OTHER_ERROR;
364             return OsclProcStatus::SUCCESS_ERROR;
365         }
366         break;
367 
368         case SCHED_OTHER:
369         {
370             //static priority is always zero.
371             if (pri != 0)
372                 return OsclProcStatus::OTHER_ERROR;
373             refThreadPriority = ThreadPriorityNormal;
374             return OsclProcStatus::SUCCESS_ERROR;
375         }
376         break;
377 
378         default:
379             return OsclProcStatus::OTHER_ERROR;
380     }
381 }
382 
383 
384 
385 /**
386  * OSCL Proc layer function
387  * SetThreadPriority sets the priority of the thread. It takes priority as the input argument
388  * and assigns it to the thread referred.
389  * Input Argument:
390  * ePriorityLevel : Input Priority value
391  * Return value : Error code
392  */
SetPriority(OsclThreadPriority ePriority)393 OSCL_EXPORT_REF OsclProcStatus::eOsclProcError OsclThread::SetPriority(OsclThreadPriority ePriority)
394 {
395     if (!bCreated)
396         return OsclProcStatus::INVALID_OPERATION_ERROR;
397 
398     //not supported.
399     OSCL_UNUSED_ARG(ePriority);
400     return OsclProcStatus::NOT_IMPLEMENTED;
401 
402 }
403 
404 
405 
406 /**
407 
408  * OSCL Proc layer function
409 
410  * This is used to compare whether the thread ID's are equal.
411 
412  * @param Thread ID passed by the application
413 
414  * @return Error code
415 
416  */
417 
GetId(TOsclThreadId & refThreadId)418 OSCL_EXPORT_REF OsclProcStatus::eOsclProcError OsclThread::GetId(TOsclThreadId& refThreadId)
419 
420 {
421 
422 
423 
424 
425     refThreadId = pthread_self();
426 
427     return OsclProcStatus::SUCCESS_ERROR;
428 
429 
430 }
431 
432 
CompareId(TOsclThreadId & t1,TOsclThreadId & t2)433 OSCL_EXPORT_REF bool OsclThread::CompareId(TOsclThreadId &t1, TOsclThreadId &t2)
434 //static routine
435 {
436     return (pthread_equal(t1, t2) != 0);
437 }
438 
439 
440 
441 
442 
443 
444 /**
445 
446  * Helper Function
447 
448  * Map the Operating system errors to OSCL defined erros
449 
450  * Input Argument:
451 
452  * error : Input error as one of the OS errors
453 
454  * Return value : Error code ( User defined )
455 
456  */
457 
458 
459 
460 
461 
462 
463