aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2012-11-23 16:05:38 -1000
committerGravatar Dirk Hohndel <dirk@hohndel.org>2012-11-23 19:33:39 -0800
commita9786564c23fbf032f47096f543699c8c402785b (patch)
tree551231e54e017c9e83fd44da59edbe4c94dfa716
parent10ce60e2120419282ff7694e8deda60e94832aa1 (diff)
downloadsubsurface-a9786564c23fbf032f47096f543699c8c402785b.tar.gz
Allocate dive samples separately from 'struct dive'
We used to avoid some extra allocations by just allocating the dive samples as part of the 'struct dive' allocation itself, but that ends up complicating things, and will make it impossible to have multiple different sets of samples (for multiple dive computers). So stop doing it. Just allocate the dive samples array separately. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--dive.c52
-rw-r--r--dive.h9
-rw-r--r--divelist.c1
-rw-r--r--file.c2
-rw-r--r--libdivecomputer.c13
-rw-r--r--parse-xml.c28
-rw-r--r--uemis.c6
7 files changed, 45 insertions, 66 deletions
diff --git a/dive.c b/dive.c
index c76b71056..ebf121643 100644
--- a/dive.c
+++ b/dive.c
@@ -145,36 +145,30 @@ double get_weight_units(unsigned int grams, int *frac, const char **units)
struct dive *alloc_dive(void)
{
- const int initial_samples = 5;
- unsigned int size;
struct dive *dive;
- size = dive_size(initial_samples);
- dive = malloc(size);
+ dive = malloc(sizeof(*dive));
if (!dive)
exit(1);
- memset(dive, 0, size);
- dive->alloc_samples = initial_samples;
+ memset(dive, 0, sizeof(*dive));
return dive;
}
-struct sample *prepare_sample(struct dive **divep)
+struct sample *prepare_sample(struct dive *dive)
{
- struct dive *dive = *divep;
if (dive) {
int nr = dive->samples;
int alloc_samples = dive->alloc_samples;
struct sample *sample;
if (nr >= alloc_samples) {
- unsigned int size;
+ struct sample *newsamples;
alloc_samples = (alloc_samples * 3)/2 + 10;
- size = dive_size(alloc_samples);
- dive = realloc(dive, size);
- if (!dive)
+ newsamples = realloc(dive->sample, alloc_samples * sizeof(struct sample));
+ if (!newsamples)
return NULL;
dive->alloc_samples = alloc_samples;
- *divep = dive;
+ dive->sample = newsamples;
}
sample = dive->sample + nr;
memset(sample, 0, sizeof(*sample));
@@ -593,16 +587,16 @@ struct dive *fixup_dive(struct dive *dive)
#define MERGE_MAX_PREFDL(res, dl, a, b, n) res->n = (dl && dl->n) ? dl->n : MAX(a->n, b->n)
#define MERGE_MIN_PREFDL(res, dl, a, b, n) res->n = (dl && dl->n) ? dl->n : (a->n)?(b->n)?MIN(a->n, b->n):(a->n):(b->n)
-static struct dive *add_sample(struct sample *sample, int time, struct dive *dive)
+static struct sample *add_sample(struct sample *sample, int time, struct dive *dive)
{
- struct sample *p = prepare_sample(&dive);
+ struct sample *p = prepare_sample(dive);
- if (!p)
- return NULL;
- *p = *sample;
- p->time.seconds = time;
- finish_sample(dive);
- return dive;
+ if (p) {
+ *p = *sample;
+ p->time.seconds = time;
+ finish_sample(dive);
+ }
+ return p;
}
/*
@@ -613,18 +607,18 @@ static struct dive *add_sample(struct sample *sample, int time, struct dive *div
* that the time in between the dives is at the surface, not some "last
* sample that happened to be at a depth of 1.2m".
*/
-static struct dive *merge_one_sample(struct sample *sample, int time, struct dive *dive)
+static void merge_one_sample(struct sample *sample, int time, struct dive *dive)
{
int last = dive->samples-1;
if (last >= 0) {
static struct sample surface;
int last_time = dive->sample[last].time.seconds;
if (time > last_time + 60) {
- dive = add_sample(&surface, last_time+20, dive);
- dive = add_sample(&surface, time - 20, dive);
+ add_sample(&surface, last_time+20, dive);
+ add_sample(&surface, time - 20, dive);
}
}
- return add_sample(sample, time, dive);
+ add_sample(sample, time, dive);
}
@@ -670,7 +664,7 @@ static struct dive *merge_samples(struct dive *res, struct dive *a, struct dive
/* Only samples from a? */
if (bt < 0) {
add_sample_a:
- res = merge_one_sample(as, at, res);
+ merge_one_sample(as, at, res);
as++;
asamples--;
continue;
@@ -679,7 +673,7 @@ add_sample_a:
/* Only samples from b? */
if (at < 0) {
add_sample_b:
- res = merge_one_sample(bs, bt, res);
+ merge_one_sample(bs, bt, res);
bs++;
bsamples--;
continue;
@@ -701,7 +695,7 @@ add_sample_b:
if (as->cylinderindex)
sample.cylinderindex = as->cylinderindex;
- res = merge_one_sample(&sample, at, res);
+ merge_one_sample(&sample, at, res);
as++;
bs++;
@@ -717,7 +711,7 @@ static struct dive *copy_samples(struct dive *res, struct dive *src)
while (samples) {
if (!res)
return NULL;
- res = add_sample(s, s->time.seconds, res);
+ add_sample(s, s->time.seconds, res);
s++;
samples--;
}
diff --git a/dive.h b/dive.h
index d4e2d3eaf..adf266b45 100644
--- a/dive.h
+++ b/dive.h
@@ -281,7 +281,7 @@ struct dive {
int sac, otu;
struct event *events;
int samples, alloc_samples;
- struct sample sample[];
+ struct sample *sample;
};
/* Pa = N/m^2 - so we determine the weight (in N) of the mass of 10m
@@ -415,11 +415,6 @@ extern void show_yearly_stats(void);
extern void update_dive(struct dive *new_dive);
extern void save_dives(const char *filename);
-static inline unsigned int dive_size(int samples)
-{
- return sizeof(struct dive) + samples*sizeof(struct sample);
-}
-
extern timestamp_t utc_mktime(struct tm *tm);
extern void utc_mkdate(timestamp_t, struct tm *tm);
@@ -427,7 +422,7 @@ extern struct dive *alloc_dive(void);
extern void record_dive(struct dive *dive);
extern void delete_dive(struct dive *dive);
-extern struct sample *prepare_sample(struct dive **divep);
+extern struct sample *prepare_sample(struct dive *dive);
extern void finish_sample(struct dive *dive);
extern void report_dives(gboolean imported, gboolean prefer_imported);
diff --git a/divelist.c b/divelist.c
index 37efed67a..13eda68b5 100644
--- a/divelist.c
+++ b/divelist.c
@@ -1931,6 +1931,7 @@ void delete_single_dive(int idx)
dive_table.nr--;
if (dive->selected)
amount_selected--;
+ free(dive->sample);
free(dive);
}
diff --git a/file.c b/file.c
index 31f5d882c..1289f3436 100644
--- a/file.c
+++ b/file.c
@@ -204,7 +204,7 @@ static int try_to_open_csv(const char *filename, struct memblock *mem, enum csv_
if (errno)
break;
- sample = prepare_sample(&dive);
+ sample = prepare_sample(dive);
sample->time.seconds = time;
add_sample_data(sample, type, val);
finish_sample(dive);
diff --git a/libdivecomputer.c b/libdivecomputer.c
index d4ffcc174..6ced23a48 100644
--- a/libdivecomputer.c
+++ b/libdivecomputer.c
@@ -115,8 +115,7 @@ void
sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
{
int i;
- struct dive **divep = userdata;
- struct dive *dive = *divep;
+ struct dive *dive = userdata;
struct sample *sample;
/*
@@ -127,9 +126,9 @@ sample_cb(dc_sample_type_t type, dc_sample_value_t value, void *userdata)
switch (type) {
case DC_SAMPLE_TIME:
- sample = prepare_sample(divep);
+ sample = prepare_sample(dive);
sample->time.seconds = value.time;
- finish_sample(*divep);
+ finish_sample(dive);
break;
case DC_SAMPLE_DEPTH:
sample->depth.mm = value.depth * 1000 + 0.5;
@@ -177,10 +176,10 @@ static void dev_info(device_data_t *devdata, const char *fmt, ...)
static int import_dive_number = 0;
-static int parse_samples(device_data_t *devdata, struct dive **divep, dc_parser_t *parser)
+static int parse_samples(device_data_t *devdata, struct dive *dive, dc_parser_t *parser)
{
// Parse the sample data.
- return dc_parser_samples_foreach(parser, sample_cb, divep);
+ return dc_parser_samples_foreach(parser, sample_cb, dive);
}
/*
@@ -303,7 +302,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
}
// Initialize the sample data.
- rc = parse_samples(devdata, &dive, parser);
+ rc = parse_samples(devdata, dive, parser);
if (rc != DC_STATUS_SUCCESS) {
dev_info(devdata, _("Error parsing the samples"));
dc_parser_destroy(parser);
diff --git a/parse-xml.c b/parse-xml.c
index 04d39643b..2593ed399 100644
--- a/parse-xml.c
+++ b/parse-xml.c
@@ -773,10 +773,8 @@ static void divinglog_place(char *place, void *_location)
country = NULL;
}
-static int divinglog_dive_match(struct dive **divep, const char *name, int len, char *buf)
+static int divinglog_dive_match(struct dive *dive, const char *name, int len, char *buf)
{
- struct dive *dive = *divep;
-
return MATCH(".divedate", divedate, &dive->when) ||
MATCH(".entrytime", divetime, &dive->when) ||
MATCH(".depth", depth, &dive->maxdepth) ||
@@ -955,10 +953,8 @@ static void uemis_percent(char *buffer, void *_cylinder)
percent(buffer, &cur_dive->cylinder[index].gasmix.o2);
}
-static int uemis_dive_match(struct dive **divep, const char *name, int len, char *buf)
+static int uemis_dive_match(struct dive *dive, const char *name, int len, char *buf)
{
- struct dive *dive = *divep;
-
return MATCH(".units.length", uemis_length_unit, &input_units) ||
MATCH(".units.volume", uemis_volume_unit, &input_units) ||
MATCH(".units.pressure", uemis_pressure_unit, &input_units) ||
@@ -986,7 +982,7 @@ static int uemis_dive_match(struct dive **divep, const char *name, int len, char
MATCH(".nitrox_3.travel_tank.oxygen", uemis_percent, dive->cylinder + 6) ||
MATCH(".dive.val.float", uemis_duration, &dive->duration) ||
MATCH(".dive.val.ts", uemis_ts, &dive->when) ||
- MATCH(".dive.val.bin", uemis_parse_divelog_binary, divep) ||
+ MATCH(".dive.val.bin", uemis_parse_divelog_binary, dive) ||
0;
}
@@ -1034,10 +1030,8 @@ success:
free(buffer);
}
-static int uddf_dive_match(struct dive **divep, const char *name, int len, char *buf)
+static int uddf_dive_match(struct dive *dive, const char *name, int len, char *buf)
{
- struct dive *dive = *divep;
-
return MATCH(".datetime", uddf_datetime, &dive->when) ||
MATCH(".diveduration", duration, &dive->duration) ||
MATCH(".greatestdepth", depth, &dive->maxdepth) ||
@@ -1055,7 +1049,7 @@ static void gps_location(char *buffer, void *_dive)
}
/* We're in the top-level dive xml. Try to convert whatever value to a dive value */
-static void try_to_fill_dive(struct dive **divep, const char *name, char *buf)
+static void try_to_fill_dive(struct dive *dive, const char *name, char *buf)
{
int len = strlen(name);
@@ -1063,17 +1057,17 @@ static void try_to_fill_dive(struct dive **divep, const char *name, char *buf)
switch (import_source) {
case UEMIS:
- if (uemis_dive_match(divep, name, len, buf))
+ if (uemis_dive_match(dive, name, len, buf))
return;
break;
case DIVINGLOG:
- if (divinglog_dive_match(divep, name, len, buf))
+ if (divinglog_dive_match(dive, name, len, buf))
return;
break;
case UDDF:
- if (uddf_dive_match(divep, name, len, buf))
+ if (uddf_dive_match(dive, name, len, buf))
return;
break;
@@ -1081,8 +1075,6 @@ static void try_to_fill_dive(struct dive **divep, const char *name, char *buf)
break;
}
- struct dive *dive = *divep;
-
if (MATCH(".number", get_index, &dive->number))
return;
if (MATCH(".tripflag", get_tripflag, &dive->tripflag))
@@ -1288,7 +1280,7 @@ static void ws_end(void)
static void sample_start(void)
{
- cur_sample = prepare_sample(&cur_dive);
+ cur_sample = prepare_sample(cur_dive);
}
static void sample_end(void)
@@ -1317,7 +1309,7 @@ static void entry(const char *name, int size, const char *raw)
return;
}
if (cur_dive) {
- try_to_fill_dive(&cur_dive, name, buf);
+ try_to_fill_dive(cur_dive, name, buf);
return;
}
if (cur_trip) {
diff --git a/uemis.c b/uemis.c
index 646c37d9a..d8bec845d 100644
--- a/uemis.c
+++ b/uemis.c
@@ -185,8 +185,7 @@ void uemis_parse_divelog_binary(char *base64, void *datap) {
uint8_t *data;
struct sample *sample;
uemis_sample_t *u_sample;
- struct dive **divep = datap;
- struct dive *dive = *divep;
+ struct dive *dive = datap;
int template, gasoffset;
in_deco = FALSE;
@@ -236,8 +235,7 @@ void uemis_parse_divelog_binary(char *base64, void *datap) {
* duration in the header is a) in minutes and b) up to 3 minutes short */
if (u_sample->dive_time > dive->duration.seconds + 180)
break;
- sample = prepare_sample(divep);
- dive = *divep; /* prepare_sample might realloc the dive */
+ sample = prepare_sample(dive);
sample->time.seconds = u_sample->dive_time;
sample->depth.mm = rel_mbar_to_depth(u_sample->water_pressure, dive);
sample->temperature.mkelvin = (u_sample->dive_temperature * 100) + 273150;