Choco OS  V.0.16.9.0
Join to the chocolate world
oc_processman.c
Go to the documentation of this file.
1 
27 #include <oc_processman.h>
28 #include <oc_threadman.h>
29 #include <string.h>
30 #include <oc_system_cfg.h>
31 #include <oc_userman.h>
32 #include <oc_debug.h>
33 #include <oc_intman.h>
34 #include <oc_module.h>
35 
41 #define _________________________________________VARIABLES_SECTION_________________________________________________________________________
42 
43 static oC_UInt_t NextPid = 0;
44 static oC_UInt_t SomeProcessToDelete= false;
45 static oC_Thread_t DeleteDeamonThread = NULL;
46 static oC_Process_t DeleteDeamonProcess= NULL;
47 static oC_List(oC_Process_t) Processes = NULL;
48 static const oC_Allocator_t Allocator = {
49  .Name = "Process Manager" ,
50  .EventFlags = 0 ,
51  .EventHandler = NULL
52 };
53 const oC_Module_Registration_t ProcessMan = {
54  .Name = "Process Manager" ,
55  .Module = oC_Module_ProcessMan ,
56  .TurnOnFunction = oC_ProcessMan_TurnOn ,
57  .TurnOffFunction = oC_ProcessMan_TurnOff ,
58  .RequiredModules = { oC_Module_ThreadMan }
59 };
60 
61 #undef _________________________________________VARIABLES_SECTION_________________________________________________________________________
62 
68 #define _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
69 
70 //==========================================================================================================================================
71 //==========================================================================================================================================
72 oC_ErrorCode_t oC_ProcessMan_TurnOn( void )
73 {
74  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
75 
76  if(oC_Module_TurnOffVerification(&errorCode, oC_Module_ProcessMan))
77  {
78  Processes = oC_List_New(&Allocator,AllocationFlags_NoWait);
79 
80  if(Processes)
81  {
82  SomeProcessToDelete = false;
83  DeleteDeamonThread = NULL;
84  DeleteDeamonProcess = NULL;
85  NextPid = 0;
86  errorCode = oC_ErrorCode_None;
87  oC_Module_TurnOn(oC_Module_ProcessMan);
88  }
89  else
90  {
91  errorCode = oC_ErrorCode_AllocationError;
92  }
93  }
94 
95  return errorCode;
96 }
97 
98 //==========================================================================================================================================
99 //==========================================================================================================================================
100 oC_ErrorCode_t oC_ProcessMan_TurnOff( void )
101 {
102  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
103 
104  if(oC_Module_TurnOnVerification(&errorCode, oC_Module_ProcessMan))
105  {
106  oC_Module_TurnOff(oC_Module_ProcessMan);
107  errorCode = oC_ErrorCode_None;
108 
109  oC_List_Foreach(Processes,process)
110  {
111  if(oC_Process_Delete(&process) == false)
112  {
113  errorCode = oC_ErrorCode_CannotDeleteProcess;
114  }
115  }
116  if(oC_List_Delete(Processes,AllocationFlags_CanWaitForever) == false)
117  {
118  errorCode = oC_ErrorCode_ReleaseError;
119  }
120  }
121 
122  return errorCode;
123 }
124 //==========================================================================================================================================
125 //==========================================================================================================================================
126 oC_ErrorCode_t oC_ProcessMan_AddProcess( oC_Process_t Process )
127 {
128  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
129 
130  if(
131  oC_Module_TurnOnVerification(&errorCode, oC_Module_ProcessMan)
132  && oC_AssignErrorCodeIfFalse(&errorCode , oC_Process_IsCorrect(Process) , oC_ErrorCode_ObjectNotCorrect)
133  )
134  {
135  bool added = oC_List_PushBack(Processes,Process,&Allocator);
136 
137  if(added)
138  {
139  errorCode = oC_ErrorCode_None;
140  }
141  else
142  {
143  errorCode = oC_ErrorCode_CannotAddObjectToList;
144  }
145  }
146 
147  return errorCode;
148 }
149 
150 //==========================================================================================================================================
151 //==========================================================================================================================================
152 oC_ErrorCode_t oC_ProcessMan_RemoveProcess( oC_Process_t Process )
153 {
154  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
155 
156  if(
157  oC_Module_TurnOnVerification(&errorCode, oC_Module_ProcessMan)
158  && oC_AssignErrorCodeIfFalse(&errorCode , oC_Process_IsCorrect(Process) , oC_ErrorCode_ObjectNotCorrect)
159  )
160  {
161  bool contains = oC_List_Contains(Processes,Process);
162 
163  if(contains)
164  {
165  bool removed = oC_List_RemoveAll(Processes,Process);
166 
167  if(removed)
168  {
169  errorCode = oC_ErrorCode_None;
170  }
171  else
172  {
173  errorCode = oC_ErrorCode_CannotRemoveObjectFromList;
174  }
175  }
176  else
177  {
178  errorCode = oC_ErrorCode_ObjectNotFoundOnList;
179  }
180  }
181 
182  return errorCode;
183 }
184 
185 
186 //==========================================================================================================================================
187 //==========================================================================================================================================
188 bool oC_ProcessMan_ContainsProcess( oC_Process_t Process )
189 {
190  bool contains = false;
191 
192  if(
193  oC_SaveIfFalse("ProcessMan", oC_Module_IsTurnedOn(oC_Module_ProcessMan) , oC_ErrorCode_ModuleNotStartedYet )
194  && oC_SaveIfFalse("Process" , oC_Process_IsCorrect(Process) , oC_ErrorCode_ObjectNotCorrect )
195  )
196  {
197  contains = oC_List_Contains(Processes,Process);
198  }
199 
200  return contains;
201 }
202 
203 //==========================================================================================================================================
204 //==========================================================================================================================================
205 oC_ErrorCode_t oC_ProcessMan_GetList( oC_List(oC_Process_t) List )
206 {
207  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
208 
209  if(
210  oC_Module_TurnOnVerification(&errorCode, oC_Module_ProcessMan)
211  )
212  {
213  errorCode = oC_ErrorCode_None;
214 
215  oC_List_Clear(List);
216 
217  oC_List_Foreach(Processes,process)
218  {
219  bool added = oC_List_PushBack(List,process,&Allocator);
220 
221  if(added == false)
222  {
223  errorCode = oC_ErrorCode_CannotAddObjectToList;
224  }
225  }
226  }
227 
228  return errorCode;
229 }
230 //==========================================================================================================================================
231 //==========================================================================================================================================
232 oC_ErrorCode_t oC_ProcessMan_GetUserProcesses( oC_User_t User , oC_List(oC_Process_t) List )
233 {
234  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
235 
236  if(
237  oC_Module_TurnOnVerification(&errorCode, oC_Module_ProcessMan) &&
238  oC_AssignErrorCodeIfFalse(&errorCode , oC_List_IsCorrect(List) , oC_ErrorCode_ListNotCorrect)
239  )
240  {
241  errorCode = oC_ErrorCode_None;
242 
243  oC_List_Clear(List);
244 
245  oC_List_Foreach(Processes,process)
246  {
247  if(oC_Process_GetUser(process) == User)
248  {
249  bool added = oC_List_PushBack(List,process,&Allocator);
250 
251  if(added == false)
252  {
253  errorCode = oC_ErrorCode_CannotAddObjectToList;
254  }
255  }
256  }
257  }
258 
259  return errorCode;
260 }
261 //==========================================================================================================================================
262 //==========================================================================================================================================
263 oC_Process_t oC_ProcessMan_GetCurrentProcess( void )
264 {
265  oC_Process_t currentProcess = NULL;
266 
267  if(oC_Module_IsTurnedOn(oC_Module_ProcessMan))
268  {
269  oC_Thread_t currentThread = oC_ThreadMan_GetCurrentThread();
270 
271  oC_List_Foreach(Processes,process)
272  {
273  if(oC_Process_ContainsThread(process,currentThread))
274  {
275  currentProcess = process;
276  break;
277  }
278  }
279  }
280 
281  return currentProcess;
282 }
283 
284 //==========================================================================================================================================
285 //==========================================================================================================================================
286 oC_Process_t oC_ProcessMan_GetProcess( const char * Name )
287 {
288  oC_Process_t processToReturn = NULL;
289 
290  if(oC_Module_IsTurnedOn(oC_Module_ProcessMan))
291  {
292  oC_List_Foreach(Processes,process)
293  {
294  if(strcmp(oC_Process_GetName(process),Name) == 0)
295  {
296  processToReturn = process;
297  break;
298  }
299  }
300  }
301 
302  return processToReturn;
303 }
304 
305 //==========================================================================================================================================
306 //==========================================================================================================================================
307 oC_Process_t oC_ProcessMan_GetProcessById( oC_UInt_t PID )
308 {
309  oC_Process_t processToReturn = NULL;
310 
311  if(oC_Module_IsTurnedOn(oC_Module_ProcessMan))
312  {
313  oC_List_Foreach(Processes,process)
314  {
315  if(oC_Process_GetPid(process) == PID)
316  {
317  processToReturn = process;
318  break;
319  }
320  }
321  }
322 
323  return processToReturn;
324 }
325 
326 //==========================================================================================================================================
327 //==========================================================================================================================================
328 Allocator_t oC_ProcessMan_GetCurrentAllocator( void )
329 {
330  Allocator_t allocator = NULL;
331 
332  if(oC_Module_IsTurnedOn(oC_Module_ProcessMan))
333  {
334  oC_IntMan_EnterCriticalSection();
335  oC_Process_t currentProcess = oC_ProcessMan_GetCurrentProcess();
336  oC_IntMan_ExitCriticalSection();
337 
338  if(currentProcess)
339  {
340  oC_IntMan_EnterCriticalSection();
341  allocator = oC_Process_GetAllocator(currentProcess);
342  oC_IntMan_ExitCriticalSection();
343  }
344  }
345 
346  return allocator;
347 }
348 
349 //==========================================================================================================================================
350 //==========================================================================================================================================
351 oC_Process_t oC_ProcessMan_GetProcessOfThread( oC_Thread_t Thread )
352 {
353  oC_Process_t process = NULL;
354 
355  if(oC_Thread_IsCorrect(Thread))
356  {
357  oC_List_Foreach(Processes,proc)
358  {
359  if(oC_Process_ContainsThread(proc,Thread))
360  {
361  process = proc;
362  break;
363  }
364  }
365  }
366  else
367  {
368  oC_SaveError("Process manager" , oC_ErrorCode_ObjectNotCorrect);
369  }
370 
371  return process;
372 }
373 
374 //==========================================================================================================================================
375 //==========================================================================================================================================
376 void * oC_ProcessMan_RawAllocate( oC_UInt_t Size , const char * Function, uint32_t LineNumber , AllocationFlags_t Flags )
377 {
378  void * address = NULL;
379 
380  if(oC_Module_IsTurnedOn(oC_Module_ProcessMan))
381  {
382  oC_Process_t currentProcess = oC_ProcessMan_GetCurrentProcess();
383 
384  if(currentProcess)
385  {
386  oC_HeapMap_t heapMap = oC_Process_GetHeapMap(currentProcess);
387 
388  if(heapMap)
389  {
390  address = oC_MemMan_RawAllocate(heapMap,Size,Function,LineNumber,Flags);
391  }
392  }
393  }
394 
395  return address;
396 }
397 
398 //==========================================================================================================================================
399 //==========================================================================================================================================
400 bool oC_ProcessMan_RawFree( void * Address , oC_UInt_t Size )
401 {
402  bool released = false;
403 
404  if(oC_Module_IsTurnedOn(oC_Module_ProcessMan))
405  {
406  oC_Process_t currentProcess = oC_ProcessMan_GetCurrentProcess();
407 
408  if(currentProcess)
409  {
410  oC_HeapMap_t heapMap = oC_Process_GetHeapMap(currentProcess);
411 
412  if(heapMap)
413  {
414  released = oC_MemMan_RawFree(heapMap,Address,Size);
415  }
416  }
417  }
418 
419  return released;
420 }
421 //==========================================================================================================================================
422 //==========================================================================================================================================
423 void * oC_ProcessMan_Allocate( oC_UInt_t Size , const char * Function, uint32_t LineNumber , AllocationFlags_t Flags )
424 {
425  void * address = NULL;
426 
427  if(oC_Module_IsTurnedOn(oC_Module_ProcessMan))
428  {
429  Allocator_t allocator = oC_ProcessMan_GetCurrentAllocator();
430 
431  if(allocator)
432  {
433  address = oC_MemMan_Allocate(Size,allocator,Function,LineNumber,Flags,0);
434  }
435  }
436 
437  return address;
438 }
439 //==========================================================================================================================================
440 //==========================================================================================================================================
441 bool oC_ProcessMan_Free( void * Address , AllocationFlags_t Flags )
442 {
443  bool released = false;
444 
445  if(oC_Module_IsTurnedOn(oC_Module_ProcessMan))
446  {
447  released = oC_MemMan_Free(Address,Flags);
448  }
449 
450  return released;
451 }
452 
453 //==========================================================================================================================================
454 //==========================================================================================================================================
455 void * oC_ProcessMan_SmartAllocate( oC_UInt_t Size, const char * Function, uint32_t LineNumber , AllocationFlags_t Flags )
456 {
457  void * address = NULL;
458 
459  if(oC_Module_IsTurnedOn(oC_Module_ProcessMan))
460  {
461  oC_UInt_t realRawAllocationSize = Size + (Size/8) + ((Size%8) > 0) ? 1 : 0;
462  oC_UInt_t realAllocationSize = Size + oC_MemMan_GetAllocationBlockSize();
463 
464  if(realAllocationSize >= realRawAllocationSize)
465  {
466  address = oC_ProcessMan_RawAllocate(Size,Function,LineNumber,Flags);
467  }
468  if(address == NULL)
469  {
470  address = oC_ProcessMan_Allocate(Size,Function,LineNumber,Flags);
471  }
472  }
473 
474  return address;
475 }
476 
477 //==========================================================================================================================================
478 //==========================================================================================================================================
479 bool oC_ProcessMan_SmartFree( void * Address , oC_UInt_t Size , AllocationFlags_t Flags )
480 {
481  bool released = false;
482 
483  if(oC_Module_IsTurnedOn(oC_Module_ProcessMan))
484  {
485  released = oC_ProcessMan_RawFree(Address,Size);
486 
487  if(!released)
488  {
489  released = oC_ProcessMan_Free(Address,Flags);
490  }
491  }
492 
493  return released;
494 }
495 
496 //==========================================================================================================================================
497 //==========================================================================================================================================
498 void * oC_ProcessMan_KernelSmartAllocate( oC_UInt_t Size , Allocator_t Allocator , const char * Function, uint32_t LineNumber , AllocationFlags_t Flags )
499 {
500  void * address = oC_ProcessMan_SmartAllocate(Size,Function,LineNumber,Flags);
501 
502  if(address == NULL)
503  {
504  address = _kmalloc(Size,Allocator,Function,LineNumber,Flags,0);
505  }
506 
507  return address;
508 }
509 
510 //==========================================================================================================================================
511 //==========================================================================================================================================
512 bool oC_ProcessMan_KernelSmartFree( void * Address , oC_UInt_t Size , AllocationFlags_t Flags )
513 {
514  bool released = oC_ProcessMan_SmartFree(Address,Size,Flags);
515 
516  if(released == false)
517  {
518  released = kfree(Address,Flags);
519  }
520 
521  return released;
522 }
523 
524 //==========================================================================================================================================
525 //==========================================================================================================================================
526 void oC_ProcessMan_DeleteDeamon( void * Parameter )
527 {
528  oC_Thread_t currentThread = oC_ThreadMan_GetCurrentThread();
530  while(1)
531  {
532  oC_IntMan_EnterCriticalSection();
533  SomeProcessToDelete = false;
534  if(oC_Thread_SetBlocked(currentThread,&SomeProcessToDelete,oC_Thread_Unblock_WhenEqual,true,oC_Thread_UnblockMask_All,oC_hour(1))==false)
535  {
536  kdebuglog(oC_LogType_Error , "DeleteDeamon: cannot block current thread\n");
537  }
538  oC_IntMan_ExitCriticalSection();
539 
540  while(oC_Thread_IsBlocked(currentThread));
541 
542  oC_Thread_SetUnblocked(currentThread);
543 
544  oC_List_Foreach(Processes,process)
545  {
546  if(oC_Process_IsKilled(process))
547  {
548  oC_Process_t copy = process;
549  oC_ErrorCode_t errorCode = oC_ProcessMan_RemoveProcess(process);
550 
551  if(oC_ErrorOccur(errorCode))
552  {
553  oC_SaveError("DeleteDeamon: Cannot delete process from the list: " , errorCode );
554  }
555 
556  if(oC_Process_Delete(&process)==false)
557  {
558  oC_SaveError(oC_Process_GetName(copy),oC_ErrorCode_CannotDeleteProcess);
559  }
560  }
561  }
562  }
563 }
564 
565 //==========================================================================================================================================
566 //==========================================================================================================================================
567 oC_ErrorCode_t oC_ProcessMan_RunDeleteDaemon( void )
568 {
569  oC_ErrorCode_t errorCode = oC_ErrorCode_ImplementError;
570 
571  if(
572  oC_Module_TurnOnVerification(&errorCode, oC_Module_ProcessMan) &&
573  oC_AssignErrorCodeIfFalse(&errorCode , oC_Thread_IsCorrect(DeleteDeamonThread) == false , oC_ErrorCode_DaemonThreadAlreadyExists ) &&
574  oC_AssignErrorCodeIfFalse(&errorCode , oC_Process_IsCorrect(DeleteDeamonProcess)== false , oC_ErrorCode_DaemonProcessAlreadyExists)
575  )
576  {
577  DeleteDeamonProcess = oC_Process_New(oC_Process_Priority_SystemHandlerDeamon,"delete daemon",oC_UserMan_GetRootUser(),0,NULL,NULL,NULL);
578 
579  if(oC_Process_IsCorrect(DeleteDeamonProcess))
580  {
581  DeleteDeamonThread = oC_Thread_New(oC_Process_Priority_SystemHandlerDeamon,CFG_BYTES_DELETE_DEAMON_STACK_SIZE,DeleteDeamonProcess,"delete daemon",oC_ProcessMan_DeleteDeamon,NULL);
582 
583  if(oC_Thread_IsCorrect(DeleteDeamonThread))
584  {
585  if(oC_Thread_Run(DeleteDeamonThread))
586  {
587  errorCode = oC_ProcessMan_AddProcess(DeleteDeamonProcess);
588  }
589  else
590  {
591  if(oC_Process_Delete(&DeleteDeamonProcess)==false)
592  {
593  oC_SaveError("Cannot delete daemon process: ",oC_ErrorCode_ReleaseError);
594  }
595 
596  if(oC_Thread_Delete(&DeleteDeamonThread)==false)
597  {
598  oC_SaveError("Cannot delete daemon thread: ",oC_ErrorCode_ReleaseError);
599  }
600 
601  errorCode = oC_ErrorCode_CannotRunThread;
602  }
603  }
604  else
605  {
606  if(oC_Process_Delete(&DeleteDeamonProcess)==false)
607  {
608  oC_SaveError("Cannot delete daemon process: ",oC_ErrorCode_ReleaseError);
609  }
610  errorCode = oC_ErrorCode_CannotCreateThread;
611  }
612  }
613  else
614  {
615  errorCode = oC_ErrorCode_CannotCreateProcess;
616  }
617  }
618 
619 
620  return errorCode;
621 }
622 
623 //==========================================================================================================================================
624 //==========================================================================================================================================
625 void oC_ProcessMan_ActivateDeleteDeamon( void )
626 {
627  if(oC_Module_IsTurnedOn(oC_Module_ProcessMan) && oC_Process_IsCorrect(DeleteDeamonProcess))
628  {
629  SomeProcessToDelete = true;
630  }
631 }
632 
633 //==========================================================================================================================================
634 //==========================================================================================================================================
635 oC_UInt_t oC_ProcessMan_GetNextPid( void )
636 {
637  oC_UInt_t pid = 0;
638 
639  if(oC_Module_IsTurnedOn(oC_Module_ProcessMan))
640  {
641  do
642  {
643  pid = ++NextPid;
644 
645  oC_List_Foreach(Processes,process)
646  {
647  if(oC_Process_GetPid(process)==pid)
648  {
649  pid = 0;
650  break;
651  }
652  }
653  } while(pid == 0);
654  }
655 
656  return pid;
657 }
658 
659 //==========================================================================================================================================
660 //==========================================================================================================================================
661 void oC_ProcessMan_KillAllZombies( void )
662 {
663  oC_List_Foreach(Processes,process)
664  {
665  if(oC_Process_GetState(process) == oC_Process_State_Zombie)
666  {
667  oC_Process_Kill(process);
668  }
669  }
670 }
671 
672 
673 #undef _________________________________________INTERFACE_FUNCTIONS_SECTION________________________________________________________________
674 
675 
676 
bool oC_MEM_LLD_SetMemoryAccessMode(oC_MEM_LLD_MemoryAccessMode_t Mode)
Change current memory access mode.
Definition: oc_mem_lld.c:654
FILE__DESCRIPTION
const char * Name
Definition: oc_stdlib.h:161
identifier for allocations
Definition: oc_stdlib.h:159
void * oC_MemMan_RawAllocate(oC_HeapMap_t Map, oC_UInt_t Size, const char *Function, uint32_t LineNumber, AllocationFlags_t Flags)
allow to allocate memory in heap map
Definition: oc_memman.c:643
The file with interface for process manager.
bool oC_MemMan_RawFree(oC_HeapMap_t Map, void *Address, oC_UInt_t Size)
release memory in heap map
Definition: oc_memman.c:692
File with interface for user system manager.
Definition: oc_user.c:43
void * oC_MemMan_Allocate(oC_UInt_t Size, Allocator_t Allocator, const char *Function, uint32_t LineNumber, AllocationFlags_t Flags, oC_UInt_t Alignment)
allocates memory on heap
Definition: oc_memman.c:770
oC_UInt_t oC_MemMan_GetAllocationBlockSize(void)
returns size of block needed for allocation
Definition: oc_memman.c:1466
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
Memory controller is configured to allow for memory access for regions that can be accessible by a pr...
Definition: oc_mem_lld.h:137
The file with interface for interrupt manager.
bool oC_MemMan_Free(void *Address, AllocationFlags_t Flags)
release allocated memory
Definition: oc_memman.c:908
static void oC_Module_TurnOn(oC_Module_t Module)
sets module as turned on
Definition: oc_module.h:170
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
The file with interface for Thread Manager.
#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