DWORD UserBpStepHandler( PPROCESS_INFO ThisProcess, PTHREAD_INFO ThisThread, PEXCEPTION_RECORD ExceptionRecord, PBREAKPOINT_INFO BreakpointInfo ) { WriteMemory( ThisProcess->hProcess, (PVOID) BreakpointInfo->LastBp->Address, &BpInstr, BpSize ); BreakpointInfo->LastBp = NULL; ResumeAllThreads( ThisProcess, ThisThread ); ZeroMemory( BreakpointInfo, sizeof(BREAKPOINT_INFO) ); return DBG_CONTINUE; }
static void SettingsLeave(const UISettings &old_ui_settings) { if (!globalRunningEvent.Test()) return; SuspendAllThreads(); VerboseOperationEnvironment operation; MainWindow &main_window = XCSoarInterface::main_window; if (LanguageChanged) ReadLanguageFile(); if (MapFileChanged) { /* set these flags, because they may be loaded from the map file */ AirspaceFileChanged = true; AirfieldFileChanged = true; WaypointFileChanged = true; TerrainFileChanged = true; TopographyFileChanged = true; } if (TerrainFileChanged) { operation.SetText(_("Loading Terrain File...")); main_window.SetTerrain(NULL); glide_computer->SetTerrain(NULL); // re-load terrain delete terrain; terrain = RasterTerrain::OpenTerrain(file_cache, operation); main_window.SetTerrain(terrain); glide_computer->SetTerrain(terrain); } if (WaypointFileChanged || AirfieldFileChanged) { // re-load waypoints WaypointGlue::LoadWaypoints(way_points, terrain, operation); WaypointDetails::ReadFileFromProfile(way_points, operation); } if (WaypointFileChanged && protected_task_manager != NULL) { ProtectedTaskManager::ExclusiveLease lease(*protected_task_manager); OrderedTask *task = lease->Clone(XCSoarInterface::GetComputerSettings().task); if (task) { // this must be done in thread lock because it potentially changes the // waypoints database task->CheckDuplicateWaypoints(way_points); /* XXX shall this task be committed if it has been modified? */ delete task; way_points.Optimise(); } } if (WaypointFileChanged || TerrainFileChanged) { // re-set home WaypointGlue::SetHome(way_points, terrain, XCSoarInterface::SetComputerSettings(), device_blackboard, WaypointFileChanged); WaypointGlue::SaveHome(CommonInterface::GetComputerSettings()); } if (TopographyFileChanged) { main_window.SetTopography(NULL); topography->Reset(); LoadConfiguredTopography(*topography, operation); main_window.SetTopography(topography); } if (AirspaceFileChanged) { if (glide_computer != NULL) glide_computer->GetAirspaceWarnings().clear(); if (glide_computer != NULL) glide_computer->ClearAirspaces(); airspace_database.clear(); ReadAirspace(airspace_database, terrain, CommonInterface::GetComputerSettings().pressure, operation); } if (DevicePortChanged) devRestart(); const UISettings &ui_settings = CommonInterface::GetUISettings(); Units::SetConfig(ui_settings.units); const MapSettings &old_settings_map = old_ui_settings.map; const MapSettings &settings_map = ui_settings.map; if (settings_map.snail_type != old_settings_map.snail_type || settings_map.snail_scaling_enabled != old_settings_map.snail_scaling_enabled) main_window.SetLook().map.trail.Initialise(settings_map); if (settings_map.waypoint.landable_style != old_settings_map.waypoint.landable_style) main_window.SetLook().map.waypoint.Initialise(settings_map.waypoint); ResumeAllThreads(); CommonInterface::main_window.ResumeThreads(); // allow map and calculations threads to continue ActionInterface::SendMapSettings(true); operation.Hide(); InfoBoxManager::SetDirty(); main_window.full_redraw(); main_window.SetDefaultFocus(); }
ResultCode AddressArbiter::ArbitrateAddress(SharedPtr<Thread> thread, ArbitrationType type, VAddr address, s32 value, u64 nanoseconds) { auto timeout_callback = [this](ThreadWakeupReason reason, SharedPtr<Thread> thread, SharedPtr<WaitObject> object) { ASSERT(reason == ThreadWakeupReason::Timeout); // Remove the newly-awakened thread from the Arbiter's waiting list. waiting_threads.erase(std::remove(waiting_threads.begin(), waiting_threads.end(), thread), waiting_threads.end()); }; switch (type) { // Signal thread(s) waiting for arbitrate address... case ArbitrationType::Signal: // Negative value means resume all threads if (value < 0) { ResumeAllThreads(address); } else { // Resume first N threads for (int i = 0; i < value; i++) ResumeHighestPriorityThread(address); } break; // Wait current thread (acquire the arbiter)... case ArbitrationType::WaitIfLessThan: if ((s32)Memory::Read32(address) < value) { WaitThread(std::move(thread), address); } break; case ArbitrationType::WaitIfLessThanWithTimeout: if ((s32)Memory::Read32(address) < value) { thread->wakeup_callback = timeout_callback; thread->WakeAfterDelay(nanoseconds); WaitThread(std::move(thread), address); } break; case ArbitrationType::DecrementAndWaitIfLessThan: { s32 memory_value = Memory::Read32(address); if (memory_value < value) { // Only change the memory value if the thread should wait Memory::Write32(address, (s32)memory_value - 1); WaitThread(std::move(thread), address); } break; } case ArbitrationType::DecrementAndWaitIfLessThanWithTimeout: { s32 memory_value = Memory::Read32(address); if (memory_value < value) { // Only change the memory value if the thread should wait Memory::Write32(address, (s32)memory_value - 1); thread->wakeup_callback = timeout_callback; thread->WakeAfterDelay(nanoseconds); WaitThread(std::move(thread), address); } break; } default: LOG_ERROR(Kernel, "unknown type={}", static_cast<u32>(type)); return ERR_INVALID_ENUM_VALUE_FND; } // The calls that use a timeout seem to always return a Timeout error even if they did not put // the thread to sleep if (type == ArbitrationType::WaitIfLessThanWithTimeout || type == ArbitrationType::DecrementAndWaitIfLessThanWithTimeout) { return RESULT_TIMEOUT; } return RESULT_SUCCESS; }
~ScopeSuspendAllThreads() { ResumeAllThreads(); }
static void SettingsLeave() { if (!globalRunningEvent.test()) return; XCSoarInterface::main_window.map.set_focus(); SuspendAllThreads(); if (MapFileChanged) { AirspaceFileChanged = true; AirfieldFileChanged = true; WaypointFileChanged = true; TerrainFileChanged = true; TopologyFileChanged = true; } if ((WaypointFileChanged) || (TerrainFileChanged) || (AirfieldFileChanged)) { ProgressGlue::Create(_("Loading Terrain File...")); XCSoarInterface::main_window.map.set_terrain(NULL); // re-load terrain delete terrain; terrain = RasterTerrain::OpenTerrain(file_cache); // re-load waypoints WayPointGlue::ReadWaypoints(way_points, terrain); ReadAirfieldFile(way_points); // re-set home if (WaypointFileChanged || TerrainFileChanged) { WayPointGlue::SetHome(way_points, terrain, XCSoarInterface::SetSettingsComputer(), WaypointFileChanged, false); } if (terrain != NULL) { RasterTerrain::UnprotectedLease lease(*terrain); lease->SetViewCenter(XCSoarInterface::Basic().Location); } XCSoarInterface::main_window.map.set_terrain(terrain); } if (TopologyFileChanged) LoadConfiguredTopology(*topology); if (AirspaceFileChanged) { airspace_warnings.clear(); airspace_database.clear(); ReadAirspace(airspace_database, terrain, XCSoarInterface::Basic().pressure); } if (PolarFileChanged) { GlidePolar gp = protected_task_manager.get_glide_polar(); if (LoadPolarById(XCSoarInterface::SettingsComputer(), gp)) { protected_task_manager.set_glide_polar(gp); } } { ProtectedTaskManager::ExclusiveLease lease(protected_task_manager); lease->set_olc_rules(XCSoarInterface::SettingsComputer().olc_rules); } if (AirfieldFileChanged || AirspaceFileChanged || WaypointFileChanged || TerrainFileChanged || TopologyFileChanged) { ProgressGlue::Close(); XCSoarInterface::main_window.map.set_focus(); draw_thread->trigger_redraw(); } if (DevicePortChanged) devRestart(); ResumeAllThreads(); // allow map and calculations threads to continue }
static void SettingsLeave(const UISettings &old_ui_settings) { if (!global_running) return; SuspendAllThreads(); VerboseOperationEnvironment operation; MainWindow &main_window = *CommonInterface::main_window; if (LanguageChanged) ReadLanguageFile(); bool TerrainFileChanged = false, TopographyFileChanged = false; if (MapFileChanged) { /* set these flags, because they may be loaded from the map file */ AirspaceFileChanged = true; AirfieldFileChanged = true; WaypointFileChanged = true; TerrainFileChanged = true; TopographyFileChanged = true; } if (TerrainFileChanged) { operation.SetText(_("Loading Terrain File...")); /* just in case the bottom widget uses the old terrain object (e.g. the cross section) */ main_window.SetBottomWidget(nullptr); main_window.SetTerrain(NULL); glide_computer->SetTerrain(NULL); // re-load terrain delete terrain; terrain = RasterTerrain::OpenTerrain(file_cache, operation); main_window.SetTerrain(terrain); glide_computer->SetTerrain(terrain); /* re-create the bottom widget if it was deleted here */ PageActions::Update(); } if (WaypointFileChanged || AirfieldFileChanged) { // re-load waypoints WaypointGlue::LoadWaypoints(way_points, terrain, operation); WaypointDetails::ReadFileFromProfile(way_points, operation); } if (WaypointFileChanged && protected_task_manager != NULL) { ProtectedTaskManager::ExclusiveLease lease(*protected_task_manager); OrderedTask *task = lease->Clone(CommonInterface::GetComputerSettings().task); if (task) { // this must be done in thread lock because it potentially changes the // waypoints database task->CheckDuplicateWaypoints(way_points); /* XXX shall this task be committed if it has been modified? */ delete task; way_points.Optimise(); } } if (WaypointFileChanged || TerrainFileChanged) { // re-set home WaypointGlue::SetHome(way_points, terrain, CommonInterface::SetComputerSettings().poi, CommonInterface::SetComputerSettings().team_code, device_blackboard, WaypointFileChanged); WaypointGlue::SaveHome(Profile::map, CommonInterface::GetComputerSettings().poi, CommonInterface::GetComputerSettings().team_code); } if (TopographyFileChanged) { main_window.SetTopography(NULL); topography->Reset(); LoadConfiguredTopography(*topography, operation); main_window.SetTopography(topography); } if (AirspaceFileChanged) { if (glide_computer != NULL) glide_computer->GetAirspaceWarnings().Clear(); if (glide_computer != NULL) glide_computer->ClearAirspaces(); airspace_database.Clear(); ReadAirspace(airspace_database, terrain, CommonInterface::GetComputerSettings().pressure, operation); } if (DevicePortChanged) devRestart(); const UISettings &ui_settings = CommonInterface::GetUISettings(); Units::SetConfig(ui_settings.format.units); SetUserCoordinateFormat(ui_settings.format.coordinate_format); const MapSettings &old_settings_map = old_ui_settings.map; const MapSettings &settings_map = ui_settings.map; if (settings_map.trail.type != old_settings_map.trail.type || settings_map.trail.scaling_enabled != old_settings_map.trail.scaling_enabled) main_window.SetLook().map.trail.Initialise(settings_map.trail); if (settings_map.waypoint.landable_style != old_settings_map.waypoint.landable_style) main_window.SetLook().map.waypoint.Reinitialise(settings_map.waypoint); ResumeAllThreads(); main_window.ResumeThreads(); // allow map and calculations threads to continue ActionInterface::SendMapSettings(true); AudioVarioGlue::Configure(CommonInterface::GetUISettings().sound.vario); operation.Hide(); InfoBoxManager::SetDirty(); main_window.FlushRendererCaches(); main_window.FullRedraw(); main_window.SetDefaultFocus(); }