Choco OS  V.0.16.9.0
Join to the chocolate world
oc_threadman.c
Go to the documentation of this file.
1 
27 #include <oc_threadman.h>
28 #include <oc_sys_lld.h>
29 #include <oc_stdlib.h>
30 #include <oc_system_cfg.h>
31 #include <oc_ktime.h>
32 #include <string.h>
33 #include <oc_processman.h>
34 #include <oc_intman.h>
35 #include <oc_debug.h>
36 #include <oc_userman.h>
37 #include <oc_exchan.h>
38 #include <oc_module.h>
39 
45 #define _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
46 
47 static void MemoryEventHandler( void * Address , MemoryEventFlags_t Event , const char * Function, uint32_t LineNumber );
48 static void SysTickReturnToIdle( void );
49 static void CountCpuLoad( void );
50 static void SysTickHandler(void);
51 
52 #undef _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
53 
54 
60 #define _________________________________________VARIABLES_SECTION__________________________________________________________________________
61 
62 static void * SavedThreadsListAddress = NULL;
63 static oC_Thread_t CurrentThread = NULL;
64 static oC_Time_t InIdleTime = 0;
65 static oC_Time_t CurrentInIdleTime = 0;
66 static double CpuLoad = 0;
67 static double CurrentCpuLoad = 0;
68 static double CpuLoadPanicMargin = CFG_PERCENT_CPU_LOAD_PANIC_MARGIN;
69 static oC_Time_t CpuLoadPanicTimeLimit = CFG_TIME_CPU_LOAD_PANIC_TIME;
70 static oC_Time_t CpuLoadPanicTimeout = 0;
71 static oC_Time_t CpuLoadMeasureTimeout = oC_Frequency_ToTime(CFG_FREQUENCY_CPU_LOAD_MEASUREMENT_FREQUENCY);
72 static oC_Time_t CpuLoadMeasureTime = 0;
73 static oC_Thread_t ThreadToRemove = NULL;
74 static oC_Thread_t NextThread = NULL;
75 static oC_MemorySize_t RedZoneSize = CFG_BYTES_DEFAULT_RED_ZONE_SIZE;
76 static oC_Frequency_t SystemFrequency = CFG_FREQUENCY_DEFAULT_SYSTEM_TIMER_FREQUENCY;
77 static oC_AutoStackMethod_t AutoStackMethod = CFG_BOOL_RERUN_THREAD_WHEN_STACK_IS_OVER ? oC_AutoStackMethod_RerunThread : oC_AutoStackMethod_Disabled;
78 static oC_MemorySize_t StackIncreaseStep = CFG_BYTES_STACK_INCREASE_STEP;
79 static oC_Time_t LastSwitchTime = 0;
80  uint64_t oC_ThreadManTickCounter = 0;
81 static oC_Time_t ForceChangeThreadTimeout= 0;
82 static oC_List(oC_Thread_t) ThreadList = NULL;
83 static oC_MemorySize_t DefaultStackSize = CFG_BYTES_DEFAULT_THREAD_STACK_SIZE;
84 
85 static const oC_Allocator_t Allocator = {
86  .Name = "thread manager" ,
87  .EventHandler = MemoryEventHandler ,
88  .EventFlags = MemoryEventFlags_BufferOverflow |
89  MemoryEventFlags_DataSectionOverflow |
90  MemoryEventFlags_PossibleMemoryLeak |
91  MemoryEventFlags_ModuleTurningOff |
92  MemoryEventFlags_PanicMemoryExhausted
93 };
94 const oC_Module_Registration_t ThreadMan = {
95  .Name = "Thread Manager" ,
96  .Module = oC_Module_ThreadMan ,
97  .TurnOnFunction = oC_ThreadMan_TurnOn ,
98  .TurnOffFunction = oC_ThreadMan_TurnOff ,
99  .RequiredModules = { 0 }
100 };
101 
102 #undef _________________________________________VARIABLES_SECTION__________________________________________________________________________
103 
104 
110 #define _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
111 
112 //==========================================================================================================================================
113 //==========================================================================================================================================
114 oC_ErrorCode_t oC_ThreadMan_TurnOn( void )
115 {
116  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
117 
118  if(oC_Module_TurnOffVerification(&errorCode, oC_Module_ThreadMan))
119  {
120  errorCode = oC_SYS_LLD_TurnOnDriver();
121 
122  if(errorCode == oC_ErrorCode_ModuleIsTurnedOn || errorCode == oC_ErrorCode_None)
123  {
124  CurrentThread = NULL;
125  ThreadToRemove = NULL;
126  SystemFrequency = CFG_FREQUENCY_DEFAULT_SYSTEM_TIMER_FREQUENCY;
127  ThreadList = oC_List_New(&Allocator,AllocationFlags_NoWait);
128  LastSwitchTime = 0;
129  oC_ThreadManTickCounter = 0;
130  ForceChangeThreadTimeout= 0;
131 
132  if(ThreadList)
133  {
134  SavedThreadsListAddress = ThreadList;
135 
136  if(oC_AssignErrorCode(&errorCode , oC_SYS_LLD_ConfigureSystemTimer(SystemFrequency , SysTickHandler)))
137  {
138  oC_Module_TurnOn(oC_Module_ThreadMan);
139  errorCode = oC_ErrorCode_None;
140  }
141  }
142  else
143  {
144  errorCode = oC_ErrorCode_AllocationError;
145  }
146  }
147  }
148 
149  return errorCode;
150 }
151 
152 //==========================================================================================================================================
153 //==========================================================================================================================================
154 oC_ErrorCode_t oC_ThreadMan_TurnOff( void )
155 {
156  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
157 
158  if(oC_Module_TurnOnVerification(&errorCode, oC_Module_ThreadMan))
159  {
160  oC_Module_TurnOff(oC_Module_ThreadMan);
161  errorCode = oC_SYS_LLD_TurnOffDriver();
162 
163  oC_List_Delete(ThreadList,AllocationFlags_CanWaitForever);
164 
165  if(errorCode == oC_ErrorCode_ModuleNotStartedYet || errorCode == oC_ErrorCode_None)
166  {
167  errorCode = oC_ErrorCode_None;
168  }
169  }
170 
171  return errorCode;
172 }
173 
174 //==========================================================================================================================================
175 //==========================================================================================================================================
176 oC_ErrorCode_t oC_ThreadMan_SetSystemTimerFrequency( oC_Frequency_t Frequency )
177 {
178  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
179 
180  if(oC_Module_TurnOnVerification(&errorCode, oC_Module_ThreadMan))
181  {
182  errorCode = oC_SYS_LLD_ConfigureSystemTimer(Frequency,SysTickHandler);
183  }
184 
185  return errorCode;
186 }
187 
188 //==========================================================================================================================================
189 //==========================================================================================================================================
190 oC_Frequency_t oC_ThreadMan_GetSystemTimerFrequency( void )
191 {
192  return SystemFrequency;
193 }
194 
195 //==========================================================================================================================================
196 //==========================================================================================================================================
197 oC_ErrorCode_t oC_ThreadMan_AddThread( oC_Thread_t Thread )
198 {
199  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
200 
201  if(
202  oC_Module_TurnOnVerification(&errorCode, oC_Module_ThreadMan) &&
203  oC_AssignErrorCodeIfFalse(&errorCode , oC_Thread_IsCorrect(Thread) , oC_ErrorCode_ObjectNotCorrect )
204  )
205  {
206  bool added = false;
207 
208  oC_IntMan_EnterCriticalSection();
209  added = oC_List_PushBack(ThreadList,Thread,&Allocator);
210  oC_IntMan_ExitCriticalSection();
211 
212  if(added)
213  {
214  oC_ThreadMan_SwitchThread();
215  errorCode = oC_ErrorCode_None;
216  }
217  else
218  {
219  errorCode = oC_ErrorCode_CannotAddObjectToList;
220  }
221  }
222 
223  return errorCode;
224 }
225 
226 //==========================================================================================================================================
227 //==========================================================================================================================================
228 oC_ErrorCode_t oC_ThreadMan_RemoveThread( oC_Thread_t Thread )
229 {
230  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
231 
232  if(
233  oC_Module_TurnOnVerification(&errorCode, oC_Module_ThreadMan) &&
234  oC_AssignErrorCodeIfFalse(&errorCode , oC_Thread_IsCorrect(Thread) , oC_ErrorCode_ObjectNotCorrect )
235  )
236  {
237  oC_IntMan_EnterCriticalSection();
238  bool objectFound = oC_List_Contains(ThreadList,Thread);
239  oC_Thread_t takenThread = NULL;
240  oC_List_Take(ThreadList,Thread,takenThread);
241  oC_IntMan_ExitCriticalSection();
242 
243  if(takenThread == Thread)
244  {
245  oC_IntMan_EnterCriticalSection();
246  if(CurrentThread == Thread)
247  {
248  ThreadToRemove = Thread;
249  errorCode = oC_ErrorCode_None;
250  }
251  else
252  {
253  if(oC_Thread_Delete(&Thread))
254  {
255  oC_ThreadMan_SwitchThread();
256  errorCode = oC_ErrorCode_None;
257  }
258  else
259  {
260  errorCode = oC_ErrorCode_CannotDeleteObject;
261  }
262  }
263  oC_IntMan_ExitCriticalSection();
264  }
265  else if(objectFound == false)
266  {
267  errorCode = oC_ErrorCode_None;
268  }
269  else
270  {
271  errorCode = oC_ErrorCode_CannotRemoveObjectFromList;
272  }
273 
274  }
275 
276  return errorCode;
277 }
278 
279 //==========================================================================================================================================
280 //==========================================================================================================================================
281 bool oC_ThreadMan_ContainsThread( oC_Thread_t Thread )
282 {
283  bool contains = false;
284 
285  if(oC_SaveIfFalse( "Module is not enabled", oC_Module_IsTurnedOn(oC_Module_ThreadMan), oC_ErrorCode_ModuleNotStartedYet ))
286  {
287  contains = oC_List_Contains(ThreadList,Thread);
288  }
289 
290  return contains;
291 }
292 
293 //==========================================================================================================================================
294 //==========================================================================================================================================
295 oC_Thread_t oC_ThreadMan_GetCurrentThread( void )
296 {
297  return (oC_Module_IsTurnedOn(oC_Module_ThreadMan)) ? CurrentThread : NULL;
298 }
299 
300 //==========================================================================================================================================
301 //==========================================================================================================================================
302 void oC_ThreadMan_UnblockAllBlockedBy( uint32_t * BlockingFlag , bool OnlyIfUnblocked )
303 {
304  if(oC_Module_IsTurnedOn(oC_Module_ThreadMan))
305  {
306  oC_List_Foreach(ThreadList,thread)
307  {
308  if(oC_Thread_IsBlockedBy(thread,BlockingFlag))
309  {
310  oC_IntMan_EnterCriticalSection();
311  if(!OnlyIfUnblocked || !oC_Thread_IsBlocked(thread))
312  {
313  oC_Thread_SetUnblocked(thread);
314  }
315  oC_IntMan_ExitCriticalSection();
316  }
317  }
318 
319  oC_ThreadMan_SwitchThread();
320  }
321 }
322 
323 //==========================================================================================================================================
324 //==========================================================================================================================================
325 void oC_ThreadMan_SwitchThread( void )
326 {
327  static bool repairInProgress = false;
329  char tempString[100] = {0};
330  bool foundOverflow = false;
331 
332  if(oC_Module_IsTurnedOn(oC_Module_ThreadMan))
333  {
334  NextThread = NULL;
335 
336  oC_List_Foreach(ThreadList,thread)
337  {
338  if(oC_Thread_IsCorrect(thread) == false)
339  {
340  kdebuglog(oC_LogType_Error , "switch-thread: Thread [%p] '%s' is not correct!\n", thread , oC_Thread_GetName(thread));
341 
342  if(oC_List_Verify(ThreadList) == false )
343  {
344  foundOverflow = oC_MemMan_FindOverflowedAllocation(NULL,&allStat);
345 
346  if(foundOverflow)
347  {
348  sprintf(tempString, "Overflowed buffer: [%p] with size: %d Allocated at: %s:%d", allStat.Address, allStat.Size, allStat.Function,allStat.LineNumber);
349  }
350  else
351  {
352  sprintf(tempString, "(Damaged thread: %p - %s)", thread, oC_Thread_GetName(thread));
353  }
354 
355  if(repairInProgress == false)
356  {
357  repairInProgress = true;
358 
359  if(List_Repair((oC_List_t)ThreadList,SavedThreadsListAddress,CFG_UINT32_MAXIMUM_NUMBER_OF_THREADS))
360  {
361  oC_ThreadMan_SwitchThread();
362  repairInProgress = false;
363  oC_ExcHan_LogEvent("Restored stable state after fatal exception. Threads list was damaged. There is a possibility of memory leakage.", tempString, NULL, CurrentThread, oC_ExcHan_ExceptionType_KernelPanic);
364  break;
365  }
366  else
367  {
368  if(isram(oC_SYS_LLD_GetSystemContext()))
369  {
370  oC_ExcHan_LogEvent("Cannot restore stable state after fatal exception. Threads list is damaged.", tempString, NULL, CurrentThread, oC_ExcHan_ExceptionType_KernelPanic | oC_ExcHan_ExceptionType_RequiredReboot);
372  break;
373  }
374  else
375  {
376  oC_Boot_Restart( oC_Boot_Reason_SystemException, oC_UserMan_GetRootUser() );
377  }
378  }
379  }
380  else
381  {
382  if(isram(oC_SYS_LLD_GetSystemContext()))
383  {
384  oC_ExcHan_LogEvent("Cannot restore stable state after fatal exception. Threads list is damaged.", tempString, NULL, CurrentThread, oC_ExcHan_ExceptionType_KernelPanic | oC_ExcHan_ExceptionType_RequiredReboot);
386  break;
387  }
388  else
389  {
390  oC_Boot_Restart( oC_Boot_Reason_SystemException, oC_UserMan_GetRootUser() );
391  }
392  }
393  }
394  else
395  {
396  oC_List_RemoveCurrentElement(ThreadList,thread);
397  }
398  }
399  else if(oC_Thread_IsBlocked(thread) == false)
400  {
401  oC_Thread_Priority_t nextPriority = oC_Thread_GetPriority(NextThread);
402  oC_Thread_Priority_t priority = oC_Thread_GetPriority(thread);
403  if(
404  (NextThread == NULL) ||
405  (priority > nextPriority) ||
406  (priority == nextPriority && oC_Thread_GetLastExecutionTick(thread) < oC_Thread_GetLastExecutionTick(NextThread))
407  )
408  {
409  NextThread = thread;
410  }
411  }
412  }
413  }
414 }
415 
416 //==========================================================================================================================================
417 //==========================================================================================================================================
418 oC_List(oC_Thread_t) oC_ThreadMan_GetList( void )
419 {
420  return ThreadList;
421 }
422 
423 //==========================================================================================================================================
424 //==========================================================================================================================================
425 oC_Thread_t oC_ThreadMan_GetThread( const char * Name )
426 {
427  oC_Thread_t threadToReturn = NULL;
428 
429  if(oC_Module_IsTurnedOn(oC_Module_ThreadMan))
430  {
431  oC_List_Foreach(ThreadList,thread)
432  {
433  if(strcmp(oC_Thread_GetName(thread),Name) == 0)
434  {
435  threadToReturn = thread;
436  }
437  }
438  }
439 
440  return threadToReturn;
441 }
442 
443 //==========================================================================================================================================
444 //==========================================================================================================================================
445 oC_MemorySize_t oC_ThreadMan_GetDefaultStackSize( void )
446 {
447  return DefaultStackSize;
448 }
449 
450 //==========================================================================================================================================
451 //==========================================================================================================================================
452 oC_ErrorCode_t oC_ThreadMan_SetDefaultStackSize( oC_MemorySize_t Size )
453 {
454  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
455 
456  if(
457  oC_Module_TurnOnVerification(&errorCode, oC_Module_ThreadMan)
458  && ErrorCondition(Size > 0 , oC_ErrorCode_SizeNotCorrect )
459  )
460  {
461  DefaultStackSize = oC_MemMan_AlignSizeTo(Size,oC_MEM_LLD_STACK_ALIGNMENT);
462  errorCode = oC_ErrorCode_None;
463  }
464 
465  return errorCode;
466 }
467 
468 //==========================================================================================================================================
469 //==========================================================================================================================================
470 oC_ErrorCode_t oC_ThreadMan_SetAutoStackMethod( oC_AutoStackMethod_t Method )
471 {
472  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
473 
474  if(
475  oC_Module_TurnOnVerification(&errorCode, oC_Module_ThreadMan)
476  && ErrorCondition( Method >= 0 && Method <= oC_AutoStackMethod_RerunThread , oC_ErrorCode_AutoStackMethodNotCorrect )
477  )
478  {
479  AutoStackMethod = Method;
480  errorCode = oC_ErrorCode_None;
481  }
482 
483  return errorCode;
484 }
485 
486 //==========================================================================================================================================
487 //==========================================================================================================================================
488 oC_AutoStackMethod_t oC_ThreadMan_GetAutoStackMethod( void )
489 {
490  return AutoStackMethod;
491 }
492 
493 //==========================================================================================================================================
494 //==========================================================================================================================================
495 oC_ErrorCode_t oC_ThreadMan_SetRedZoneSize( oC_MemorySize_t Size )
496 {
497  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
498 
499  if(
500  oC_Module_TurnOnVerification(&errorCode, oC_Module_ThreadMan)
501  && ErrorCondition(Size > 0 , oC_ErrorCode_SizeNotCorrect )
502  )
503  {
504  RedZoneSize = oC_MemMan_AlignSize(Size);
505  errorCode = oC_ErrorCode_None;
506  }
507 
508  return errorCode;
509 }
510 
511 //==========================================================================================================================================
512 //==========================================================================================================================================
513 oC_MemorySize_t oC_ThreadMan_GetRedZoneSize( void )
514 {
515  return RedZoneSize;
516 }
517 
518 //==========================================================================================================================================
519 //==========================================================================================================================================
520 oC_ErrorCode_t oC_ThreadMan_SetStackIncreaseStep( oC_MemorySize_t Size )
521 {
522  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
523 
524  if(
525  oC_Module_TurnOnVerification(&errorCode, oC_Module_ThreadMan)
526  && ErrorCondition(Size > 0 , oC_ErrorCode_SizeNotCorrect )
527  )
528  {
529  StackIncreaseStep = oC_MemMan_AlignSizeTo(Size,oC_MEM_LLD_STACK_ALIGNMENT);
530  errorCode = oC_ErrorCode_None;
531  }
532 
533  return errorCode;
534 }
535 
536 //==========================================================================================================================================
537 //==========================================================================================================================================
538 oC_MemorySize_t oC_ThreadMan_GetStackIncreaseStep( void )
539 {
540  return StackIncreaseStep;
541 }
542 
543 //==========================================================================================================================================
544 //==========================================================================================================================================
545 double oC_ThreadMan_GetCpuLoad( void )
546 {
547  return CpuLoad;
548 }
549 
550 //==========================================================================================================================================
551 //==========================================================================================================================================
552 double oC_ThreadMan_GetCurrentCpuLoad( void )
553 {
554  return CurrentCpuLoad;
555 }
556 
557 //==========================================================================================================================================
558 //==========================================================================================================================================
559 oC_Thread_t oC_ThreadMan_GetThreadOfContext( void * Context )
560 {
561  oC_Thread_t foundThread = NULL;
562 
563  foreach(ThreadList, thread)
564  {
565  bool inRedZone = false;
566 
567  if(oC_Thread_IsOwnedByStack(thread,Context,&inRedZone) || inRedZone)
568  {
569  foundThread = thread;
570  }
571  }
572 
573  return foundThread;
574 }
575 
576 #undef _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
577 
583 #define _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
584 
585 //==========================================================================================================================================
589 //==========================================================================================================================================
590 static void SysTickReturnToIdle( void )
591 {
593  CurrentThread = NULL;
594 }
595 
596 //==========================================================================================================================================
597 //==========================================================================================================================================
598 static void CountCpuLoad( void )
599 {
600  oC_Timestamp_t currentTimestamp = oC_KTime_GetTimestamp();
601  oC_Time_t timeFromLastSwitch = currentTimestamp - LastSwitchTime;
602  CpuLoadMeasureTime += timeFromLastSwitch;
603 
605  {
606  InIdleTime += timeFromLastSwitch;
607  CurrentInIdleTime += timeFromLastSwitch;
608  }
609  CpuLoad = (100.0 - (InIdleTime / currentTimestamp) * 100);
610 
611  if(CpuLoadMeasureTime >= CpuLoadMeasureTimeout || (CurrentCpuLoad == 0 && CpuLoadMeasureTime > 0))
612  {
613  CurrentCpuLoad = (100.0 - (CurrentInIdleTime / CpuLoadMeasureTime) * 100);
614  CpuLoadMeasureTime = 0;
615  CurrentInIdleTime = 0;
616  }
617 
618  if(CurrentCpuLoad > CpuLoadPanicMargin)
619  {
620  if(CpuLoadPanicTimeout > 0)
621  {
622  if(CpuLoadPanicTimeout < currentTimestamp)
623  {
624  char string[60];
625 
626  sprintf_s(string,sizeof(string), "margin = %f, thread name = %s", CurrentCpuLoad, oC_Thread_GetName(CurrentThread));
627  oC_ExcHan_LogEvent("PANIC CPU LOAD limit exhausted", string, NULL, NULL, oC_ExcHan_ExceptionType_ProcessDamaged);
628  CpuLoadPanicTimeout = 0;
629  ForceChangeThreadTimeout = currentTimestamp;
630  oC_Thread_Delete(&CurrentThread);
631  }
632  }
633  else
634  {
635  CpuLoadPanicTimeout = currentTimestamp + CpuLoadPanicTimeLimit;
636  }
637  }
638  else
639  {
640  CpuLoadPanicTimeout = 0;
641  }
642 }
643 
644 //==========================================================================================================================================
645 //==========================================================================================================================================
646 static void SysTickHandler(void)
647 {
648  if(oC_Module_IsTurnedOn(oC_Module_ThreadMan))
649  {
650  oC_IntMan_EnterCriticalSection();
651  oC_Time_t currentTime = oC_KTime_GetTimestamp();
653  oC_SYS_LLD_Context_t * threadContext = oC_Thread_GetContext(CurrentThread);
654 
655  CountCpuLoad();
656 
657  if(CurrentThread)
658  {
659  if(currentContext != threadContext)
660  {
661  kdebuglog(oC_LogType_Error , "systick: current context is not current thread!");
662  kdebuglog(oC_LogType_Error , "systick: Searching new thread...");
664  oC_ThreadMan_SwitchThread();
665  }
666  }
667 
668  if(ThreadToRemove)
669  {
670  if(ThreadToRemove == CurrentThread)
671  {
672  CurrentThread = NULL;
673  }
674  oC_Thread_Delete(&ThreadToRemove);
675  ThreadToRemove = NULL;
676  }
677 
678  if(oC_Thread_IsBlocked(CurrentThread) || currentTime >= ForceChangeThreadTimeout)
679  {
680 
681  if(CurrentThread)
682  {
683  oC_Thread_AddToExecutionTime(CurrentThread, currentTime - LastSwitchTime);
684  oC_Thread_SetLastExecutionTick(CurrentThread,oC_ThreadManTickCounter);
685  }
686 
687  LastSwitchTime = currentTime;
688 
689  if(NextThread == NULL || oC_Thread_IsBlocked(NextThread))
690  {
691  oC_ThreadMan_SwitchThread();
692  }
693 
694  if(NextThread != CurrentThread)
695  {
696  if(NextThread == NULL && currentTime >= ForceChangeThreadTimeout && CurrentThread != NULL && oC_Thread_IsBlocked(CurrentThread) == false)
697  {
698  oC_ErrorCode_t errorCode = oC_SYS_LLD_SetNextContext(oC_Thread_GetContext(CurrentThread));
699 
700  if(errorCode != oC_ErrorCode_None)
701  {
702  oC_Int_t freeStackSize = oC_Thread_GetFreeStackSize(CurrentThread,true);
703  if(freeStackSize <= 0)
704  {
705  kdebuglog(oC_LogType_Error,"systick: Stack of the thread %s is too small! Closing..." , oC_Thread_GetName(CurrentThread));
706  kdebuglog(oC_LogType_Error,"%s: lack of %d stack bytes..." , oC_Thread_GetName(CurrentThread) , freeStackSize);
707 
708  char string[60];
709 
710  sprintf(string,"Stack of the thread %s is too small! Lack of %d bytes", oC_Thread_GetName(CurrentThread), freeStackSize);
711 
712  oC_ExcHan_LogEvent("Stack of the thread is too small!\n", string, NULL, CurrentThread, oC_ExcHan_ExceptionType_ProcessDamaged);
713  }
714  oC_SaveError("ThreadMan : SysTickHandler - cannot set next context (after timeout): " , errorCode );
715  oC_ThreadMan_RemoveThread(CurrentThread);
717  }
718  }
719  else if(NextThread != NULL)
720  {
721  ForceChangeThreadTimeout = oC_Frequency_ToTime(CFG_FREQUENCY_DEFAULT_FORCE_CHANGE_THREAD) + currentTime;
722 
723  oC_ErrorCode_t errorCode = oC_SYS_LLD_SetNextContext(oC_Thread_GetContext(NextThread));
724 
725  if(errorCode == oC_ErrorCode_None)
726  {
727  CurrentThread = NextThread;
728  NextThread = NULL;
729  }
730  else
731  {
732  oC_Int_t freeStackSize = oC_Thread_GetFreeStackSize(NextThread,true);
733  oC_Thread_t oldThread = NextThread;
734 
735  if(freeStackSize <= 0)
736  {
737  kdebuglog(oC_LogType_Error,"systick: Stack of the thread %s is too small! Closing..." , oC_Thread_GetName(oldThread));
738  kdebuglog(oC_LogType_Error,"%s: lack of %d stack bytes..." , oC_Thread_GetName(oldThread) , freeStackSize);
739  char string[60];
740 
741  sprintf(string,"Stack of the thread `%s` is too small! Lack of %d bytes", oC_Thread_GetName(oldThread), freeStackSize);
742 
743  oC_ExcHan_LogEvent("Stack of the thread is too small!\n", string, NULL, oldThread, oC_ExcHan_ExceptionType_ProcessDamaged);
744 
745  if(AutoStackMethod == oC_AutoStackMethod_RerunThread)
746  {
747  oC_MemorySize_t newStackSize = oC_Thread_GetStackSize(oldThread) + StackIncreaseStep;
748  oC_Thread_t newThread = oC_Thread_CloneWithNewStack(oldThread,newStackSize);
749 
750  kdebuglog(oC_LogType_Error , "%s-rerun: new stack size: %uB" , oC_Thread_GetName(oldThread) , newStackSize);
751 
752  errorCode = oC_ThreadMan_AddThread(newThread);
753 
754  if(oC_ErrorOccur(errorCode))
755  {
756  kdebuglog(oC_LogType_Error , "systick: cannot rerun thread '%s'" , oC_Thread_GetName(oldThread));
757  kdebuglog(oC_LogType_Error , "systick: rerun error: %s" , oC_GetErrorString(errorCode));
758  }
759  }
760  }
761  oC_SaveError("ThreadMan : SysTickHandler - cannot set next context: " , errorCode );
762  oC_ThreadMan_RemoveThread(oldThread);
764  }
765  }
766  else
767  {
769  }
770  }
771  else if(CurrentThread == NULL)
772  {
774  }
775  }
776  oC_IntMan_ExitCriticalSection();
777  }
778 
779  oC_ThreadManTickCounter++;
780 }
781 
782 //==========================================================================================================================================
783 //==========================================================================================================================================
784 static void MemoryEventHandler( void * Address , MemoryEventFlags_t Event , const char * Function, uint32_t LineNumber )
785 {
786  char string[100];
787 
788  sprintf(string,"Event flags: 0x%X, Address = %p, %s:%d", Event, Address, Function, LineNumber);
789 
790  oC_ExcHan_LogEvent("Memory event in thread manager\n",string, NULL, NULL, oC_ExcHan_ExceptionType_MemoryAccess);
791 }
792 
793 #undef _________________________________________LOCAL_FUNCTIONS_SECTION____________________________________________________________________
Definition: oc_list.h:63
oC_SYS_LLD_Context_t * oC_SYS_LLD_GetSystemContext(void)
returns pointer to the system context
Definition: oc_sys_lld.c:408
FILE__DESCRIPTION
const char * Name
Definition: oc_stdlib.h:161
double oC_Frequency_t
type to store frequency
Definition: oc_frequency.h:76
identifier for allocations
Definition: oc_stdlib.h:159
oC_UInt_t oC_MemMan_AlignSizeTo(oC_UInt_t Size, oC_UInt_t Alignment)
returns size aligned to the given alignment
Definition: oc_memman.c:1239
oC_SYS_LLD_Context_t * oC_SYS_LLD_GetCurrentContext(void)
returns pointer to the current context
Definition: oc_sys_lld.c:397
The file with interface for process manager.
File with interface for user system manager.
oC_ErrorCode_t oC_SYS_LLD_TurnOnDriver(void)
initializes the driver to work
Definition: oc_sys_lld.c:103
oC_ErrorCode_t oC_SYS_LLD_ReturnToSystemContext(void)
switches to the system context
Definition: oc_sys_lld.c:386
oC_ErrorCode_t oC_SYS_LLD_ConfigureSystemTimer(oC_Frequency_t Frequency, oC_SYS_LLD_SysTickIncrementHandler_t Interrupt)
configures system timer
Definition: oc_sys_lld.c:261
void oC_SYS_LLD_Context_t
type for storing context of the machine
Definition: oc_sys_lld.h:143
oC_ErrorCode_t oC_SYS_LLD_TurnOffDriver(void)
release the driver
Definition: oc_sys_lld.c:138
The file with interface for the module library.
static bool oC_Module_IsTurnedOn(oC_Module_t Module)
checks if the module is turned on
Definition: oc_module.h:121
void oC_Boot_Restart(oC_Boot_Reason_t Reason, oC_User_t User)
restarts the system
Definition: oc_boot.c:145
bool oC_MemMan_FindOverflowedAllocation(Allocator_t Allocator, oC_MemMan_AllocationStats_t *outAllocationStat)
searches for a overflowed buffer
Definition: oc_memman.c:1743
void oC_ExcHan_LogEvent(const char *Name, char *AdditionalInfo, void *Stack, oC_Thread_t Thread, oC_ExcHan_ExceptionType_t Type)
logs system event
Definition: oc_exchan.c:347
The file with interface for interrupt manager.
oC_ErrorCode_t oC_SYS_LLD_SetNextContext(oC_SYS_LLD_Context_t *Context)
configures next machine context
Definition: oc_sys_lld.c:321
static void MemoryEventHandler(void *Address, MemoryEventFlags_t Event, const char *Function, uint32_t LineNumber)
handler for memory manager events
Definition: oc_exchan.c:441
oC_UInt_t oC_MemMan_AlignSize(oC_UInt_t Size)
returns size aligned to the machine alignment
Definition: oc_memman.c:1222
static void oC_Module_TurnOn(oC_Module_t Module)
sets module as turned on
Definition: oc_module.h:170
File with interface of Exception Handler.
static void SysTickReturnToIdle(void)
Definition: oc_threadman.c:590
static bool oC_Module_TurnOffVerification(oC_ErrorCode_t *outErrorCode, oC_Module_t Module)
verify if module is turned off
Definition: oc_module.h:155
static const oC_Allocator_t Allocator
Definition: oc_eth.c:152
static bool oC_Module_TurnOnVerification(oC_ErrorCode_t *outErrorCode, oC_Module_t Module)
verify if module is turned on
Definition: oc_module.h:138
const char * oC_GetErrorString(oC_ErrorCode_t ErrorCode)
Definition: oc_errors.c:115
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
Definition: oc_thread.c:272
The file with interface for Thread Manager.
#define oC_MEM_LLD_STACK_ALIGNMENT
number of bytes in alignment of the stack
Definition: oc_mem_lld.h:105
The file with interface of kernel time module.
#define NULL
pointer to a zero
Definition: oc_null.h:37
static void oC_Module_TurnOff(oC_Module_t Module)
sets module as turned off
Definition: oc_module.h:185