Exemple #1
0
void
InspectorWindow::ThreadStateChanged(const Team::ThreadEvent& event)
{
	BMessage message(MSG_THREAD_STATE_CHANGED);
	BReference< ::Thread> threadReference(event.GetThread());
	message.AddPointer("thread", threadReference.Get());

	if (PostMessage(&message) == B_OK)
		threadReference.Detach();
}
Exemple #2
0
int32
_user_create_timer(clockid_t clockID, thread_id threadID, uint32 flags,
	const struct sigevent* userEvent,
	const thread_creation_attributes* userThreadAttributes)
{
	// copy the sigevent structure from userland
	struct sigevent event;
	if (userEvent != NULL) {
		if (!IS_USER_ADDRESS(userEvent)
			|| user_memcpy(&event, userEvent, sizeof(event)) != B_OK) {
			return B_BAD_ADDRESS;
		}
	} else {
		// none given -- use defaults
		event.sigev_notify = SIGEV_SIGNAL;
		event.sigev_signo = SIGALRM;
	}

	// copy thread creation attributes from userland, if specified
	char nameBuffer[B_OS_NAME_LENGTH];
	ThreadCreationAttributes threadAttributes;
	if (event.sigev_notify == SIGEV_THREAD) {
		status_t error = threadAttributes.InitFromUserAttributes(
			userThreadAttributes, nameBuffer);
		if (error != B_OK)
			return error;
	}

	// get team and thread
	Team* team = thread_get_current_thread()->team;
	Thread* thread = NULL;
	if (threadID >= 0) {
		thread = Thread::GetAndLock(threadID);
		if (thread == NULL)
			return B_BAD_THREAD_ID;

		thread->Unlock();
	}
	BReference<Thread> threadReference(thread, true);

	// create the timer
	return create_timer(clockID, -1, team, thread, flags, event,
		userThreadAttributes != NULL ? &threadAttributes : NULL,
		userEvent == NULL);
}
bigtime_t
_user_estimate_max_scheduling_latency(thread_id id)
{
	syscall_64_bit_return_value();

	// get the thread
	Thread* thread;
	if (id < 0) {
		thread = thread_get_current_thread();
		thread->AcquireReference();
	} else {
		thread = Thread::Get(id);
		if (thread == NULL)
			return 0;
	}
	BReference<Thread> threadReference(thread, true);

	// ask the scheduler for the thread's latency
	InterruptsSpinLocker locker(gSchedulerLock);
	return gScheduler->estimate_max_scheduling_latency(thread);
}
Exemple #4
0
void
InspectorWindow::MessageReceived(BMessage* message)
{
	switch (message->what) {
		case MSG_THREAD_STATE_CHANGED:
		{
			::Thread* thread;
			if (message->FindPointer("thread",
					reinterpret_cast<void**>(&thread)) != B_OK) {
				break;
			}

			BReference< ::Thread> threadReference(thread, true);
			if (thread->State() == THREAD_STATE_STOPPED) {
				if (fCurrentBlock != NULL) {
					_SetCurrentBlock(NULL);
					_SetToAddress(fCurrentAddress);
				}
			}
			break;
		}
		case MSG_INSPECT_ADDRESS:
		{
			target_addr_t address = 0;
			if (message->FindUInt64("address", &address) != B_OK) {
				if (fAddressInput->TextView()->TextLength() == 0)
					break;

				fExpressionInfo->SetTo(fAddressInput->Text());

				fListener->ExpressionEvaluationRequested(fLanguage,
					fExpressionInfo);
			} else
				_SetToAddress(address);
			break;
		}
		case MSG_EXPRESSION_EVALUATED:
		{
			BString errorMessage;
			BReference<ExpressionResult> reference;
			ExpressionResult* value = NULL;
			if (message->FindPointer("value",
					reinterpret_cast<void**>(&value)) == B_OK) {
				reference.SetTo(value, true);
				if (value->Kind() == EXPRESSION_RESULT_KIND_PRIMITIVE) {
					Value* primitive = value->PrimitiveValue();
					BVariant variantValue;
					primitive->ToVariant(variantValue);
					if (variantValue.Type() == B_STRING_TYPE) {
						errorMessage.SetTo(variantValue.ToString());
					} else {
						_SetToAddress(variantValue.ToUInt64());
						break;
					}
				}
			} else {
				status_t result = message->FindInt32("result");
				errorMessage.SetToFormat("Failed to evaluate expression: %s",
					strerror(result));
			}

			BAlert* alert = new(std::nothrow) BAlert("Inspect Address",
				errorMessage.String(), "Close");
			if (alert != NULL)
				alert->Go();
			break;
		}

		case MSG_NAVIGATE_PREVIOUS_BLOCK:
		case MSG_NAVIGATE_NEXT_BLOCK:
		{
			if (fCurrentBlock != NULL) {
				target_addr_t address = fCurrentBlock->BaseAddress();
				if (message->what == MSG_NAVIGATE_PREVIOUS_BLOCK)
					address -= fCurrentBlock->Size();
				else
					address += fCurrentBlock->Size();

				BMessage setMessage(MSG_INSPECT_ADDRESS);
				setMessage.AddUInt64("address", address);
				PostMessage(&setMessage);
			}
			break;
		}
		case MSG_MEMORY_BLOCK_RETRIEVED:
		{
			TeamMemoryBlock* block = NULL;
			status_t result;
			if (message->FindPointer("block",
					reinterpret_cast<void **>(&block)) != B_OK
				|| message->FindInt32("result", &result) != B_OK) {
				break;
			}

			if (result == B_OK) {
				_SetCurrentBlock(block);
				fPreviousBlockButton->SetEnabled(true);
				fNextBlockButton->SetEnabled(true);
			} else {
				BString errorMessage;
				errorMessage.SetToFormat("Unable to read address 0x%" B_PRIx64
					": %s", block->BaseAddress(), strerror(result));

				BAlert* alert = new(std::nothrow) BAlert("Inspect address",
					errorMessage.String(), "Close");
				if (alert == NULL)
					break;

				alert->Go(NULL);
				block->ReleaseReference();
			}
			break;
		}
		case MSG_EDIT_CURRENT_BLOCK:
		{
			_SetEditMode(true);
			break;
		}
		case MSG_MEMORY_DATA_CHANGED:
		{
			if (fCurrentBlock == NULL)
				break;

			target_addr_t address;
			if (message->FindUInt64("address", &address) == B_OK
				&& address >= fCurrentBlock->BaseAddress()
				&& address < fCurrentBlock->BaseAddress()
					+ fCurrentBlock->Size()) {
				fCurrentBlock->Invalidate();
				_SetEditMode(false);
				fListener->InspectRequested(address, this);
			}
			break;
		}
		case MSG_COMMIT_MODIFIED_BLOCK:
		{
			// TODO: this could conceivably be extended to detect the
			// individual modified regions and only write those back.
			// That would require potentially submitting multiple separate
			// write requests, and thus require tracking all the writes being
			// waited upon for completion.
			fListener->MemoryWriteRequested(fCurrentBlock->BaseAddress(),
				fMemoryView->GetEditedData(), fCurrentBlock->Size());
			break;
		}
		case MSG_REVERT_MODIFIED_BLOCK:
		{
			_SetEditMode(false);
			break;
		}
		default:
		{
			BWindow::MessageReceived(message);
			break;
		}
	}
}