summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorGravatar Robert C. Helling <helling@atdotde.de>2017-05-26 00:45:53 +0200
committerGravatar Dirk Hohndel <dirk@hohndel.org>2017-05-26 15:44:36 -0700
commit7b18be2a50e3c94fa1e9ae30c92bbb3eee3593d6 (patch)
treeaf16a82b1302591c3448812280f261b1cc5296e4 /core
parent57ee5a5477c92ff4dd7b8975b1866c988556d14e (diff)
downloadsubsurface-7b18be2a50e3c94fa1e9ae30c92bbb3eee3593d6.tar.gz
Adopt planner state caching to new struct
Signed-off-by: Robert C. Helling <helling@atdotde.de>
Diffstat (limited to 'core')
-rw-r--r--core/deco.c34
-rw-r--r--core/dive.h6
-rw-r--r--core/planner.c21
-rw-r--r--core/profile.c8
4 files changed, 35 insertions, 34 deletions
diff --git a/core/deco.c b/core/deco.c
index 37c34a024..33a049f7c 100644
--- a/core/deco.c
+++ b/core/deco.c
@@ -569,32 +569,30 @@ void clear_deco(double surface_pressure)
deco_state->max_ambient_pressure = 0.0;
}
-void cache_deco_state(char **cached_datap)
+void cache_deco_state(struct deco_state **cached_datap)
{
- char *data = *cached_datap;
+ struct deco_state *data = *cached_datap;
if (!data) {
- data = malloc(2 * TISSUE_ARRAY_SZ + sizeof(double) + sizeof(int));
+ data = malloc(sizeof(struct deco_state));
*cached_datap = data;
}
- memcpy(data, deco_state->tissue_n2_sat, TISSUE_ARRAY_SZ);
- data += TISSUE_ARRAY_SZ;
- memcpy(data, deco_state->tissue_he_sat, TISSUE_ARRAY_SZ);
- data += TISSUE_ARRAY_SZ;
- memcpy(data, &deco_state->gf_low_pressure_this_dive, sizeof(double));
- data += sizeof(double);
- memcpy(data, &deco_state->ci_pointing_to_guiding_tissue, sizeof(int));
+ *data = *deco_state;
}
-void restore_deco_state(char *data)
+void restore_deco_state(struct deco_state *data, bool keep_vpmb_state)
{
- memcpy(deco_state->tissue_n2_sat, data, TISSUE_ARRAY_SZ);
- data += TISSUE_ARRAY_SZ;
- memcpy(deco_state->tissue_he_sat, data, TISSUE_ARRAY_SZ);
- data += TISSUE_ARRAY_SZ;
- memcpy(&deco_state->gf_low_pressure_this_dive, data, sizeof(double));
- data += sizeof(double);
- memcpy(&deco_state->ci_pointing_to_guiding_tissue, data, sizeof(int));
+ if (keep_vpmb_state) {
+ int ci;
+ for (ci = 0; ci < 16; ci++) {
+ data->bottom_n2_gradient[ci] = deco_state->bottom_n2_gradient[ci];
+ data->bottom_he_gradient[ci] = deco_state->bottom_he_gradient[ci];
+ data->initial_n2_gradient[ci] = deco_state->initial_n2_gradient[ci];
+ data->initial_he_gradient[ci] = deco_state->initial_he_gradient[ci];
+ }
+ }
+ *deco_state = *data;
+
}
int deco_allowed_depth(double tissues_tolerance, double surface_pressure, struct dive *dive, bool smooth)
diff --git a/core/dive.h b/core/dive.h
index a39759763..fa89edc44 100644
--- a/core/dive.h
+++ b/core/dive.h
@@ -863,8 +863,8 @@ extern void clear_deco(double surface_pressure);
extern void dump_tissues(void);
extern void set_gf(short gflow, short gfhigh, bool gf_low_at_maxdepth);
extern void set_vpmb_conservatism(short conservatism);
-extern void cache_deco_state(char **datap);
-extern void restore_deco_state(char *data);
+extern void cache_deco_state(struct deco_state **datap);
+extern void restore_deco_state(struct deco_state *data, bool keep_vpmb_state);
extern void nuclear_regeneration(double time);
extern void vpmb_start_gradient();
extern void vpmb_next_gradient(double deco_time, double surface_pressure);
@@ -900,7 +900,7 @@ struct divedatapoint *create_dp(int time_incr, int depth, int cylinderid, int po
#if DEBUG_PLAN
void dump_plan(struct diveplan *diveplan);
#endif
-bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool show_disclaimer);
+bool plan(struct diveplan *diveplan, struct deco_state **cached_datap, bool is_planner, bool show_disclaimer);
void calc_crushing_pressure(double pressure);
void vpmb_start_gradient();
void clear_vpmb_state();
diff --git a/core/planner.c b/core/planner.c
index 30552a954..22f62a2c1 100644
--- a/core/planner.c
+++ b/core/planner.c
@@ -130,7 +130,7 @@ void interpolate_transition(struct dive *dive, duration_t t0, duration_t t1, dep
}
/* returns the tissue tolerance at the end of this (partial) dive */
-unsigned int tissue_at_end(struct dive *dive, char **cached_datap)
+unsigned int tissue_at_end(struct dive *dive, struct deco_state **cached_datap)
{
struct divecomputer *dc;
struct sample *sample, *psample;
@@ -143,7 +143,7 @@ unsigned int tissue_at_end(struct dive *dive, char **cached_datap)
if (!dive)
return 0;
if (*cached_datap) {
- restore_deco_state(*cached_datap);
+ restore_deco_state(*cached_datap, true);
} else {
surface_interval = init_decompression(dive);
cache_deco_state(cached_datap);
@@ -563,17 +563,20 @@ bool trial_ascent(int trial_depth, int stoplevel, int avg_depth, int bottom_time
{
bool clear_to_ascend = true;
- char *trial_cache = NULL;
+ struct deco_state *trial_cache = NULL;
// For consistency with other VPM-B implementations, we should not start the ascent while the ceiling is
// deeper than the next stop (thus the offgasing during the ascent is ignored).
// However, we still need to make sure we don't break the ceiling due to on-gassing during ascent.
+ cache_deco_state(&trial_cache);
if (decoMode() == VPMB && (deco_allowed_depth(tissue_tolerance_calc(&displayed_dive,
depth_to_bar(stoplevel, &displayed_dive)),
- surface_pressure, &displayed_dive, 1) > stoplevel))
+ surface_pressure, &displayed_dive, 1) > stoplevel)) {
+ restore_deco_state(trial_cache, false);
+ free(trial_cache);
return false;
+ }
- cache_deco_state(&trial_cache);
while (trial_depth > stoplevel) {
int deltad = ascent_velocity(trial_depth, avg_depth, bottom_time) * TIMESTEP;
if (deltad > trial_depth) /* don't test against depth above surface */
@@ -589,7 +592,7 @@ bool trial_ascent(int trial_depth, int stoplevel, int avg_depth, int bottom_time
}
trial_depth -= deltad;
}
- restore_deco_state(trial_cache);
+ restore_deco_state(trial_cache, false);
free(trial_cache);
return clear_to_ascend;
}
@@ -613,7 +616,7 @@ bool enough_gas(int current_cylinder)
// Work out the stops. Return value is if there were any mandatory stops.
-bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool show_disclaimer)
+bool plan(struct diveplan *diveplan, struct deco_state **cached_datap, bool is_planner, bool show_disclaimer)
{
int bottom_depth;
int bottom_gi;
@@ -621,7 +624,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool
bool is_final_plan = true;
int deco_time;
int previous_deco_time;
- char *bottom_cache = NULL;
+ struct deco_state *bottom_cache = NULL;
struct sample *sample;
int po2;
int transitiontime, gi;
@@ -807,7 +810,7 @@ bool plan(struct diveplan *diveplan, char **cached_datap, bool is_planner, bool
vpmb_next_gradient(deco_time, diveplan->surface_pressure / 1000.0);
previous_deco_time = deco_time;
- restore_deco_state(bottom_cache);
+ restore_deco_state(bottom_cache, true);
depth = bottom_depth;
gi = bottom_gi;
diff --git a/core/profile.c b/core/profile.c
index efe97d4f3..86bc974b8 100644
--- a/core/profile.c
+++ b/core/profile.c
@@ -950,7 +950,7 @@ void calculate_deco_information(struct dive *dive, struct divecomputer *dc, stru
double surface_pressure = (dc->surface_pressure.mbar ? dc->surface_pressure.mbar : get_surface_pressure_in_mbar(dive, true)) / 1000.0;
bool first_iteration = true;
int deco_time = 0, prev_deco_time = 10000000;
- char *cache_data_initial = NULL;
+ struct deco_state *cache_data_initial = NULL;
/* For VPM-B outside the planner, cache the initial deco state for CVA iterations */
if (decoMode() == VPMB && !in_planner())
cache_deco_state(&cache_data_initial);
@@ -1043,13 +1043,13 @@ void calculate_deco_information(struct dive *dive, struct divecomputer *dc, stru
last_ndl_tts_calc_time = entry->sec;
/* We are going to mess up deco state, so store it for later restore */
- char *cache_data = NULL;
+ struct deco_state *cache_data = NULL;
cache_deco_state(&cache_data);
calculate_ndl_tts(entry, dive, surface_pressure);
if (decoMode() == VPMB && !in_planner() && i == pi->nr - 1)
final_tts = entry->tts_calc;
/* Restore "real" deco state for next real time step */
- restore_deco_state(cache_data);
+ restore_deco_state(cache_data, false);
free(cache_data);
}
}
@@ -1066,7 +1066,7 @@ void calculate_deco_information(struct dive *dive, struct divecomputer *dc, stru
first_ceiling = 0;
first_iteration = false;
count_iteration ++;
- restore_deco_state(cache_data_initial);
+ restore_deco_state(cache_data_initial, false);
} else {
// With Buhlmann, or not in planner, iterating isn't needed. This makes the while condition false.
prev_deco_time = deco_time = 0;