On Sat, Apr 29, 2017 at 4:09 PM, Linus Torvalds
<[email protected]> wrote:
>
> I think that needs to be reverted, but I'll look at this a bit more.
> Maybe I can just fix it up.
Ok, this should fix it up. It makes Jan's test work for me.
Dirk, I'm attaching it as a patch because my tree has other patches in
it due to my BLE experiments, so I don't have a nice branch that I'd
ask you to merge on github. I can do that if you wish, but if you
still take patches this is better.
Linus
From 94fd24b4e2201292b016b7260fe4de630f6f40e0 Mon Sep 17 00:00:00 2001
From: Linus Torvalds <[email protected]>
Date: Sat, 29 Apr 2017 16:21:41 -0700
Subject: [PATCH] Fix event merging when interleaving dives
The core to avoid adding redundant gas switch events was completely
buggered, and caused the result list to be corrupted if it ever
triggered. This should fix it.
Fixes: b5de08b7 ("No gas change event on merging dives with same gas")
Reported-by: Jan Mulder <[email protected]>
Cc: Miika Turkia <[email protected]>
Cc: Dirk Hohndel <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
---
core/dive.c | 45 +++++++++++++++++++++++++--------------------
1 file changed, 25 insertions(+), 20 deletions(-)
diff --git a/core/dive.c b/core/dive.c
index 7e939068..e73b4f6f 100644
--- a/core/dive.c
+++ b/core/dive.c
@@ -1782,6 +1782,7 @@ static void merge_events(struct divecomputer *res, struct divecomputer *src1, st
{
struct event *a, *b;
struct event **p = &res->events;
+ struct event *last_gas = NULL;
/* Always use positive offsets */
if (offset < 0) {
@@ -1803,6 +1804,8 @@ static void merge_events(struct divecomputer *res, struct divecomputer *src1, st
while (a || b) {
int s;
+ struct event *pick;
+
if (!b) {
*p = a;
break;
@@ -1813,32 +1816,34 @@ static void merge_events(struct divecomputer *res, struct divecomputer *src1, st
}
s = sort_event(a, b);
- /* No gas change event when continuing with same gas */
- if (same_gas(a, b)) {
- if (s > 0) {
- p = &b->next;
- b = b->next;
- } else {
- p = &a->next;
- a = a->next;
- }
+ /* Identical events? Just skip one of them (we pick a) */
+ if (!s) {
+ a = a->next;
continue;
}
- /* Pick b */
- if (s > 0) {
- *p = b;
- p = &b->next;
+ /* Otherwise, pick the one that sorts first */
+ if (s < 0) {
+ pick = a;
+ a = a->next;
+ } else {
+ pick = b;
b = b->next;
- continue;
}
- /* Pick 'a' or neither */
- if (s < 0) {
- *p = a;
- p = &a->next;
+
+ /*
+ * If that's a gas-change that matches the previous
+ * gas change, we'll just skip it
+ */
+ if (event_is_gaschange(pick)) {
+ if (last_gas && same_gas(pick, last_gas))
+ continue;
+ last_gas = pick;
}
- a = a->next;
- continue;
+
+ /* Add it to the target list */
+ *p = pick;
+ p = &pick->next;
}
}
--
2.12.2.578.g5c4e54f4e
_______________________________________________
subsurface mailing list
[email protected]
http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface