mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-25 07:25:47 +03:00
record stack traces
This commit is contained in:
parent
0276dd54aa
commit
c5c00d5740
@ -518,6 +518,37 @@ epsilon and negative checks everywhere in kinematics, but why? Should research
|
||||
it more, but I think the better approach is to use fixed-point arithmetic for
|
||||
everything (aka u8 or whatever).
|
||||
|
||||
Problems with floats:
|
||||
- they dont natively order
|
||||
- they arent PartialEq
|
||||
- serialization sometimes breaks
|
||||
- epsilon comparison issues
|
||||
|
||||
Options:
|
||||
- just to solve epsilon comparison issues
|
||||
- https://crates.io/crates/float-cmp
|
||||
- https://crates.io/crates/approx
|
||||
- just to get Ord and Eq
|
||||
- https://crates.io/crates/decorum
|
||||
- https://crates.io/crates/ordered-float
|
||||
- use rational / fraction types
|
||||
- https://crates.io/crates/fraction
|
||||
- https://crates.io/crates/rug
|
||||
- this seems a bit overpowered
|
||||
- use my own custom wrapper type around u8 or whatever size makes sense for each thing
|
||||
- representing 0.1s or 0.1m or whatever
|
||||
- use a fixed point arithmetic crate
|
||||
- https://crates.io/crates/fpa
|
||||
- https://crates.io/crates/fixed
|
||||
- https://crates.io/crates/fix
|
||||
- would want to wrap the types anyway; only some operations make sense
|
||||
|
||||
|
||||
- can we compare results with the prev float approach? make them store the
|
||||
other thing, compare results? or compare the results of a sim?
|
||||
- is it possible to do this change gradually? unlikely...
|
||||
|
||||
|
||||
- moment in time (tick)
|
||||
- resolution: 0.1s with u32, so about 13.5 years
|
||||
- duration
|
||||
@ -822,3 +853,10 @@ It happens because a car was previously throttling itself due to somebody in
|
||||
the way, but as soon as they start a turn, the car eagerly jumps ahead.
|
||||
|
||||
ah no, it's because we use max_lookahead_dist in accel_to_follow, and the speed limit we assert is the old road's speed.
|
||||
|
||||
## Moving away from piston
|
||||
|
||||
- options
|
||||
- gfx (pre-II or not?) + winit
|
||||
- https://suhr.github.io/gsgt/
|
||||
- glium (unmaintained)
|
||||
|
@ -71,4 +71,5 @@ fn main() {
|
||||
}
|
||||
}),
|
||||
);
|
||||
sim::save_backtraces("call_graph.json");
|
||||
}
|
||||
|
@ -1,20 +1,16 @@
|
||||
use abstutil;
|
||||
use backtrace::Backtrace;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::HashSet;
|
||||
use std::sync::Mutex;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct CallStack {
|
||||
calls: Vec<String>,
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref BACKTRACES: Mutex<HashMap<String, CallStack>> = Mutex::new(HashMap::new());
|
||||
static ref BACKTRACES: Mutex<HashSet<Vec<String>>> = Mutex::new(HashSet::new());
|
||||
}
|
||||
|
||||
pub fn capture_backtrace() {
|
||||
pub fn capture_backtrace(event: &str) {
|
||||
let bt = Backtrace::new();
|
||||
let mut found_this_fxn = false;
|
||||
let mut calls: Vec<String> = Vec::new();
|
||||
let mut calls: Vec<String> = vec![event.to_string()];
|
||||
for f in bt.frames() {
|
||||
let raw_name = format!("{}", f.symbols()[0].name().unwrap());
|
||||
let mut raw_name_parts: Vec<&str> = raw_name.split("::").collect();
|
||||
@ -33,15 +29,14 @@ pub fn capture_backtrace() {
|
||||
}
|
||||
}
|
||||
|
||||
let caller = &calls[0];
|
||||
let stack = CallStack {
|
||||
calls: calls[1..].to_vec(),
|
||||
};
|
||||
println!("insert {}: {:?}", caller, stack);
|
||||
let mut remember = BACKTRACES.lock().unwrap();
|
||||
remember.insert(caller.to_string(), stack);
|
||||
BACKTRACES.lock().unwrap().insert(calls);
|
||||
}
|
||||
|
||||
// TODO dump to file
|
||||
// TODO manually call when events are created and at other interesting points
|
||||
// TODO compiler flag so capture_backtrace is usually a no-op
|
||||
pub fn save_backtraces(path: &str) {
|
||||
abstutil::write_json(path, &(*BACKTRACES.lock().unwrap())).unwrap();
|
||||
}
|
||||
|
||||
// TODO call from all interesting methods in a few different types; maybe use macros to help
|
||||
// TODO compiler flag so capture_backtrace is usually a no-op. actually, looks like this doesn't
|
||||
// work in --release mode, so use that.
|
||||
// TODO script to organize and visualize results
|
||||
|
@ -48,6 +48,7 @@ use dimensioned::si;
|
||||
pub use events::Event;
|
||||
use geom::{Angle, Pt2D};
|
||||
pub use helpers::load;
|
||||
pub use instrument::save_backtraces;
|
||||
use map_model::{LaneID, Map, TurnID};
|
||||
pub use sim::{Benchmark, Sim};
|
||||
use std::fmt;
|
||||
|
@ -7,6 +7,7 @@ use draw_car::DrawCar;
|
||||
use draw_ped::DrawPedestrian;
|
||||
use driving::DrivingSimState;
|
||||
use failure::Error;
|
||||
use instrument::capture_backtrace;
|
||||
use intersections::IntersectionSimState;
|
||||
use kinematics::Vehicle;
|
||||
use map_model::{IntersectionID, LaneID, LaneType, Map, Turn, TurnID};
|
||||
@ -169,6 +170,7 @@ impl Sim {
|
||||
&self.car_properties,
|
||||
)? {
|
||||
events.push(Event::CarReachedParkingSpot(p.clone()));
|
||||
capture_backtrace("CarReachedParkingSpot");
|
||||
self.parking_state.add_parked_car(p.clone());
|
||||
self.spawner.car_reached_parking_spot(
|
||||
self.time,
|
||||
@ -185,6 +187,7 @@ impl Sim {
|
||||
.step(&mut events, TIMESTEP, map, &mut self.intersection_state)?
|
||||
{
|
||||
events.push(Event::PedReachedParkingSpot(ped, spot));
|
||||
capture_backtrace("PedReachedParkingSpot");
|
||||
self.spawner.ped_reached_parking_spot(
|
||||
self.time,
|
||||
ped,
|
||||
|
@ -138,7 +138,7 @@ impl TransitSimState {
|
||||
self.buses.get_mut(&car).unwrap().state =
|
||||
BusState::AtStop(stop_idx, time + 10.0 * si::S);
|
||||
events.push(Event::BusArrivedAtStop(car, stop.id));
|
||||
capture_backtrace();
|
||||
capture_backtrace("BusArrivedAtStop");
|
||||
if view.debug {
|
||||
println!("{} arrived at stop {:?}, now waiting", car, stop);
|
||||
}
|
||||
@ -156,6 +156,7 @@ impl TransitSimState {
|
||||
let next_stop = route.next_stop(stop_idx);
|
||||
self.buses.get_mut(&car).unwrap().state = BusState::DrivingToStop(next_stop);
|
||||
events.push(Event::BusDepartedFromStop(car, stop.id));
|
||||
capture_backtrace("BusDepartedFromStop");
|
||||
if view.debug {
|
||||
println!("{} departing from stop {:?}", car, stop);
|
||||
}
|
||||
@ -210,6 +211,7 @@ impl TransitSimState {
|
||||
for p in walking_sim.get_peds_waiting_at_stop(stop.id).into_iter() {
|
||||
if trips.should_ped_board_bus(p, b.route) {
|
||||
events.push(Event::PedEntersBus(p, b.car));
|
||||
capture_backtrace("PedEntersBus");
|
||||
b.passengers.push(p);
|
||||
walking_sim.ped_joined_bus(p, stop.id);
|
||||
}
|
||||
@ -226,6 +228,7 @@ impl TransitSimState {
|
||||
b.passengers.retain(|p| {
|
||||
if trips.should_ped_leave_bus(*p, stop.id) {
|
||||
events.push(Event::PedLeavesBus(*p, car));
|
||||
capture_backtrace("PedLeavesBus");
|
||||
// TODO would be a little cleaner to return this info up to sim and have it
|
||||
// plumb through to spawner? not sure
|
||||
spawner.ped_finished_bus_ride(now, *p, stop.id, trips, map);
|
||||
|
@ -4,6 +4,7 @@ use dimensioned::si;
|
||||
use draw_ped::DrawPedestrian;
|
||||
use failure::Error;
|
||||
use geom::{Line, Pt2D};
|
||||
use instrument::capture_backtrace;
|
||||
use intersections::{IntersectionSimState, Request};
|
||||
use map_model::{BuildingID, BusStop, IntersectionID, Lane, LaneID, Map, Turn, TurnID};
|
||||
use multimap::MultiMap;
|
||||
@ -216,6 +217,7 @@ impl Pedestrian {
|
||||
fp.dist_along -= new_dist;
|
||||
if fp.dist_along < 0.0 * si::M {
|
||||
events.push(Event::PedReachedBuilding(self.id, fp.bldg));
|
||||
capture_backtrace("PedReachedBuilding");
|
||||
return true;
|
||||
}
|
||||
false
|
||||
@ -399,6 +401,7 @@ impl WalkingSimState {
|
||||
Action::WaitAtBusStop(stop) => {
|
||||
self.peds.get_mut(&id).unwrap().active = false;
|
||||
events.push(Event::PedReachedBusStop(*id, stop));
|
||||
capture_backtrace("PedReachedBusStop");
|
||||
self.peds_per_bus_stop.insert(stop, *id);
|
||||
}
|
||||
Action::StartParkedCar(ref spot) => {
|
||||
|
Loading…
Reference in New Issue
Block a user