You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by an...@apache.org on 2023/06/02 18:23:26 UTC

[mynewt-newt] 01/02: Fixed issue where packages with the same sysinit value were odered in non-deterministic and no longer lexicographic order

This is an automated email from the ASF dual-hosted git repository.

andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-newt.git

commit f0663b08e9f7c1d7aca0df0e5c065c37d4405623
Author: Philip Burkhardt <ph...@juul.com>
AuthorDate: Tue May 23 10:36:10 2023 -0700

    Fixed issue where packages with the same sysinit value were odered in non-deterministic and no longer lexicographic order
---
 newt/sysinit/sysinit.go | 39 ++++++++++++++++++++++++++++++++-------
 1 file changed, 32 insertions(+), 7 deletions(-)

diff --git a/newt/sysinit/sysinit.go b/newt/sysinit/sysinit.go
index efa226ae..ee1caf3c 100644
--- a/newt/sysinit/sysinit.go
+++ b/newt/sysinit/sysinit.go
@@ -133,12 +133,43 @@ func ResolveStageFuncsOrder(sfs []stage.StageFunc) ([]stage.StageFunc, error) {
 		if len(sfRef.Stage.Befores) == 0 && len(sfRef.Stage.Afters) == 0 {
 			stage, _ := sfRef.Stage.IntVal()
 			nodesByStage[stage] = append(nodesByStage[stage], sfRef)
-			nodes = append(nodes, sfRef)
 		} else {
 			nodesQ = append(nodesQ, sfRef)
 		}
 	}
 
+	var stages []int
+	for stage := range nodesByStage {
+		stages = append(stages, stage)
+	}
+	sort.Ints(stages)
+
+	// Lexicographically sort nodes in each stage, then build the nodes stack.
+	// This helps ensure that sysinit order is reproducable and deterministic
+	for stageIndex, _ := range stages {
+		lsfs := nodesByStage[stages[stageIndex]]
+		sort.Slice(lsfs, func(i int, j int) bool {
+			a := lsfs[i]
+			b := lsfs[j]
+
+			if strings.Compare(a.Name, b.Name) == -1 {
+				return false
+			}
+			return true
+		})
+		nodes = append(nodes, nodesByStage[stages[stageIndex]]...)
+	}
+
+	sort.Slice(nodesQ, func(i int, j int) bool {
+		a := nodesQ[i]
+		b := nodesQ[j]
+
+		if strings.Compare(a.Name, b.Name) == -1 {
+			return false
+		}
+		return true
+	})
+    
 	// Put nodes without stages first, so they are resolved and put to
 	// stack first - we do not want them to precede all nodes with stages.
 	// While technically correct, it's better not to start sysinit with
@@ -146,12 +177,6 @@ func ResolveStageFuncsOrder(sfs []stage.StageFunc) ([]stage.StageFunc, error) {
 	// before os init packages.
 	nodes = append(nodesQ, nodes...)
 
-	var stages []int
-	for stage := range nodesByStage {
-		stages = append(stages, stage)
-	}
-	sort.Ints(stages)
-
 	// Add implicit dependencies for nodes with stages. We need to add
 	// direct dependencies between each node of stage X to each node of
 	// stage Y to make sure they can be resolved properly and reordered