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 <philip.burkha...@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

Reply via email to