示例#1
0
/**
 * Given a thread ID, return a handle to the corresponding DThread. If the returned
 * pointer is non-NULL, it is the responsibility of the caller to close the handle.
 * 
 * @pre caller must be in thread critical section
 * @post if a non-NULL value is returned then a handle to the thread has been
 * opened on the callers behalf
 * @param aThreadId ID of the thread to return a handle for
 * @return a DThread* to the appropriate thread, or NULL if a handle could not be
 * opened to the specified thread
 */
DThread* DebugUtils::OpenThreadHandle(TUint64 aThreadId)
	{
	__ASSERT_CRITICAL;
	LOG_MSG2("DebugUtils::OpenThreadHandle(0x%lx)", aThreadId);

	DObjectCon& threads = *Kern::Containers()[EThread];  // Get containing holding threads
	threads.Wait();  // Obtain the container mutex so the list does get changed under us

	DThread* thread = Kern::ThreadFromId(aThreadId);

	// Open a handle to the thread so that it doesn't exit while we are processing
	if (thread)
		{
		// if opening a handle fails then set thread to NULL
		if(KErrNone != thread->Open())
			{
			LOG_MSG2("\tCould not open handle to thread %d", (TUint32)aThreadId);
			thread = NULL;
			}
		}
	else
		{
		LOG_MSG2("\tThread with ID %d is NULL", (TUint32)aThreadId);
		}

	threads.Signal();  // Release the container mutex

	return thread;
	}
示例#2
0
//
// The implementation of RBMDriver::SetAbsPriority() call.
//
TInt DBMLChannel::SetAbsPriority(TInt aThreadHandle, TInt aNewPrio, TInt* aOldPrio)
	{
	NKern::LockSystem();
	//
	// Under the system lock find the DThread object and increment its ref-count (i.e Open()) 
	//
	DThread* thr = (DThread*) Kern::ObjectFromHandle(&Kern::CurrentThread(), aThreadHandle, EThread);
	TInt r;
	if (!thr)
		{
		r = EBadHandle;
		}
	else
		{
		r = thr->Open();
		}
	//
	// Now it's safe to release the system lock and to work with the object.
	//
	NKern::ThreadEnterCS();
	NKern::UnlockSystem();
	if (r != KErrNone)
		{
		NKern::ThreadLeaveCS();
		return r;
		}
	*aOldPrio = thr->iDefaultPriority;
	Kern::SetThreadPriority(aNewPrio, thr);
	//
	// Work is done - close the object.
	//	
	thr->Close(NULL);
	NKern::ThreadLeaveCS();
	return KErrNone;
	}
示例#3
0
void DPowerManager::RequestWakeupEventNotification(TRequestStatus* aStatus)
	{ // called by ExecHandler
	__KTRACE_OPT(KPOWER,Kern::Printf("PowerManger::RequestWakeupEventNotification()"));
	Lock();		// we aquire this lock to avoid new requests while in PowerDown
	NKern::LockSystem();
	if (iClient || iRequest->SetStatus(aStatus) != KErrNone)
		Kern::RequestComplete(aStatus, KErrInUse);
	else
		{
		iClient = TheCurrentThread;
		iClient->Open();
		}
	NKern::UnlockSystem();
	Unlock();
	__KTRACE_OPT(KPOWER,Kern::Printf("<PowerManger::RequestWakeupEventNotification()"));
	}	
示例#4
0
/**
 * Opens a reference to the first thread of the given process. Returns NULL if
 * there are no threads remaining in the process or if the thread couldn't be opened.
 * 
 * @pre Caller must be in thread context, in critical section, no fast mutexes held.
 * @post if result is non-NULL caller is responsible for closing the handle
 * @param aProcess The process whose first thread is to be opened
 * @return an Open()ed pointer to the first thread in the process, or NULL.
 */
DThread* DebugUtils::OpenFirstThreadForProcess(DProcess* aProcess)
	{
	__ASSERT_CRITICAL;
	// Copied from memspy's DMemSpyDriverOSAdaptionDProcess::OpenFirstThread()

	// It appears that the system lock needs to be held while manipulating the iThreadQ
	DThread* result = NULL;
	NKern::LockSystem();
	// We don't use DProcess::FirstThread() as that doesn't appear to do any checking of whether the list is empty, ie if there are no threads at all
	SDblQueLink* threadLink = aProcess->iThreadQ.First();
	if (threadLink != NULL && threadLink != &aProcess->iThreadQ.iA)
		{
		result = _LOFF(threadLink,DThread,iProcessLink);
		if (result->Open() != KErrNone)
			{
			result = NULL;
			}
		}
	NKern::UnlockSystem();
    return result;
    }
示例#5
0
/**
	Handle the requests for this channel.

@param aFunction 	The operation the LDD should perform.
@param a1 			The first argument for the operation.
@param a2 			The second argument for the operation.
@return KErrNone on success or one of the system wide error codes.
*/
TInt DDefragChannel::Request(TInt aFunction, TAny* a1, TAny* a2)
	{
	TInt r = KErrNone;
	NKern::ThreadEnterCS();

	Kern::SemaphoreWait(*iDefragSemaphore);
	if (!iDefragDfcFree && aFunction != RDefragChannel::EControlGeneralDefragDfcComplete)
		{// Only allow a single defrag operation at a time.
		r = KErrInUse;
		goto exit;
		}

	switch (aFunction)
		{
		case RDefragChannel::EControlGeneralDefragDfc:
			// Queue a defrag operation so that on completion it queues a
			// DFC on this driver.
			iRequestThread = &Kern::CurrentThread();
			iRequestThread->Open();

			// Open a reference on this channel to stop the destructor running before
			// the defrag request has completed.
			Open();
			r = iCompleteReq->SetStatus((TRequestStatus*)a1);
			if (r == KErrNone)
				r = iDefragReq.DefragRam(&iDefragCompleteDfc, KDefragRamThreadPriority);
			if (r != KErrNone)
				{// defrag operation didn't start so close all openned handles
				AsyncClose();
				iRequestThread->AsyncClose();
				iRequestThread = NULL;
				}
			else
				iDefragDfcFree = EFalse;
			break;

		case RDefragChannel::EControlGeneralDefragDfcComplete:
			if (iRequestThread != NULL)
				{// The defrag dfc hasn't completed so this shouldn't have been invoked.
				r = KErrGeneral;
				}
			else
				{
				iDefragDfcFree = ETrue;
				}
			break;

		case RDefragChannel::EControlGeneralDefragSem:
			{// Queue a defrag operation so that it will signal a fast mutex once
			// it has completed.
			NFastSemaphore sem;
			NKern::FSSetOwner(&sem, 0);
			r = iDefragReq.DefragRam(&sem, KDefragRamThreadPriority);

			if (r != KErrNone)
				{// Error occurred attempting to queue the defrag operation.
				break;
				}

			// Defrag operation has now been queued so wait for it to finish.
			// Could do some extra kernel side work here before waiting on the 
			// semaphore.
			NKern::FSWait(&sem);
			r = iDefragReq.Result();
			}
			break;

		case RDefragChannel::EControlGeneralDefrag:
			// Synchronously perform a defrag.
			{
			r = iDefragReq.DefragRam(KDefragRamThreadPriority);
			}
			break;

		case RDefragChannel::EControlAllocLowestZone:
			// Allocate from the lowest preference zone
			r = DoAllocLowestZone();
			break;

		case RDefragChannel::EControlClaimLowestZone:
			// Claims the lowest preference zone
			r = DoClaimLowestZone();
			break;
			
		case RDefragChannel::EControlCloseChunk:
			// Have finished with the chunk so close it then free the RAM mapped by it
			r = DoChunkClose();
			TRACE( if (r != KErrNone) {Kern::Printf("ChunkClose returns %d", r);});
			break;

		default:
			r=KErrNotSupported;
			break;
		}