refactor: harden shared SPI ownership and ESP memory use

This commit is contained in:
Trail Mate Dev
2026-07-26 14:02:58 +08:00
parent 95da006db3
commit 1bb0ee3b35
96 changed files with 2212 additions and 2840 deletions
@@ -30,23 +30,20 @@ MapTileLookupResult FilesystemMapTileSource::lookup(const MapTileRef& ref) const
return result;
}
bool FilesystemMapTileSource::read(const MapTileRef& ref,
uint8_t* buffer,
std::size_t capacity,
std::size_t& out_size,
MapTileFormat& out_format) const
MapTileReadResult FilesystemMapTileSource::read(
const MapTileRef& ref,
uint8_t* buffer,
std::size_t capacity) const
{
out_size = 0;
out_format = mapTileFormatForLayer(ref.layer);
char path[160]{};
if (!resolver_.resolvePath(ref, path, sizeof(path)))
{
out_format = MapTileFormat::Unknown;
return false;
return {MapTileReadStatus::Invalid, 0, -1, MapTileFormat::Unknown};
}
return file_system_.readFile(path, buffer, capacity, out_size);
MapTileReadResult result = file_system_.readFile(path, buffer, capacity);
result.format = mapTileFormatForLayer(ref.layer);
return result;
}
bool FilesystemMapTileSource::resolvePath(const MapTileRef& ref,
@@ -26,9 +26,8 @@ uint32_t dedupeKeyForTile(const MapTileRef& ref)
} // namespace
MapTileAsyncRuntime::MapTileAsyncRuntime(IMapTileCommandSink& commands,
sys::runtime::RuntimePolicyStrategy* policy)
: commands_(commands), policy_(policy ? policy : &default_policy_)
MapTileAsyncRuntime::MapTileAsyncRuntime(IMapTileCommandSink& commands)
: commands_(commands)
{
}
@@ -103,7 +102,7 @@ bool MapTileAsyncRuntime::handleEvent(const MapTileAsyncEvent& event, MapTileRen
case MapTileAsyncEventKind::Cancelled:
ref.state = MapTileRenderState::Cancelled;
break;
case MapTileAsyncEventKind::ResourceBusy:
case MapTileAsyncEventKind::RetryLater:
ref.state = MapTileRenderState::Loading;
break;
case MapTileAsyncEventKind::Failed:
@@ -126,7 +125,7 @@ sys::runtime::RuntimeCommand MapTileAsyncRuntime::commandFromIntent(
sys::runtime::RuntimeCommand command{};
command.command_id = next_command_id_++;
command.kind = intent.kind;
command.priority = policy_->selectPriority(intent);
command.priority = intent.priority_hint;
command.cancel_policy = intent.cancel_policy;
command.created_at_ms = intent.submitted_at_ms;
command.deadline_ms = intent.deadline_ms;
@@ -137,15 +136,11 @@ sys::runtime::RuntimeCommand MapTileAsyncRuntime::commandFromIntent(
}
MapTileWorker::MapTileWorker(IMapTileWorkerBackend& backend,
sys::runtime::IBusArbiter& bus,
IMapTileEventSink& events,
uint8_t* scratch,
std::size_t scratch_size,
sys::runtime::RuntimePolicyStrategy* policy)
std::size_t scratch_size)
: backend_(backend),
bus_(bus),
events_(events),
policy_(policy ? policy : &default_policy_),
scratch_(scratch),
scratch_size_(scratch_size)
{
@@ -153,31 +148,6 @@ MapTileWorker::MapTileWorker(IMapTileWorkerBackend& backend,
bool MapTileWorker::execute(const LoadTileCommand& command, uint32_t now_ms)
{
sys::runtime::BusAcquireRequest request{};
request.resource = command.runtime.origin;
request.policy = policy_->selectBusPolicy(command.runtime);
request.command_id = command.runtime.command_id;
request.deadline_ms = command.runtime.deadline_ms;
request.owner_label = "map_tile_sd";
const auto acquired = bus_.acquire(request);
if (acquired.status != sys::runtime::BusAcquireStatus::Acquired)
{
MapTileAsyncEvent event{};
event.kind = MapTileAsyncEventKind::ResourceBusy;
event.command_id = command.runtime.command_id;
event.generation = command.runtime.generation;
event.tile = command.tile;
event.error = static_cast<int32_t>(acquired.status);
(void)events_.publish(event);
return false;
}
// The bus grant is an admission check only. The backend owns its
// transaction boundaries and must reacquire the shared bus for each
// filesystem or hardware-safe operation. Holding the bus across tile
// reads would allow a large SD read to starve display frames.
bus_.release(acquired.token);
MapTileAsyncEvent event{};
event.command_id = command.runtime.command_id;
event.generation = command.runtime.generation;
@@ -186,9 +156,9 @@ bool MapTileWorker::execute(const LoadTileCommand& command, uint32_t now_ms)
const MapTileReadResult read_result =
backend_.read(command.tile, scratch_, scratch_size_);
const bool ok = read_result.status == MapTileReadStatus::Ready;
if (read_result.status == MapTileReadStatus::ResourceBusy)
if (read_result.status == MapTileReadStatus::RetryLater)
{
event.kind = MapTileAsyncEventKind::ResourceBusy;
event.kind = MapTileAsyncEventKind::RetryLater;
}
else
{