40 { |
41 { |
41 _LIT(KCategory,"SYMC-Exec"); |
42 _LIT(KCategory,"SYMC-Exec"); |
42 User::Panic(KCategory,aReason); |
43 User::Panic(KCategory,aReason); |
43 } |
44 } |
44 |
45 |
|
46 |
|
47 const TInt KTrapStackSize=256; |
|
48 |
|
49 /* |
|
50 TODO: should we use CObject? |
|
51 */ |
|
52 class TThread |
|
53 { |
|
54 public: |
|
55 |
|
56 public: |
|
57 RSemaphore iRequestSemaphore; |
|
58 CActiveScheduler* iActiveScheduler; //Current active scheduler for this thread. Used. |
|
59 TTrapHandler* iHandler; //This is our cleanup stack. Used. |
|
60 //No idea why we need that trap stack |
|
61 //TTrap* iTrapStack[KTrapStackSize]; |
|
62 //TInt iTrapCount; |
|
63 }; |
|
64 |
|
65 /* |
|
66 TODO: should we use CObject? |
|
67 Object used to store process globals for our pseudo kernel. |
|
68 That's typically going to be a singleton. |
|
69 */ |
|
70 class TProcess |
|
71 { |
|
72 public: |
|
73 void CreateHeap(); |
|
74 void Free(); |
|
75 |
|
76 public: |
|
77 RHeap* iAllocator; |
|
78 TAny* iBase; |
|
79 TThread iThread; //Single thread for now |
|
80 }; |
|
81 |
|
82 |
|
83 void TProcess::CreateHeap() |
|
84 { |
|
85 //iThread.iTrapCount=0; |
|
86 //Define the size of our heap |
|
87 const TInt KHeapMaxSize=1024*1024*10; // 10 Mo for now |
|
88 __ASSERT_ALWAYS(iAllocator==NULL && iBase==NULL,Panic(ESymcExecPanicHeapAlreadyExists)); |
|
89 iBase=malloc(KHeapMaxSize); |
|
90 __ASSERT_ALWAYS(iBase!=NULL,Panic(ESymcExecPanicCreateHeapFailed)); |
|
91 //TODO: is there anyway we could use variable size heap? |
|
92 iAllocator=UserHeap::FixedHeap(iBase,KHeapMaxSize); |
|
93 __ASSERT_ALWAYS(iAllocator!=NULL,Panic(ESymcExecPanicCreateHeapFailed)); |
|
94 } |
|
95 |
|
96 void TProcess::Free() |
|
97 { |
|
98 free(iBase); |
|
99 } |
|
100 |
|
101 |
|
102 |
|
103 TProcess gProcess; |
45 |
104 |
46 |
105 |
47 |
106 |
48 // |
107 // |
49 |
108 |
61 #pragma bss_seg() |
120 #pragma bss_seg() |
62 #endif |
121 #endif |
63 |
122 |
64 TInt __fastcall LazyDispatch(TInt aFunction, TInt* aArgs) |
123 TInt __fastcall LazyDispatch(TInt aFunction, TInt* aArgs) |
65 { |
124 { |
66 //SL: |
125 Panic(ESymcExecPanicNotSupported); |
|
126 // |
67 HINSTANCE kernel = GetModuleHandleA("ekern.dll"); |
127 HINSTANCE kernel = GetModuleHandleA("ekern.dll"); |
68 //HINSTANCE kernel = GetModuleHandleA("ekern.exe"); |
128 //HINSTANCE kernel = GetModuleHandleA("ekern.exe"); |
69 if (kernel) |
129 if (kernel) |
70 { |
130 { |
71 TDispatcher dispatcher = (TDispatcher)Emulator::GetProcAddress(kernel, (LPCSTR)1); |
131 TDispatcher dispatcher = (TDispatcher)Emulator::GetProcAddress(kernel, (LPCSTR)1); |
269 return Exec::UTraceOut(aHeader,aModuleUid,ext,aDataSize); |
329 return Exec::UTraceOut(aHeader,aModuleUid,ext,aDataSize); |
270 aHeader += 4; |
330 aHeader += 4; |
271 return Exec::BTraceOut(aHeader,aModuleUid,ext,aDataSize); |
331 return Exec::BTraceOut(aHeader,aModuleUid,ext,aDataSize); |
272 } |
332 } |
273 |
333 |
274 __NAKED__ void ExecRequestComplete(TInt /*aHandle*/, TRequestStatus*& /*aStatus*/, TInt /*aReason*/) |
334 __NAKED__ void ExecRequestComplete(TInt aHandle, TRequestStatus*& aStatus, TInt aReason) |
275 { |
335 { |
276 _asm mov ecx, [esp+8] // ecx = TRequestStatus** |
336 //TODO: look our thread per handle |
277 _asm xor eax, eax // |
337 *aStatus=aReason; |
278 _asm lock xchg eax, [ecx] // eax=TRequestStatus*, zero TRequestStatus* |
338 gProcess.iThread.iRequestSemaphore.Signal(); |
279 _asm cmp eax, 0 // |
|
280 _asm je ExecRequestComplete_ret |
|
281 _asm mov ecx, [esp+12] // ecx = aReason |
|
282 _asm mov [eax], ecx // store aReason in request status |
|
283 __DISPATCH(EExecThreadRequestSignal|EXECUTIVE_SLOW) |
|
284 _asm ExecRequestComplete_ret: ret |
|
285 } |
339 } |
286 |
340 |
287 |
341 |
288 |
342 |
289 |
343 |
353 |
407 |
354 |
408 |
355 // |
409 // |
356 #ifndef __GEN_USER_EXEC_CODE__ |
410 #ifndef __GEN_USER_EXEC_CODE__ |
357 |
411 |
358 const TInt KTrapStackSize=256; |
412 |
359 |
|
360 /* |
|
361 |
|
362 */ |
|
363 class TThread |
|
364 { |
|
365 public: |
|
366 |
|
367 public: |
|
368 RSemaphore iRequestSemaphore; |
|
369 CActiveScheduler* iActiveScheduler; //Current active scheduler for this thread. Used. |
|
370 TTrapHandler* iHandler; //This is our cleanup stack. Used. |
|
371 //No idea why we need that trap stack |
|
372 //TTrap* iTrapStack[KTrapStackSize]; |
|
373 //TInt iTrapCount; |
|
374 }; |
|
375 |
|
376 /* |
|
377 Object used to store process globals for our pseudo kernel. |
|
378 That's typically going to be a singleton. |
|
379 */ |
|
380 class TProcess |
|
381 { |
|
382 public: |
|
383 void CreateHeap(); |
|
384 void Free(); |
|
385 |
|
386 public: |
|
387 RHeap* iAllocator; |
|
388 TAny* iBase; |
|
389 TThread iThread; //Single thread for now |
|
390 }; |
|
391 |
|
392 |
|
393 void TProcess::CreateHeap() |
|
394 { |
|
395 //iThread.iTrapCount=0; |
|
396 //Define the size of our heap |
|
397 const TInt KHeapMaxSize=1024*1024*10; // 10 Mo for now |
|
398 __ASSERT_ALWAYS(iAllocator==NULL && iBase==NULL,Panic(ESymcExecPanicHeapAlreadyExists)); |
|
399 iBase=malloc(KHeapMaxSize); |
|
400 __ASSERT_ALWAYS(iBase!=NULL,Panic(ESymcExecPanicCreateHeapFailed)); |
|
401 //TODO: is there anyway we could use variable size heap? |
|
402 iAllocator=UserHeap::FixedHeap(iBase,KHeapMaxSize); |
|
403 __ASSERT_ALWAYS(iAllocator!=NULL,Panic(ESymcExecPanicCreateHeapFailed)); |
|
404 } |
|
405 |
|
406 void TProcess::Free() |
|
407 { |
|
408 free(iBase); |
|
409 } |
|
410 |
|
411 |
|
412 |
|
413 TProcess gProcess; |
|
414 |
|
415 |
|
416 |
|
417 //RHeap gAllocator; |
|
418 |
413 |
419 __EXECDECL__ void Exec::WaitForAnyRequest() |
414 __EXECDECL__ void Exec::WaitForAnyRequest() |
420 { |
415 { |
421 FAST_EXEC0(EFastExecWaitForAnyRequest); |
416 FAST_EXEC0(EFastExecWaitForAnyRequest); |
422 } |
417 } |
451 //return gProcess.iThread.iTrapStack[gProcess.iThread.iTrapCount--]; |
446 //return gProcess.iThread.iTrapStack[gProcess.iThread.iTrapCount--]; |
452 } |
447 } |
453 |
448 |
454 __EXECDECL__ CActiveScheduler* Exec::ActiveScheduler() |
449 __EXECDECL__ CActiveScheduler* Exec::ActiveScheduler() |
455 { |
450 { |
456 FAST_EXEC0(EFastExecActiveScheduler); |
451 //FAST_EXEC0(EFastExecActiveScheduler); |
457 } |
452 return gProcess.iThread.iActiveScheduler; |
458 |
453 } |
459 __EXECDECL__ void Exec::SetActiveScheduler(CActiveScheduler*) |
454 |
460 { |
455 __EXECDECL__ void Exec::SetActiveScheduler(CActiveScheduler* aActiveScheduler) |
461 FAST_EXEC1(EFastExecSetActiveScheduler); |
456 { |
|
457 //FAST_EXEC1(EFastExecSetActiveScheduler); |
|
458 gProcess.iThread.iActiveScheduler=aActiveScheduler; |
462 } |
459 } |
463 |
460 |
464 __EXECDECL__ TTimerLockSpec Exec::LockPeriod() |
461 __EXECDECL__ TTimerLockSpec Exec::LockPeriod() |
465 { |
462 { |
466 FAST_EXEC0(EFastExecLockPeriod); |
463 FAST_EXEC0(EFastExecLockPeriod); |
1109 __EXECDECL__ TInt Exec::MutexCreate(const TDesC8*, TOwnerType) |
1106 __EXECDECL__ TInt Exec::MutexCreate(const TDesC8*, TOwnerType) |
1110 { |
1107 { |
1111 SLOW_EXEC2(EExecMutexCreate); |
1108 SLOW_EXEC2(EExecMutexCreate); |
1112 } |
1109 } |
1113 |
1110 |
1114 __EXECDECL__ TInt Exec::SemaphoreCreate(const TDesC8*, TInt, TOwnerType) |
1111 __EXECDECL__ TInt Exec::SemaphoreCreate(const TDesC8* aName, TInt aCount, TOwnerType aType) |
1115 { |
1112 { |
1116 SLOW_EXEC3(EExecSemaphoreCreate); |
1113 //SLOW_EXEC3(EExecSemaphoreCreate); |
|
1114 #ifdef _WINDOWS |
|
1115 HANDLE semaphore = CreateSemaphore( |
|
1116 NULL, // default security attributes |
|
1117 aCount, |
|
1118 KMaxTInt, |
|
1119 //TODO: use the name |
|
1120 NULL); // unnamed mutex |
|
1121 |
|
1122 if (semaphore) |
|
1123 { |
|
1124 //success |
|
1125 return (TInt)semaphore; |
|
1126 } |
|
1127 |
|
1128 //failure |
|
1129 return NULL; |
|
1130 #else |
|
1131 //TODO: pthread implementation |
|
1132 Panic(ESymcExecPanicNotSupported); |
|
1133 #endif |
1117 } |
1134 } |
1118 |
1135 |
1119 __EXECDECL__ TInt Exec::ThreadOpenById(TUint, TOwnerType) |
1136 __EXECDECL__ TInt Exec::ThreadOpenById(TUint, TOwnerType) |
1120 { |
1137 { |
1121 SLOW_EXEC2(EExecThreadOpenById); |
1138 SLOW_EXEC2(EExecThreadOpenById); |
1684 SLOW_EXEC1(EExecExceptionDescriptor); |
1701 SLOW_EXEC1(EExecExceptionDescriptor); |
1685 } |
1702 } |
1686 |
1703 |
1687 __EXECDECL__ void Exec::ThreadRequestSignal(TInt) |
1704 __EXECDECL__ void Exec::ThreadRequestSignal(TInt) |
1688 { |
1705 { |
1689 SLOW_EXEC1(EExecThreadRequestSignal); |
1706 //SLOW_EXEC1(EExecThreadRequestSignal); |
|
1707 //TODO: look our thread per handle |
|
1708 gProcess.iThread.iRequestSemaphore.Signal(); |
1690 } |
1709 } |
1691 |
1710 |
1692 __EXECDECL__ TBool Exec::MutexIsHeld(TInt) |
1711 __EXECDECL__ TBool Exec::MutexIsHeld(TInt) |
1693 { |
1712 { |
1694 SLOW_EXEC1(EExecMutexIsHeld); |
1713 SLOW_EXEC1(EExecMutexIsHeld); |