kernel/eka/euser/epoc/symc/uc_exec.cpp
branchanywhere
changeset 101 86a1781f0e9b
parent 96 428c5911a502
equal deleted inserted replaced
96:428c5911a502 101:86a1781f0e9b
    29 /*
    29 /*
    30 Symbian compatibility executive panics
    30 Symbian compatibility executive panics
    31 */
    31 */
    32 enum TSymcExecPanic
    32 enum TSymcExecPanic
    33 	{
    33 	{
       
    34 	ESymcExecPanicNotSupported,
    34 	ESymcExecPanicHeapAlreadyExists,
    35 	ESymcExecPanicHeapAlreadyExists,
    35 	ESymcExecPanicCreateHeapFailed,
    36 	ESymcExecPanicCreateHeapFailed,
    36 	ESymcExecPanicNotUsed
    37 	ESymcExecPanicNotUsed
    37 	};
    38 	};
    38 
    39 
    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);