INOS
cinostask.h
Go to the documentation of this file.
1//******************************************************************************
26//******************************************************************************
27#ifndef INC_INOSTASK_H
28#define INC_INOSTASK_H
29//------------------------------------------------------------------------------
30// defines
31//------------------------------------------------------------------------------
32//
33//------------------------------------------------------------------------------
34// includes
35//------------------------------------------------------------------------------
36//
37// system
38//
39// C++
40#if defined(INOS_DESKTOP)
41#include <thread>
42#include <condition_variable>
43#endif
44//
45// project
46//
47//------------------------------------------------------------------------------
48// class definition
49//------------------------------------------------------------------------------
50//
52{
53 // public members
54 public:
78 CINOSTask(char* apName=nullptr, uint32 auStackSize=defDefaultStackSize,
79 uint32 auPriority=DF_INOS_TASK_PRIO_LOWEST, bool abFloatingPoint=true,
80 uint32 auTimeSlice=defDefaultTimeSlice, bool abInterruptsDisabled=false,
81 void* apHandler=0, void* apObject=0);
82
89 CINOSTask(std::function<void(void*)> aFunction, void* apParam = nullptr,
90 uint8 auPriority=DF_INOS_TASK_PRIO_LOWEST);
91
99 CINOSTask(const char* apName, std::function<void(void*)> aFunction,
100 void* apParam = nullptr, uint8 auPriority=DF_INOS_TASK_PRIO_LOWEST);
101
104 virtual ~CINOSTask();
105
110 virtual uint32 Shutdown(CINOSSync* apSync=DF_INOS_SYNCHRONOUS);
111
115 virtual uint32 Join();
116
120 virtual void Detach();
121
125 virtual void Exit();
126
130 virtual void Exit(uint32 auExitCode);
131
135 virtual void SetExitCode(uint32 auExitCode)
136 { m_uExitCode = auExitCode; };
137
140 virtual uint32 GetExitCode()
141 { return m_uExitCode; };
142
146 virtual bool CheckShutdown()
147 { return (m_uTskFlags & eTskFlgShutdownRequest); };
148
152 virtual void SetSuspendHook(void* apSuspendHook)
153 {
154 #if defined(INOS_DESKTOP)
155 m_pSuspendHook = apSuspendHook;
156 #else
157 if (apSuspendHook)
158 m_pSuspendHook = (void*) ((uintnbr)apSuspendHook | 3);
159 else
160 m_pSuspendHook = nullptr;
161 #endif
162 };
163
166 virtual void ClrSuspendHook()
167 {
168 m_pSuspendHook = nullptr;
169 };
170
173 virtual void* GetSuspendHook()
174 {
175 return m_pSuspendHook;
176 };
177
180 enum ETskType {
181 eTskTypeBoot = 0,
182 eTskTypeResource = 1,
183 eTskTypeSystem = 2,
184 eTskTypeApplication = 3,
185 eTskTypeCommunication = 4,
186 eTskTypeRealtime = 5,
187 eTskTypeInterrupt = 6,
188 eTskTypeBackground = 7,
189 eTskTypeLua = 8,
190 eTskTypeTest = 9,
191 eTskTypeReserved0 = 10,
192 eTskTypeReserved1 = 11,
193 eTskTypeUser0 = 12,
194 eTskTypeUser1 = 13,
195 eTskTypeUser2 = 14,
196 eTskTypeUser3 = 15,
197 };
198
202 {
203 return ETskType(m_eTskType&0xf);
204 };
205
209 {
210 ETskType old = m_eTskType;
211 m_eTskType = ETskType(aeType&0xf);
212 return old;
213 };
214
215 // protected members
216 protected:
217
221 virtual void Action();
222
223#if defined(INOS_TIMINIG_CHECKS_SUSPEND)
225 virtual void OnResume(uint32 auLastState, uint32 auElapsedUs, void* apSync);
226#endif
227
229
230 // private members
231 private :
232
233 // friend classes
234 friend class CINOSMutex;
235 friend class CINOSSync;
236 friend class CINOSMultiSync;
237 friend class CINOSExceptionContext;
238 friend class CINOSExceptionCleanup;
239 friend class CINOSRegisterLoadDevice;
240 friend class CINOSWatchPoint;
241 friend class CINCODataLogger;
242 friend class CINCODataLoggerReader;
243 friend class CINFOLink;
244 friend class CINOSTaskQueue;
245 friend class CINOSTaskEx;
246 friend class CINOSTaskExMsg;
247 friend class CINCOTaskExProcedure;
248 friend class CINOSMcLua;
249 friend class CINOSMcMessage;
250 friend class CINOSMcCoord;
251 friend class CINOSConcurrencyCheck;
252 friend class CINOSOpcUaIncoItemProcedureAdapter;
253 friend class CINCOEvtLoggerGet;
254 friend class CINCOObject;
255 friend class CINCOProcedure;
256 friend class CINOSSioTftExpProc;
257 friend class CINOSTestpoint;
258 friend class CINCOVThreadImpl;
259 friend class CINCOVParseProcedure;
260 friend class CINOSConditionVariable;
261 friend class CINOSMcTargetINCOFrameHandler;
262 // hardware
263 friend class CINOSHwTarget;
264 friend class CINOSHwDevice;
265 friend class CINOSHwEthernet;
266
267
268
269 friend class CINOSHwDbg_P50XX;
270 friend class CINOSHwDbg_P2020;
271 friend class CINOSHwDbg_ppc750;
272 friend class CINOSHwDbg_CortexA9;
273 friend class CINOSHwDbg_ARMv8;
274
275 friend class CINOSHwIrq_P50XX;
276 friend class CINOSHwIrq_p2020;
277 friend class CINOSHwIrq_ppc750;
278 friend class CINOSHwIrq_CortexA9;
279 friend class CINOSHwIrq_GIC;
280 friend class CINOSHwIrq_GICv2;
281 friend class CINOSHwIrq_GICv3;
282
283 friend class CINOSHwCpu_p50XX;
284 friend class CINOSHwCpu_p2020;
285 friend class CINOSHwCpu_ppc750;
286 friend class CINOSHwCpu_CortexA9;
287 friend class CINOSHwCpu_ARMv8;
288
289 friend class CINOSHwTrp_P50XX;
290 friend class CINOSHwTrp_P2020;
291 friend class CINOSHwTrp_ppc750;
292 friend class CINOSHwTrp_CortexA9;
293 friend class CINOSHwTrp_ARMv8;
294 // kernel
295 friend class CINOSKernel;
296 friend class CINOSKernel_ARM;
297 friend class CINOSKernel_P50XX;
298 friend class CINOSKernel_P2020;
299 friend class CINOSKernel_PPC750;
300 friend class CINOSKernel_CortexA9;
301 friend class CINOSKernel_ARMv8;
302
303 friend void Ready(CINOSTask* apTask, uint32 auFlags);
304 friend void* _SetupTask(CINOSTask*);
305 #if defined (INOS_DESKTOP)
306 #if defined (INOS_WINDOWS)
307 friend long _Sleep(long aTime);
308 #else
309 friend long Sleep(long aTime);
310 #endif
311 #endif
312 friend void _suspend(uint32 auState);
313 friend void _suspend(uint32 auState, uint32 auFlags);
314 friend void _resume(CINOSTask* apTask);
315 friend void _resume(CINOSTask* apTask, uint32 auFlags);
316 friend void _preemption();
317 friend void _schedule();
318 friend void _changepriority(uint32 auPriority);
319 friend void _relinquish();
320 // friend functions
321 friend uint32 INOSDisableExceptions();
322 friend void INOSEnableExceptions(uint32 auState);
323 friend bool _CINOSExceptionContext__Save();
324 friend void SlaveVariable(class CINCOFrame* aFrame);
325
326 // Tests
327 friend class CTaskExTestImpl;
328 friend class CINOSTaskExMsgTest;
329 friend class CINOSStackCorruptionTest;
330
331
332 // private members
333 #if defined(INOS_TESTING)
334 public:
335 #else
336 private:
337 #endif
338 // task stack (has ro be the first local data)
339 void* pStack; // pointer to top of stack
340 void* pStackBegin; // pointer to start of stack
341 void* pStackEnd; // pointer to end of stack
342
344 void* m_pSuspendHook = nullptr;
345
346 // linked list pointers
347 CINOSTask* pNext; // pointer to next task in list
348 CINOSTask* pPrevious; // pointer to previous task in list
349
350 uint16 mState; // task state
351 uint16 mTrapNumber; // trap number if task on trap
352 uint32 mCycleTicks; // number of cpu ticks of one task cycle
353 uint8 mPriority; // task priority
354 uint8 mSavedPriority; // saved task priority
355 uint16 mUsecTimeSlice; // task timeslice (in usec)
356 uint16 mPreemptionCnt; // preemption counter
357 uint32 mBclkTimeSlice; // task timeslice (in bus clocks)
358 uintnbr mDecSave; // decrementer save
359 uintnbr mSavedMSR; // temporarly saved mrs over singelstep
360 public:
361 enum {
362 eTskFlgFloatingpoint = 0x00000001,
363 eTskFlgIrqDisabled = 0x00000002,
364 eTskFlgTimeslice = 0x00000004,
365 eTskFlgTimingFailureHaltTask = 0x00000008,
366 eTskFlgDebugTimingDisableIrq = 0x00000010,
367 eTskFlgStartupDone = 0x00000020,
368 eTskFlgShutdownRequest = 0x00000040,
369 eTskFlgFunctionValid = 0x00000080,
370 eTskFlgShutdownPending = 0x00000100,
371 eTskFlgStackProtection = 0x00000200,
372 eTskFlgPriorityCheck = 0x00000400,
373 eTskFlgSuspendTimingCheck = 0x00000800,
374 eTskFlgSuspendHookRunning = 0x00001000,
375 eTskFlgIncoTouch = 0x00002000,
376 };
377 uint32 m_uTskFlags;
379 uint32 m_uTskId = 0;
381 uint32 m_uTskNxtId = 0;
383 uint32 m_uTskPrvId = 0;
385 uint32 m_uTskParentId = 0;
387 volatile uint32 m_uTskLastChildId = 0;
388
389 // sync handling
390 private:
391 CINOSMutex* pActualMutex; // pointer to actual mutex
392
393 // IMPORTANT: Do not use this member in new projects, as it will not be available
394 // anymore in the future. But some projects of key customers rely on
395 // an 'only' protected' member.
396 protected:
397 CINOSSync* pActualSync; // pointer to actual sync object
398
399 private:
400 tTaskId m_idNxtWaiting; // id of next task waiting for a sync object
401
402 // exception handling members
403 private:
404 uint32 mExceptionState; // exception state
405 class CINOSException* pExceptionPending; // pointer to pending exception
406 class CINOSExceptionContext* pExceptionContext; // pointer to task exception context
407
408 // task data
409 private:
410 char* pName; // task name
411 char* pNameSave = nullptr;// task name used at shutdown
412 uint32 mTaskIdentification;// task id pattern (0x05640172)
413 _reent* m_pReentrancy; // pointer to _reent structure (libc reentrancy)
414 uint32 mTimer_1ms; // 1ms timer (for Sleep)
415
416 // timing data (all data in ticks (4 bus cycles (603) / 1 cpu cycle (403))
417 uint64 m_uTbRestore; // timebase at restore
418 uint64 m_uTbTask; // task timebase
419 uint32 m_uTbEntry; // timebase at method entry
420 uint32 m_uTbOld; // task timebase at last suspend
421 uint32 m_uTbAct; // actual used cpu time
422 uint32 m_uTbMin; // min. used cpu time
423 uint32 m_uTbMax; // max. used cpu time
424 uint32 mResumeTime; // timebase at task resume
425 uint64 mResumeTimeNs; // timebase at task resume [ns]
426 uint32 mMinResponseTime; // min. response time (resume until active)
427 uint32 mMaxResponseTime; // max. response time (resume until active)
428 uint32 mActResponseTime; // actual response time (resume until active)
429 uint32 mSinglestepInstruction; // The instruction which we singlestep. we need to store it because it can't always be calculated in the interrupt handler, becuase after a 'branch instruction', the stepped over instruction can't be calculated anymore.
430 uint32 m_uActivity;
431
432 uint16 mError; // task error (used for callprocedure etc.)
433 uint16 mClassSize; // size of class (used for delete operator)
434 static uint32 m_uDebugUpdateId; // update id that changes whenever a "debug setting" changes, such as breakpoint/watchpoint added, removed, etc.
435 void* m_pHandler;
436 void* m_pObject;
449 uint64 m_uBusTickAtIrq;
450
451 // private member functions
452 private :
453 // prepare stack context
454 void PrepareStack(bool aInterruptsDisabled, void* apHandler, void* apObject);
455 // main loop (called at startup)
456 void MainLoop();
457
458 // public debug functions
459 public :
464 enum ETaskErrorFlags {
465 // note: the lower Byte is currently used to send inco errors,
466 // such as 'wrong param count' (defRpcNumberParam) to the caller,
467 // therfore do not use the lower Byte
468
469 eFlagCalledByINCO = 0x100,
470 eFlagUseINCO4AsyncResultMgr = 0x200,
471#if defined(INCO_RETRY_AWARE_GETVARIABLE)
472 eFlagINCODenyRetries = 0x400
473#endif
474 };
475 virtual void MsgReply(
476 CINOSTaskExMsg* apMsg, uint32 auReply, uint32 aAppError)
477 {}
478 uint32 GetError()
479 {return mError;}
480 # if defined(INCO_DEPRECATED_CALLPROCEDURE_ERRORS)
481 // Some projects of key customers return CallProcedure errors via this SetError method
482 public:
483 #else
484 // SetError is private to avoid code that accidentally sets the error of the task with
485 // an unsupported error.
486 private:
487 #endif
488 void SetError(uint32 aError)
489 { mError=(uint16)aError;}
490 public:
491 uint32 GetId()
492 {return mTaskIdentification;}
493 void SetId(uint32 aId)
494 { mTaskIdentification=aId;}
495 uint32 GetTaskId()
496 { return m_uTskId; }
497 uint32 GetParentId()
498 { return m_uTskParentId; }
499 uint32 GetState () const
500 { return mState;}
501 void SetState(uint16 aState)
502 { mState=aState;}
503 uint32 GetPriority()
504 { return mPriority;}
508 void SetPriority(uint32 auPriority);
509
510 uint32 GetTrapNumber()
511 { return mTrapNumber;}
512 void SetTrapNumber(uint32 aNumber)
513 { mTrapNumber = (uint16)aNumber;}
514 uint32 GetCycleTicks()
515 { return mCycleTicks&0x00ffffff;}
516 uint32 SetCycleTicks(uint32 auCycleTicks)
517 { return mCycleTicks = auCycleTicks;}
518 uint8 GetOversampling()
519 { return (uint8) ((mCycleTicks>>24)&0xff);}
520 void SetOversampling(uint8 auOversampling)
521 { mCycleTicks = (mCycleTicks&0x00ffffff)|(auOversampling<<24);}
522 uint32 GetResumeTicks()
523 { return mResumeTime;}
524 uint64 GetResumeTimeNs()
525 { return mResumeTimeNs;}
526 void SetResumeTimeNs(uint64 auResumeTimeNs)
527 { mResumeTimeNs = auResumeTimeNs;}
528 uint32 GetTbEntry()
529 { return m_uActivity;}
532 uint64 GetTbTask() const
533 {
534 uint32 uMsr = INOSDisableInterrupts();
535 uint64 uValue = m_uTbTask;
536 INOSEnableInterrupts(uMsr);
537 return uValue;
538 }
542 uint64 GetTbTaskReal() const
543 {
544 uint64 uCurrentTicks = GetSystemTicks();
545 const CINOSTask* pTask = ActualTask();
546 uint32 uMsr = INOSDisableInterrupts();
547 uint64 uTskTicks = pTask->m_uTbTask;
548 uint64 uTskRestore = pTask->m_uTbRestore;
549 INOSEnableInterrupts(uMsr);
550 if (uCurrentTicks > uTskRestore) uTskTicks += (uCurrentTicks-uTskRestore);
551 return uTskTicks;
552 }
555 uint64 GetTbRestore() const
556 {
557 uint32 uMsr = INOSDisableInterrupts();
558 uint64 uValue = m_uTbRestore;
559 INOSEnableInterrupts(uMsr);
560 return uValue;
561 }
562 uint16 GetClassSize()
563 { return mClassSize;}
564 _reent* GetReentrancy()
565 {
566 m_uReentrancyTouched++;
567 return m_pReentrancy;
568 };
569 uint32 GetReentrancyTouched()
570 {
571 return m_uReentrancyTouched;
572 };
573
574 char* GetName() const
575 { return pName;}
576 CINCOObject* iGetRegister();
577
578 uint32 SingleStep();
579 uint32 RangeStep(uint32 auFrom, uint32 auTo);
580 uint32 Halt();
581 uint32 Run();
582
583 uint32 GetPC(uintnbr* aValue);
584 uint32 PutPC(uintnbr aValue);
585 uint32 GetLR(uintnbr* aValue);
586 uint32 GetSPR(uint32 aNumber, uint32* aValue);
587 uint32 PutSPR(uint32 aNumber, uint32 aValue);
588 uint32 GetSPRs(uint32* aResult);
589 uint32 GetSPRsGdb(uint32* aResult);
590
591 uint32 GetGPR(uint32 aNumber, uint32* aValue);
592 uint32 PutGPR(uint32 aNumber, uint32 aValue);
594 uint32 GetGPRs(uint32* aResult, bool abNative=false);
595
598 uint32 GetGdbRegsSize(uint32& auSize);
599
602 uint32 GetGdbRegs(void* apData);
603
609 uint32 PutGdbReg(const uint32 auRegister, const void* apData, uint32 auDataLength);
610
611 uint32 GetFPR(uint32 aNumber, double* aValue);
612 uint32 PutFPR(uint32 aNumber, double aValue);
613 uint32 GetFPRs(double* aResult);
614 #ifdef E500V2
615 uint32 GetEVHs(uint32* aResult);
616 uint32 GetSPE(uint32* aResult);
617 #endif
618
619 uint32 GetTaskData(uint32 aDataDef, uintnbr* aResult, uint32& aLength);
620 uint32 PutTaskData(uint32 aDataDef, uint32* aData, uint32 aLength);
621
622 bool DisableFloatingPoint();
623 bool EnableFloatingPoint();
624
627 uint16 EnableExceptions();
628
631 void RestoreExceptions(uint16 auLevel);
632
635 bool AreExceptionsEnabled();
636
637 // checks the passed address against the stack of this task and returns true
638 // if the address belongs to the tasks stack or false otherwise.
639 bool IsAddressOnStack(uintptr auAddress) const;
640 // return stack size [bytes]
641 uint32 GetStackSize() const;
642
643 // returns size of the stack that has never been allocated yet [bytes]
644 // this is used to determine the maximum stack usage so far in percent,
645 // and if this is zero, most likely a stack overflow happened at some time
646 uint32 GetStackSizeFree() const;
647
648 #if !defined(INOS_DESKTOP)
649 // return stack still left [bytes]
650 uintnbr GetStackLeft() const
651 {
652 uintnbr uSp;
653 #if defined(INOS_CPU_CORTEXA9)
654 asm volatile ("mov %0,sp" : "=r" (uSp));
655 #elif defined(INOS_CPU_ARMV8)
656 asm volatile ("mov %0,sp" : "=r" (uSp));
657 #else
658 asm volatile ("mr %0,1" : "=r" (uSp));
659 #endif
660 return uSp - (uintnbr)pStackEnd;
661 }
662 #endif
663
668 static uint32 GetDebugUpdateId();
671 static void ChangeDebugUpdateId();
672
673#ifdef INOS_STACKPROTECTION
674 void ProtectStack();
675 void UnprotectStack();
676 void StackProtectionEnable() {
677 m_uTskFlags |= eTskFlgStackProtection;
678 }
679 void StackProtectionDisable() {
680 m_uTskFlags &= ~eTskFlgStackProtection;
681 }
682 bool StackProtectionEnabled() const {
683 return m_uTskFlags & eTskFlgStackProtection;
684 }
685#endif
686
687 // protected member functions
688 protected :
689 // sleep 'aTime' ms and return 0 if the requested time was slept or the
690 // number of remaining ms if the task was resumed by someone else before
691 // aTime ms
692 #ifndef INOS_DESKTOP
693 friend long Sleep(long aTime);
694 #endif
695
696 // exception handling member functions
697 public:
698 // throw exception to myself
699 void ThrowException(CINOSException* aException);
700 // throw exception to myself (running in a context of a different task)
701 void ThrowExceptionToTask(CINOSException* aException);
702 // accept exception
703 void AcceptException();
704 // ignore exception
705 void IgnoreException();
706 #ifdef INOS_EXCEPTION_MUTEX
707 CINOSMutex* pExceptionMutex;
708 #endif
711 inline void SetBusTicksAtIrq(uint64 auBusTicks) {
712 #ifdef INOS_ARCH_ARM
713 m_uBusTickAtIrq = auBusTicks;
714 #else
715 // avoid double instructions, because FP instructions are usually
716 // not allowed in the context of calling this function (e.g.
717 // GINLink interrupt context), because on PPC, the FP-unit is
718 // disabled and on ARM, the IRQ tasks do not save the FP-registers.
719 // That's why we need to ensure that the compiler doesn't generate
720 // FP-instructions.
721 const uint32* pSrc = reinterpret_cast<const uint32*>(&auBusTicks);
722 uint32* pDst = reinterpret_cast<uint32*>(&m_uBusTickAtIrq);
723 pDst[0] = pSrc[0];
724 pDst[1] = pSrc[1];
725 #endif
726 }
729 inline uint64 GetBusTicksAtIrq() const {
730 return m_uBusTickAtIrq;
731 }
732
733 // allow dynamic object handling (new/delete)
734 void* operator new(size_t aSize);
735 void operator delete(void* aPtr);
736
737 // private member functions
738 protected :
739 // create task
740 void Create(char* apName = nullptr, uint32 auStackSize=defDefaultStackSize,
741 uint32 auPriority=DF_INOS_TASK_PRIO_LOWEST, bool abFloatingPoint=true,
742 uint32 auTimeSlice=defDefaultTimeSlice, bool abInterruptsDisabled=false,
743 void* apHandler=0, void* apObject=0);
744 // allocate task stack
745 void* AllocStack(uint32 auSize);
746 // reallocate task stack
747 void ReAllocStack(uint32 auSize);
748 // free task stack
749 void FreeStack();
750
752 virtual CINOSSync* GetSync();
754 virtual void SetCallResult(CMcResult aResult);
756 virtual CMcResult GetCallResult();
757
758 public:
761 struct STLSKeyData* TLSFindData(STLSKeyData* apKeyData) const;
763 void TLSAddData(struct STLSKeyData* apKeyData);
766 void TLSRemoveData(struct STLSKeyData* apKeyData);
767
768 #ifdef INOS_MULTICORE_KERNEL
770 void SetCoreSync(struct SINOSCoreSync* apCoreSync) { m_pCoreSync = apCoreSync; };
772 struct SINOSCoreSync* GetCoreSync() { return m_pCoreSync; };
774 uint8 GetTaskCoreId() const { return m_uTaskCoreId; }
775 //** Set Id of CPU core this task has to run on.
776 void SetTaskCoreId(uint8 auCoreId)
777 { m_uTaskCoreId = auCoreId; m_uTaskCoreIdRequested = auCoreId; };
781 void SetTaskCoreIdRequested(uint8 auCoreIdRequested)
782 { m_uTaskCoreIdRequested = auCoreIdRequested; };
784 uint8 GetTaskCoreIdRequested()
785 { return m_uTaskCoreIdRequested; };
786 #else
788 struct SINOSCoreSync* GetCoreSync() { return nullptr; };
790 uint8 GetTaskCoreId() const { return 0; }
791 #endif
792 //** Set fieldbus category this task belongs to.
793 void SetTaskCategory(uint8 auCategory)
794 { m_uTaskCategory = auCategory; };
795 //** Get fieldbus category this task belongs to.
796 uint8 GetTaskCategory()
797 { return m_uTaskCategory; };
801 void EnableTimingFailureHaltTask() {
802 m_uTskFlags |= eTskFlgTimingFailureHaltTask;
803 }
807 void DisableTimingFailureHaltTask() {
808 m_uTskFlags &= (~eTskFlgTimingFailureHaltTask);
809 }
812 bool IsTimingFailureHaltTaskEnabled() {
813 return (m_uTskFlags & eTskFlgTimingFailureHaltTask);
814 }
815
819 inline void EnableIrqDisableTiming() {
820 m_uTskFlags |= eTskFlgDebugTimingDisableIrq;
821 }
825 inline void DisableIrqDisableTiming() {
826 m_uTskFlags &= (~eTskFlgDebugTimingDisableIrq);
827 }
830 inline bool IsIrqDisableTimingEnabled() {
831 return (m_uTskFlags & eTskFlgDebugTimingDisableIrq);
832 }
836 inline void EnablePriorityChecking() {
837 m_uTskFlags |= eTskFlgPriorityCheck;
838 }
841 inline void DisablePriorityChecking() {
842 m_uTskFlags &= (~eTskFlgPriorityCheck);
843 }
846 inline bool IsPriorityCheckingEnabled() {
847 return (m_uTskFlags & eTskFlgPriorityCheck);
848 }
852 inline void EnableSuspendTimingCheck() {
853 m_uTskFlags |= eTskFlgSuspendTimingCheck;
854 }
857 inline void DisableSuspendTimingCheck() {
858 m_uTskFlags &= (~eTskFlgSuspendTimingCheck);
859 }
862 inline bool IsSuspendTimingCheckEnabled() {
863 return (m_uTskFlags & eTskFlgSuspendTimingCheck);
864 }
866 inline bool IsStartupDone() {
867 return (m_uTskFlags & eTskFlgStartupDone);
868 }
870 inline void EnableIncoTouch() {
871 m_uTskFlags |= eTskFlgIncoTouch;
872 }
874 inline void DisableIncoTouch() {
875 m_uTskFlags &= (~eTskFlgIncoTouch);
876 }
878 inline bool IsIncoTouchEnabled() {
879 return (m_uTskFlags & eTskFlgIncoTouch);
880 }
882 inline void EnableFloatingpoint() {
883 m_uTskFlags |= eTskFlgFloatingpoint;
884 }
886 inline void DisableFloatingpoint() {
887 m_uTskFlags &= (~eTskFlgFloatingpoint);
888 }
890 inline bool IsFloatingpointEnabled() {
891 return (m_uTskFlags & eTskFlgFloatingpoint);
892 }
894 void SetTskFlag(uint32 auFlag) {
895 m_uTskFlags |= auFlag;
896 }
897 /* \return Reference to the time stamp (in system ticks) when the
898 INOSDisableInterrupts() function has been called. The value is 0
899 if the function has not been called or if the INOSEnableInterrupts
900 has already been called again. */
901 inline uint32& GetIrqDisableTicks() {
902 return m_uIrqDisableTicks;
903 }
905 inline bool IsRealtime() {
906 return (m_eTskType == eTskTypeInterrupt) || ((m_eTskType == eTskTypeRealtime));
907 }
908
909 private:
911 TINOSBalancedBinaryTree<STLSKeyData> m_TLS;
913 mutable CINOSMutex m_TLSLock;
914 // call sync
915 CINOSSync* m_pCallSync{};
916 // call result
917 CMcResult* m_pCallResult{};
918 // multi core sync
919 #ifdef INOS_MULTICORE_KERNEL
920 struct SINOSCoreSync* m_pCoreSync;
922 uint8 m_uTaskCoreId = GetCoreId();
924 uint8 m_uTaskCoreIdRequested = DF_INOS_CORE_DEFAULT;
925 #endif
927 uint8 m_uTaskCategory = 0xff;
928 // thread handle
929 #if defined(INOS_DESKTOP)
930 friend class CINOSKernel_desktop;
931 friend void _Suspend(uint32 auState, uint32 auFlags, CINOSTask* apTask);
932 friend void Resume(CINOSTask* apTask, uint32 auFlags);
933 friend void Relinquish();
934 friend void ChangePriority(uint32 auPriority);
935 std::thread* m_pThread = nullptr;
936 std::condition_variable_any m_Startup;
937 std::condition_variable_any m_Resume;
938 #endif
950 uint32 m_uIrqDisableTicks = 0;
951
953 uint32 m_uExitCode = 0;
955 CINOSSync* m_pShutdownDone = nullptr;
957 CINOSMutex m_ShutdownMutex = CINOSMutex(CINOSMutex::eFlgReclaimLock);
959 alignas(4) inosName128 m_cName = {0};
961 void* m_pFunctionParam = nullptr;
963 std::function<void(void*)> m_Function;
965 ETskType m_eTskType = eTskTypeSystem;
967 uint32 m_uReentrancyTouched{};
968
969 #if !defined(INOS_DESKTOP) && defined(INOS_THREADLOCAL)
971 uint8* m_pThreadLocal{};
972 uint8* m_pThreadLocalBase{};
973 #endif
974
976};
977
978//------------------------------------------------------------------------------
979//--- class CINOSTaskType ------------------------------------------------------
980//------------------------------------------------------------------------------
981
983{
984 //--- user interface ---------------------------------------------------
985
986 // public members
987 public :
992 { m_eType = ActualTask()->SetTskType(aeType);};
993
998
999 //--- internals --------------------------------------------------------
1000
1001 // protected members
1002 protected :
1005};
1006
1007//------------------------------------------------------------------------------
1008// end of file
1009//------------------------------------------------------------------------------
1010
1011#endif // INC_INOSTASK_H
Definition cinostaskex.h:2715
Definition inos_syn.h:368
Definition inoskernel.h:229
Definition inos_syn.h:235
Definition cinosmutex.h:36
Definition cinossiotftexp.h:731
Definition inos_syn.h:67
Definition cinostaskex.h:396
Definition cinostaskex.h:966
Definition cinostask.h:983
CINOSTaskType(CINOSTask::ETskType aeType)
Set task type to the requested value.
Definition cinostask.h:991
CINOSTask::ETskType m_eType
original type
Definition cinostask.h:1004
~CINOSTaskType()
Restore original type.
Definition cinostask.h:996
Definition cinostask.h:52
virtual void Exit()
Terminate myself. Exit code is INOS_OK or the code previously set with SetExitCode.
virtual ~CINOSTask()
Destroy task.
virtual void Exit(uint32 auExitCode)
Terminate myself.
INOS_INLINE ETskType SetTskType(ETskType aeType)
Set task type.
Definition cinostask.h:208
CINOSTask(const char *apName, std::function< void(void *)> aFunction, void *apParam=nullptr, uint8 auPriority=DF_INOS_TASK_PRIO_LOWEST)
Create a task with given properties. One needs to Resume the task after creation to get it running.
ETskType
Task types.
Definition cinostask.h:180
virtual uint32 Shutdown(CINOSSync *apSync=DF_INOS_SYNCHRONOUS)
Shutdown task, used to shutdown a foreign task.
virtual void SetExitCode(uint32 auExitCode)
Set exit code.
Definition cinostask.h:135
virtual void ClrSuspendHook()
Clear Suspend hook.
Definition cinostask.h:166
INOS_INLINE ETskType GetTskType()
Get task type.
Definition cinostask.h:201
virtual uint32 GetExitCode()
Get exit code.
Definition cinostask.h:140
virtual void SetSuspendHook(void *apSuspendHook)
Set Suspend hook.
Definition cinostask.h:152
virtual bool CheckShutdown()
Check if a shutdown is pending.
Definition cinostask.h:146
virtual void Action()
Task action loop, needs to be overwritten by the user. For more info, see section Creation.
virtual void * GetSuspendHook()
Get Suspend hook if any.
Definition cinostask.h:173
CINOSTask(std::function< void(void *)> aFunction, void *apParam=nullptr, uint8 auPriority=DF_INOS_TASK_PRIO_LOWEST)
Create a task with given properties. One needs to Resume the task after creation to get it running.
CINOSTask(char *apName=nullptr, uint32 auStackSize=defDefaultStackSize, uint32 auPriority=DF_INOS_TASK_PRIO_LOWEST, bool abFloatingPoint=true, uint32 auTimeSlice=defDefaultTimeSlice, bool abInterruptsDisabled=false, void *apHandler=0, void *apObject=0)
Create a task with given properties. One needs to Resume the task after creation to get it running.
virtual uint32 Join()
Join task or in other words, wait till it terminates.
virtual void Detach()
Detach task from parent. One uses this method if one doesn't want this task to be shut down if the pa...
CINOSTask * ActualTask()
#define DF_INOS_TASK_PRIO_LOWEST
Definition inosdefine.h:192
#define INOS_INLINE
Definition inosdefine.h:60
#define DF_INOS_CORE_DEFAULT
Definition inosdefine.h:175
#define DF_INOS_SYNCHRONOUS
Definition inosmacro.h:332
Definition inostype.h:192