31 #include <oc_system_cfg.h> 32 #include <oc_stdlib.h> 44 #define _________________________________________TYPES_SECTION______________________________________________________________________________ 48 oC_Thread_RevertFunction_t Function;
53 typedef oC_Thread_FinishedFunction_t FinishedFunction_t;
87 typedef bool (*CheckFunction_t)( uint32_t Value , uint32_t Expected , oC_Thread_UnblockMask_t
UnblockMask );
89 #undef _________________________________________TYPES_SECTION______________________________________________________________________________ 96 #define _________________________________________LOCAL_PROTOTYPES_SECTION___________________________________________________________________ 98 static void ThreadExitHandler(
void );
99 static bool CheckUnblockedWhenEqual ( uint32_t Value , uint32_t Expected , oC_Thread_UnblockMask_t
UnblockMask );
100 static bool CheckUnblockedWhenNotEqual ( uint32_t Value , uint32_t Expected , oC_Thread_UnblockMask_t
UnblockMask );
101 static bool CheckUnblockedWhenSmaller ( uint32_t Value , uint32_t Expected , oC_Thread_UnblockMask_t
UnblockMask );
102 static bool CheckUnblockedWhenGreater ( uint32_t Value , uint32_t Expected , oC_Thread_UnblockMask_t
UnblockMask );
103 static bool CheckUnblockedWhenSmallerOrEqual( uint32_t Value , uint32_t Expected , oC_Thread_UnblockMask_t
UnblockMask );
104 static bool CheckUnblockedWhenGreaterOrEqual( uint32_t Value , uint32_t Expected , oC_Thread_UnblockMask_t
UnblockMask );
106 #undef _________________________________________LOCAL_PROTOTYPES_SECTION___________________________________________________________________ 114 #define _________________________________________VARIABLES_SECTION__________________________________________________________________________ 116 static const uint16_t NotUsedByteValue = 0xbeef;
117 static const CheckFunction_t CheckFunctions[] = {
118 CheckUnblockedWhenEqual ,
119 CheckUnblockedWhenNotEqual,
120 CheckUnblockedWhenSmaller ,
121 CheckUnblockedWhenGreater ,
122 CheckUnblockedWhenSmallerOrEqual ,
123 CheckUnblockedWhenGreaterOrEqual
126 #undef _________________________________________VARIABLES_SECTION__________________________________________________________________________ 134 #define _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________ 152 process = oC_ProcessMan_GetCurrentProcess();
155 if(oC_Process_IsCorrect(process) ==
false)
157 kdebuglog(oC_LogType_Error,
"thread: process 0x%08X is not correct" , Process);
160 allocator = oC_Process_GetAllocator(process);
164 StackSize = oC_ThreadMan_GetDefaultStackSize();
171 thread = kmalloc(
sizeof(
struct Thread_t) , allocator , AllocationFlags_CanWait1Second | AllocationFlags_ZeroFill );
175 oC_MemorySize_t redZoneSize = oC_ThreadMan_GetRedZoneSize();
178 void * endStack = (
void*)(((oC_UInt_t)realStack) + minimumContextSize);
181 for(uint16_t * stack = (uint16_t*)realStack; stack < ((uint16_t*)endStack) ; stack++ )
183 *stack = NotUsedByteValue;
188 oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
192 thread->
Priority = Priority + oC_Process_GetPriority(process);
229 if(errorCode == oC_ErrorCode_ModuleNotStartedYet)
235 if(oC_ErrorOccur(errorCode))
237 oC_SaveError(
"Thread: Cannot initialize context" , errorCode);
239 if(!kfree(realStack , AllocationFlags_CanWait1Second) ||
240 !kfree(thread , AllocationFlags_CanWait1Second)
243 oC_SaveError(
"Thread: Cannot release memory" , oC_ErrorCode_AllocationError);
250 bool stackReleased = kfree(realStack,0);
252 oC_SaveIfFalse(
"Stack" , stackReleased || realStack ==
NULL, oC_ErrorCode_ReleaseError);
253 if(!kfree(thread,AllocationFlags_CanWait1Second))
255 oC_SaveError(
"Thread: Cannot release memory" , oC_ErrorCode_AllocationError);
276 if(oC_Thread_IsCorrect(Thread) && (outAddressInRedZone ==
NULL || isram(outAddressInRedZone)))
283 if(outAddressInRedZone !=
NULL)
285 void * redZoneStart = Thread->
RedZone;
287 *outAddressInRedZone = Address >= redZoneStart && Address <= redZoneEnd;
290 owned = Address >= stackStart && Address < stackEnd;
302 if(oC_Thread_IsCorrect(Thread) && NewStackSize > 0)
314 bool deleted =
false;
316 if(isram(Thread) && oC_Thread_IsCorrect(*Thread))
318 if(oC_ThreadMan_GetCurrentThread() != (*Thread))
320 uint32_t blockingFlag = 0;
321 bool threadRemoved =
false;
323 oC_Thread_SetBlocked(*Thread,&blockingFlag,oC_Thread_Unblock_WhenEqual,0xff,oC_Thread_UnblockMask_All,oC_hour(1));
325 oC_IntMan_EnterCriticalSection();
327 if(oC_Thread_IsActive(*Thread))
329 threadRemoved = oC_SaveIfErrorOccur(
"Thread - Removing from list: ", oC_ThreadMan_RemoveThread(*Thread));
330 deleted = threadRemoved;
331 (*Thread)->ObjectControl = 0;
335 void * realStack = (*Thread)->RealStackStart;
337 bool stackReleased =
false;
338 bool objectReleased=
false;
340 oC_ARRAY_FOREACH_IN_ARRAY((*Thread)->ActionsToRevert,action)
342 if(action->Function !=
NULL)
344 if(oC_SaveIfFalse(
"cannot revert action", isaddresscorrect(action->Function), oC_ErrorCode_WrongAddress))
346 oC_SaveIfFalse(
"cannot revert action", action->Function(*Thread,action->Object,action->
Parameter), oC_ErrorCode_InternalDataAreDamaged );
351 threadRemoved =
true;
352 (*Thread)->ObjectControl = 0;
354 stackReleased = kfree(realStack, AllocationFlags_CanWaitForever);
355 objectReleased = kfree(*Thread, AllocationFlags_CanWaitForever);
359 && oC_SaveIfFalse(
"Thread - Stack - ", stackReleased , oC_ErrorCode_ReleaseError )
360 && oC_SaveIfFalse(
"Thread - Object - ", objectReleased , oC_ErrorCode_ReleaseError )
368 oC_IntMan_ExitCriticalSection();
373 oC_IntMan_EnterCriticalSection();
375 oC_ErrorCode_t errorCode = oC_ThreadMan_RemoveThread(*Thread);
377 if(oC_ErrorOccur(errorCode))
379 oC_SaveError((*Thread)->Name , errorCode);
386 oC_IntMan_ExitCriticalSection();
388 if(oC_IntMan_AreInterruptsTurnedOn())
410 return oC_Thread_IsCorrect(Thread) && oC_ThreadMan_ContainsThread(Thread);
417 bool blocked =
false;
420 oC_Thread_IsCorrect(Thread) &&
425 oC_IntMan_EnterCriticalSection();
431 oC_IntMan_ExitCriticalSection();
433 oC_ThreadMan_SwitchThread();
445 bool unblocked =
false;
447 if(oC_Thread_IsCorrect(Thread))
449 oC_IntMan_EnterCriticalSection();
453 oC_IntMan_ExitCriticalSection();
455 oC_ThreadMan_SwitchThread();
467 if(oC_Thread_IsCorrect(Thread))
469 oC_IntMan_EnterCriticalSection();
470 oC_Timestamp_t currentTimestamp = oC_KTime_GetTimestamp();
476 oC_IntMan_ExitCriticalSection();
480 ((blockedFlagRef !=
NULL) && (CheckFunctions[Thread->
Unblock](blockedFlag,stateToUnblock,unblockMask)) && (currentTimestamp < timeout))
497 bool oC_Thread_IsBlockedBy(
oC_Thread_t Thread , uint32_t * BlockingFlag )
499 return oC_Thread_IsCorrect(Thread) && isram(BlockingFlag) && Thread->
BlockedFlag == BlockingFlag;
508 if(oC_Thread_IsCorrect(Thread))
510 oC_ErrorCode_t errorCode = oC_ThreadMan_AddThread(Thread);
512 if(oC_ErrorOccur(errorCode))
514 oC_SaveError(Thread->
Name,errorCode);
529 bool canceled =
false;
531 if(oC_Thread_IsCorrect(*Thread))
537 if(oC_SaveIfFalse(
"Finished Function", isaddresscorrect(thread->
FinishedFunction), oC_ErrorCode_WrongAddress))
544 oC_ErrorCode_t errorCode = oC_ThreadMan_RemoveThread(*Thread);
546 if(oC_ErrorOccur(errorCode))
548 oC_SaveError((*Thread)->Name , errorCode);
564 void * context =
NULL;
566 if(oC_Thread_IsCorrect(Thread))
576 oC_Thread_Priority_t oC_Thread_GetPriority(
oC_Thread_t Thread )
578 oC_Thread_Priority_t priority = 0;
580 if(oC_Thread_IsCorrect(Thread))
590 void * oC_Thread_GetParameter(
oC_Thread_t Thread )
592 void * parameter =
NULL;
594 if(oC_Thread_IsCorrect(Thread))
604 const char * oC_Thread_GetName(
oC_Thread_t Thread )
606 const char * name =
"incorrect thread";
608 if(oC_Thread_IsCorrect(Thread))
618 bool oC_Thread_Sleep(
oC_Thread_t Thread , oC_Time_t Time )
622 if(oC_Thread_IsCorrect(Thread))
624 oC_IntMan_EnterCriticalSection();
629 oC_IntMan_ExitCriticalSection();
631 while(oC_Thread_IsBlocked(Thread));
639 oC_Time_t oC_Thread_GetExecutionTime (
oC_Thread_t Thread )
641 oC_Time_t executionTime = 0;
643 if(oC_Thread_IsCorrect(Thread))
648 return executionTime;
653 bool oC_Thread_AddToExecutionTime(
oC_Thread_t Thread , oC_Time_t Time )
657 if(oC_Thread_IsCorrect(Thread))
667 uint64_t oC_Thread_GetLastExecutionTick(
oC_Thread_t Thread )
671 if(oC_Thread_IsCorrect(Thread))
681 bool oC_Thread_SetLastExecutionTick(
oC_Thread_t Thread , uint64_t Tick )
685 if(oC_Thread_IsCorrect(Thread))
695 oC_UInt_t oC_Thread_GetStackSize(
oC_Thread_t Thread )
699 if(oC_Thread_IsCorrect(Thread))
714 oC_Int_t oC_Thread_GetFreeStackSize(
oC_Thread_t Thread ,
bool Current )
718 if(oC_Thread_IsCorrect(Thread))
727 uint16_t* redZoneEnd = (
void*)(((oC_UInt_t)Thread->
RedZoneEnd));
734 for(uint16_t * stack = (uint16_t*)Thread->
RedZone ; stack < redZoneEnd ; stack++ )
736 if(*stack != NotUsedByteValue)
738 size-=
sizeof(uint16_t);
744 uint16_t * stackEnd = (Thread->
StackStart + contextSize);
751 for(uint16_t * stack = Thread->
StackStart ; stack < stackEnd ; stack++ )
753 if(*stack == NotUsedByteValue)
755 size+=
sizeof(uint16_t);
767 bool oC_Thread_SaveToRevert(
oC_Thread_t Thread , oC_Thread_RevertFunction_t Function,
void * Object , uint32_t Parameter )
769 bool success =
false;
772 oC_SaveIfFalse(
"Thread object", oC_Thread_IsCorrect(Thread), oC_ErrorCode_ObjectNotCorrect )
773 && oC_SaveIfFalse(
"Function" , isaddresscorrect(Function) , oC_ErrorCode_WrongAddress )
776 oC_IntMan_EnterCriticalSection();
779 if(action->Function ==
NULL)
782 action->Object = Object;
789 oC_IntMan_ExitCriticalSection();
790 oC_SaveIfFalse(
"Cannot add function", success, oC_ErrorCode_NoFreeSlots);
798 bool oC_Thread_RemoveFromRevert(
oC_Thread_t Thread , oC_Thread_RevertFunction_t Function,
void * Object )
800 bool success =
false;
803 oC_SaveIfFalse(
"Thread object", oC_Thread_IsCorrect(Thread), oC_ErrorCode_ObjectNotCorrect )
804 && oC_SaveIfFalse(
"Function" , isaddresscorrect(Function) , oC_ErrorCode_WrongAddress )
807 oC_IntMan_EnterCriticalSection();
810 if(action->Function == Function && action->Object == Object)
812 action->Function =
NULL;
813 action->Parameter = 0;
814 action->Object =
NULL;
819 oC_IntMan_ExitCriticalSection();
820 oC_SaveIfFalse(
"Cannot remove function", success, oC_ErrorCode_ObjectNotFoundOnList);
828 bool oC_Thread_SetFinishedFunction(
oC_Thread_t Thread , oC_Thread_FinishedFunction_t Function,
void * Parameter )
830 bool success =
false;
833 oC_SaveIfFalse(
"Thread object", oC_Thread_IsCorrect(Thread), oC_ErrorCode_ObjectNotCorrect )
834 && oC_SaveIfFalse(
"Function" , isaddresscorrect(Function) , oC_ErrorCode_WrongAddress )
845 #undef _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________ 853 #define _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________ 857 static void ThreadExitHandler(
void )
859 oC_Thread_t thread = oC_ThreadMan_GetCurrentThread();
860 oC_List(
oC_Thread_t) threads = oC_ThreadMan_GetList();
861 bool contains = oC_List_Contains(threads,thread);
865 if(oC_SaveIfFalse(
"Finished Function", isaddresscorrect(thread->
FinishedFunction), oC_ErrorCode_WrongAddress))
872 if(oC_Thread_IsCorrect(thread) && contains)
874 oC_Thread_Delete(&thread);
881 static bool CheckUnblockedWhenEqual( uint32_t Value , uint32_t Expected , oC_Thread_UnblockMask_t UnblockMask )
883 return (Value & UnblockMask) != (Expected &
UnblockMask);
888 static bool CheckUnblockedWhenNotEqual( uint32_t Value , uint32_t Expected , oC_Thread_UnblockMask_t UnblockMask )
890 return (Value & UnblockMask) == (Expected &
UnblockMask);
895 static bool CheckUnblockedWhenSmaller( uint32_t Value , uint32_t Expected , oC_Thread_UnblockMask_t UnblockMask )
897 return (Value & UnblockMask) >= (Expected &
UnblockMask);
902 static bool CheckUnblockedWhenGreater( uint32_t Value , uint32_t Expected , oC_Thread_UnblockMask_t UnblockMask )
904 return (Value & UnblockMask) <= (Expected &
UnblockMask);
909 static bool CheckUnblockedWhenSmallerOrEqual( uint32_t Value , uint32_t Expected , oC_Thread_UnblockMask_t UnblockMask )
911 return (Value & UnblockMask) > (Expected &
UnblockMask);
916 static bool CheckUnblockedWhenGreaterOrEqual( uint32_t Value , uint32_t Expected , oC_Thread_UnblockMask_t UnblockMask )
918 return (Value & UnblockMask ) < (Expected &
UnblockMask);
921 #undef _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
oC_Int_t oC_SYS_LLD_GetMinimumContextSize(oC_Int_t StackSize)
returns minimum size to allocate for context
void * oC_MemMan_AlignAddressTo(const void *Address, oC_UInt_t Alignment)
returns address aligned to the given alignment.
The file with interface for thread managing.
bool oC_MemMan_IsRamAddress(const void *Address)
checks if address is in ram section
identifier for allocations
oC_ErrorCode_t oC_SYS_LLD_InitializeContext(oC_SYS_LLD_Context_t **Context, oC_Int_t StackSize, oC_SYS_LLD_ContextHandler_t ContextHandler, void *Parameters, oC_SYS_LLD_ContextExitHandler_t ExitHandler)
initializes stack of process
oC_UInt_t oC_MemMan_AlignSizeTo(oC_UInt_t Size, oC_UInt_t Alignment)
returns size aligned to the given alignment
The file with interface for process manager.
uint32_t * BlockedFlag
!< Size of the stack with red zone
oC_Int_t StackSize
!< Tick of last execution
oC_Int_t RealStackSize
!< Pointer to the normal stack (not red zone)
oC_Process_t Process
!< Control value for checking if object is correct
oC_ErrorCode_t oC_SYS_LLD_TurnOnDriver(void)
initializes the driver to work
The file with LLD interface for the MEM driver.
void * StackStart
!< Machine context (stack)
oC_UInt_t * RedZoneEnd
!< Pointer to the red zone
FinishedFunction_t FinishedFunction
!< Parameter to main function
void oC_SYS_LLD_Context_t
type for storing context of the machine
oC_UInt_t * RedZone
!< Name of the thread
The file with helper macros for managing objects.
bool oC_MemMan_IsDynamicAllocatedAddress(const void *Address)
checks if address is in dynamic allocated section
oC_Time_t ExecutionTime
!< Timeout for the blocked state
oC_Thread_Unblock_t Unblock
!< Mask with bits important for unblocking
oC_Int_t oC_SYS_LLD_GetContextStackSize(oC_SYS_LLD_Context_t *Context)
returns size of the stack for context
uint32_t oC_ObjectControl_t
stores object control value
The file with interface for interrupt manager.
static oC_ObjectControl_t oC_CountObjectControl(void *ObjectPointer, oC_ObjectId_t ObjectId)
counts object control for object
static bool oC_CheckObjectControl(void *ObjectPointer, oC_ObjectId_t ObjectId, oC_ObjectControl_t ObjectControl)
checks if object control is correct
uint32_t LastExecutionTick
!< Time of execution of this thread
uint32_t StateToUnblock
!< Reference to the flag of the blocked context
oC_Thread_Function_t Function
!< Size of the stack
oC_Thread_Priority_t Priority
!< Process owner
void * RealStackStart
!< Pointer to end of the RedZone (start of the real stack)
void * FinishedParameter
!< Function to call after thread finish
The file with memory manager interface.
void * Parameter
!< Main function to execute
oC_SYS_LLD_Context_t * Context
!< Pointer to the real stack (real allocated memory)
oC_Timestamp_t TimeoutTimestamp
!< Type of operation to unblock thread
The file with LLD interface for the SYS driver.
bool oC_Thread_IsOwnedByStack(oC_Thread_t Thread, const void *Address, bool *outAddressInRedZone)
checks if the given address is owned by the thread stack
RevertAction_t ActionsToRevert[CFG_UINT8_MAX_ACTIONS_TO_REVERT]
!< Parameter to give to the thread finish
uint32_t UnblockMask
!< State to unblock thread
The file with interface for Thread Manager.
const char * Name
!< Priority of this thread
bool oC_SYS_LLD_IsStackPushDecrementPointer(void)
flag if stack push is decrement pointer
#define oC_MEM_LLD_STACK_ALIGNMENT
number of bytes in alignment of the stack
bool oC_SYS_LLD_IsMachineSupportMultithreadMode(void)
checks if the machine supports multi-thread mode
#define NULL
pointer to a zero
oC_Int_t oC_SYS_LLD_GetContextFreeStackSize(oC_SYS_LLD_Context_t *Context)
returns size of free stack in the context