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(); }
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); }
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; } } }