All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ian Jackson <ian.jackson@eu.citrix.com>
To: xen-devel@lists.xenproject.org
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>,
	Ian Campbell <ian.campbell@citrix.com>
Subject: [OSSTEST PATCH 08/13] Planner: ms-queuedaemon: Prep for multiple walkers
Date: Wed, 2 Sep 2015 16:45:14 +0100	[thread overview]
Message-ID: <1441208719-31336-9-git-send-email-ian.jackson@eu.citrix.com> (raw)
In-Reply-To: <1441208719-31336-1-git-send-email-ian.jackson@eu.citrix.com>

We are going to introduce multiple concurrent streams of planning
processing, called `walkers'.

Prepare the ground for this with some formulaic changes which will
otherwise greatly clutter substantive patches.

(A client will still only think for one walker at once, because that's
what the client protocol expects - and anything else would be far too
confusing.)

General:
 * Introduce the concept of a `walker' to ms-queuedaemon.
 * Provide a list of the walkers which might exist, `walkers'
 * Provide some helper procedures for iterating over these,
   and easily accessing their state.

Queue handling:
 * Add a new `w' argument to many procs: specifically, most of the
   procs in the section `machinery for running the queue'.
 * Log the walker ($w) at the start of all relevant log messages.
 * Pass the -w option to ms-planner and ms-planner-debug.
 * Add safety catches which will crash the ms-queuedaemon if it finds
   it is asking the same client to think for more than one walker.
 * we-are-thinking and check-we-are-thinking tell the caller what
   walker the client is thinking for.
 * In the resource-plan.html filename, replace `plan' with the walker
   filename.

Elsewhere:
 * Teach dequeue-chan to deal with all the walkers, including
   maybe the (one) walker for which the client is thinking.
 * Teach log-state to report on all the walkers.
 * In the runneeded logic, hardcode `plan' as the walker to use.

There is still actually only one walker.

No overall functional change, except to some log messages.

Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
---
 ms-queuedaemon |  191 +++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 121 insertions(+), 70 deletions(-)

diff --git a/ms-queuedaemon b/ms-queuedaemon
index 1aa526c..53ac655 100755
--- a/ms-queuedaemon
+++ b/ms-queuedaemon
@@ -21,6 +21,23 @@
 
 source ./tcl/daemonlib.tcl
 
+set walkers {plan}
+
+proc walker-globals {w} {
+    # introduces queue_running, thinking[_after] for the specific walker
+    foreach v {queue_running thinking thinking_after} {
+	uplevel 1 [list upvar $w/$v $v]
+    }
+}
+
+proc foreach-walker {walkervar body} {
+    global walkers
+    upvar 1 $walkervar w
+    foreach w $walkers {
+	uplevel 1 walker-globals $w
+	uplevel 1 $body
+    }
+}
 
 proc chan-destroy-stuff {chan} {
     dequeue-chan $chan destroy
@@ -31,13 +48,20 @@ proc chan-destroy-stuff {chan} {
 proc dequeue-chan {chan why} {
     log-event "dequeue-chan $chan $why"
 
-    global queue queue_running thinking
+    global queue
     lremove queue $chan
 
-    if {[info exists queue_running]} { lremove queue_running $chan }
-    if {[info exists thinking] &&
-        ![string compare $thinking $chan]} {
-        queuerun-step-done $why
+    foreach-walker w {
+	if {[info exists queue_running]} { lremove queue_running $chan }
+    }
+
+    # Reentrancy: this next loop can only trigger once, because
+    # the queuerun-step-done won't ever start chan thinking again
+    foreach-walker w {
+	if {[info exists thinking] &&
+	    ![string compare $thinking $chan]} {
+	    queuerun-step-done $w $why
+	}
     }
 }
 
@@ -55,31 +79,35 @@ proc log-event {m} {
 }
 
 proc log-state {m} {
-    global need_queue_run queue queue_running thinking
+    global need_queue_run queue
 
     set lhs [format "N=%d Q=%d (%-11.11s) " \
                  $need_queue_run [llength $queue] $queue]
 
-    if {[info exists queue_running]} {
-        append lhs [format "R=%d " [llength $queue_running]]
-        if {[info exists thinking]} {
-            append lhs [format "T=%s " $thinking]
-        } else {
-            append lhs [format "        "]
-        }
-        append lhs [format "(%-11.11s) " $queue_running]
-    } else {
-        append lhs "                          "
+    foreach-walker w {
+	if {[info exists queue_running]} {
+	    append lhs [format "R=%d " [llength $queue_running]]
+	    if {[info exists thinking]} {
+		append lhs [format "T=%s " $thinking]
+	    } else {
+		append lhs [format "        "]
+	    }
+	    append lhs [format "(%-11.11s) " $queue_running]
+	} else {
+	    append lhs "                          "
+	}
     }
+
     log "$lhs | $m"
 }
 
 #---------- machinery for making sure we run the queue ----------
 #
 # variables:
-#   queue            chans that are waiting for resources
-#   queue_running    unset if not running, list of chans if running
-#   need_queue_run   0: not needed; 1: needed if more resources; 2: force
+#  $w/queue            chans that are waiting for resources
+#  $w/queue_running    unset if not running, list of chans if running
+#  need_queue_run      0: not needed; 1: needed if more resources; 2: force
+# the $w/ variables are generally upvar'd with walker-globals
 
 proc runneeded-ensure-will {need} {
     global runneeded_holdoff_after c need_queue_run
@@ -96,7 +124,8 @@ proc runneeded-ensure-will {need} {
 
 proc runneeded-perhaps-start {} {
     log-event runneeded-perhaps-start
-    global queue queue_running thinking need_queue_run inhibit
+    walker-globals plan
+    global queue need_queue_run inhibit
     global runneeded_holdoff_after
     unset runneeded_holdoff_after
 
@@ -108,8 +137,8 @@ proc runneeded-perhaps-start {} {
     set need_queue_run 0
 
     if {![llength $queue]} {
-        plan-reset
-        report-plan
+        plan-reset plan
+        report-plan plan
         return
     }
 
@@ -140,7 +169,7 @@ proc runneeded-perhaps-start {} {
     log "runneeded-perhaps-start starting cleaned=$cleaned"
 
     runneeded-2-requeue
-    queuerun-start
+    queuerun-start plan
 }
 
 proc runneeded-ensure-polling {} {
@@ -181,26 +210,29 @@ proc runneeded-2-requeue {} {
 #---------- machinery for running the queue ----------
 #
 # variables:
-#    queue             chans waiting, read when we start
-#    queue_running     chans not yet asked
-#    thinking          chan currently asking
-#    thinking_after    timeout
+#  queue                chans waiting, read when we start
+#  $w/queue_running     chans not yet asked
+#  $w/thinking          chan currently asking
+#  $w/thinking_after    timeout
+# all the $w/ are generally upvar'd by walker-globals
 
-proc plan-reset {} {
-    exec ./ms-planner reset < /dev/null
+proc plan-reset {w} {
+    exec ./ms-planner -w$w reset < /dev/null
 }
 
-proc queuerun-start {} {
-    log-event queuerun-start
-    global queue_running queue
-    plan-reset
+proc queuerun-start {w} {
+    global queue
+    walker-globals $w
+    log-event "$w queuerun-start"
+    plan-reset $w
     set queue_running $queue
-    after idle queuerun-perhaps-step
+    after idle queuerun-perhaps-step plan
 }
 
-proc queuerun-perhaps-step {} {
-    log-event queuerun-perhaps-step
-    global thinking queue_running thinking_after c
+proc queuerun-perhaps-step {w} {
+    log-event "$w queuerun-perhaps-step"
+    walker-globals $w
+    global c
 
     if {[info exists thinking]} return
     if {![info exists queue_running]} return
@@ -208,107 +240,126 @@ proc queuerun-perhaps-step {} {
     if {![llength $queue_running]} {
         unset queue_running
         runneeded-ensure-will 0
-        report-plan
+        report-plan $w
         return
     }
 
-    set thinking [lshift queue_running]
-    log-event "queuerun-perhaps-step selected"
+    set next [lindex $queue_running 0]
+    set already [we-are-thinking $next]
+    if {[llength $already]} {
+	error "next $next thinking $already but also want $w"
+    }
+
+    set thinking $next
+    lshift queue_running
+    log-event "$w queuerun-perhaps-step selected"
 
     set thinking_after [after [expr {$c(QueueThoughtsTimeout) * 1000}] \
-                            queue-thoughts-timedout]
+                            queue-thoughts-timedout $w]
     for-chan $thinking {
         puts-chan $thinking "!OK think"
     }
 }
 
-proc report-plan {} {
+proc report-plan {w} {
     global c
     if {[catch {
-        exec ./ms-planner show-html > "$c(WebspaceFile)/resource-plan.html"
+	set outputfile "$c(WebspaceFile)/resource-$w.html"
+	exec ./ms-planner -w$w show-html > $outputfile
     } emsg]} {
-        log "INTERNAL ERROR showing plan html: $emsg"
+        log "INTERNAL ERROR showing $w html: $emsg"
     } else {
-        log "report-plan OK"
+        log "$w report-plan OK"
     }
 }
 
 proc we-are-thinking {chan} {
-    global thinking
-    return [expr {[info exists thinking] && ![string compare $thinking $chan]}]
+    set ws {}
+    foreach-walker w {
+	if {[info exists thinking] && ![string compare $thinking $chan]} {
+	    lappend ws $w
+	}
+    }
+    if {[llength $ws] > 1} {
+	error "arrgh chan $chan thinking $ws !"
+    }
+    return [lindex $ws 0]
 }
 
 proc check-we-are-thinking {chan} {
-    if {![we-are-thinking $chan]} {
+    set w [we-are-thinking $chan]
+    if {![string length $w]} {
         puts-chan $chan "ERROR you are not thinking"
         return -code return
     }
+    return $w
 }
 
-proc queuerun-step-done {why} {
-    log-event "queuerun-step-done $why"
-    global queue_running thinking thinking_after
-    puts-chan-desc $thinking "queuerun-step-done $thinking $why"
+proc queuerun-step-done {w why} {
+    log-event "$w queuerun-step-done $why"
+    walker-vars $w
+    puts-chan-desc $thinking "$w queuerun-step-done $thinking $why"
     if {[info exists thinking_after]} {
         after cancel $thinking_after
         unset thinking_after
     }
     unset thinking
-    after idle queuerun-perhaps-step
+    after idle queuerun-perhaps-step $w
 }
 
-proc queue-thoughts-timedout {} {
-    log-event queue-thoughts-timedout
-    global thinking thinking_after
+proc queue-thoughts-timedout {w} {
+    log-event "$w queue-thoughts-timedout"
+    walker-vars $w
     set chan $thinking
     unset thinking_after
-    queuerun-step-done timeout
+    queuerun-step-done $w timeout
     for-chan $chan {
         puts-chan $chan "!ERROR timed out (too pensive)"
     }
 }
 
 proc cmd/thought-wait {chan desc} {
-    check-we-are-thinking $chan
-    queuerun-step-done thought-wait
+    set w [check-we-are-thinking $chan]
+    queuerun-step-done $w thought-wait
     puts-chan $chan "OK thought"
 }
 
 proc cmd/thought-done {chan desc} {
-    check-we-are-thinking $chan
-    queuerun-step-done thought-done
+    set w [check-we-are-thinking $chan]
+    queuerun-step-done $w thought-done
     dequeue-chan $chan thought-wait
     puts-chan $chan "OK thought"
 }
 
 proc cmd/get-plan {chan desc} {
     global plan
-    set plan [exec -keepnewline ./ms-planner get-plan < /dev/null]
+    set w [check-we-are-thinking $chan]
+    set plan [exec -keepnewline ./ms-planner -w$w get-plan < /dev/null]
     puts-chan-data $chan "OK get-plan" $plan
 }
 
 proc cmd/book-resources {chan desc bytes} {
-    check-we-are-thinking $chan
-    read-chan-data $chan $bytes do-book-resources
+    read-chan-data $chan $bytes do-book-resources $w
 }
 proc do-book-resources {chan desc data} {
     global plan errorInfo
-    check-we-are-thinking $chan
+    set w [check-we-are-thinking $chan]
     set info [chan-get-info $chan {"$info(preinfo) "} ""]
     append info [chan-get-info $chan {"job $info(job)"} $desc]
     if {[catch {
-	exec ./ms-planner book-resources $info << $data
+	exec ./ms-planner -w$w book-resources $info << $data
     } emsg]} {
-	set f [exec ./ms-planner-debug $info $data $plan]
+	set f [exec ./ms-planner-debug -w$w $info $data $plan]
 	error "$f $emsg" $errorInfo
     }
     puts-chan $chan "OK book-resources"
 }
 
 proc cmd/unwait {chan desc} {
-    if {[we-are-thinking $chan]} {
-        queuerun-step-done unwait
-        set res cancel
+    set w [we-are-thinking $chan]
+    if {[string length $w]} {
+        queuerun-step-done $w unwait
+        set res "$w cancel"
     } else {
         set res noop
     }
-- 
1.7.10.4

  parent reply	other threads:[~2015-09-02 15:51 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-02 15:45 [OSSTEST RFC PATCH 00/13] Planner: Performance improvement Ian Jackson
2015-09-02 15:45 ` [OSSTEST PATCH 01/13] Tcl: Use lshift instead of open-coding with lrange Ian Jackson
2015-09-03 10:44   ` Ian Campbell
2015-09-03 10:50     ` Ian Jackson
2015-09-02 15:45 ` [OSSTEST PATCH 02/13] Planner: docs: Minor fixes Ian Jackson
2015-09-03 10:47   ` Ian Campbell
2015-09-03 12:04     ` Ian Jackson
2015-09-02 15:45 ` [OSSTEST PATCH 03/13] Planner: docs: Document set-info command Ian Jackson
2015-09-03 10:48   ` Ian Campbell
2015-09-02 15:45 ` [OSSTEST PATCH 04/13] Planner: Fix indefinite holdoff Ian Jackson
2015-09-03 10:51   ` Ian Campbell
2015-09-02 15:45 ` [OSSTEST PATCH 05/13] Planner: client side: $mayalloc parameter to $resourcecall->() Ian Jackson
2015-09-03 10:52   ` Ian Campbell
2015-09-02 15:45 ` [OSSTEST PATCH 06/13] Planner: client side: New `!OK think noalloc' protocol Ian Jackson
2015-09-03 10:53   ` Ian Campbell
2015-09-02 15:45 ` [OSSTEST PATCH 07/13] Planner: ms-planner support -w option Ian Jackson
2015-09-03 11:25   ` Ian Campbell
2015-09-02 15:45 ` Ian Jackson [this message]
2015-09-03 12:05   ` [OSSTEST PATCH 08/13] Planner: ms-queuedaemon: Prep for multiple walkers Ian Campbell
2015-09-03 15:42     ` Ian Jackson
2015-09-02 15:45 ` [OSSTEST PATCH 09/13] Planner: ms-queuedaemon: Synchronise thinking " Ian Jackson
2015-09-03 12:06   ` Ian Campbell
2015-09-02 15:45 ` [OSSTEST PATCH 10/13] Planner: ms-queuedaemon: Break out queuerun-finished/<walker> Ian Jackson
2015-09-03 12:43   ` Ian Campbell
2015-09-02 15:45 ` [OSSTEST PATCH 11/13] Planner: ms-queuedaemon: Break out notify-to-think Ian Jackson
2015-09-03 12:44   ` Ian Campbell
2015-09-02 15:45 ` [OSSTEST PATCH 12/13] Planner: ms-queuedaemon: Make report-plan take output walker name Ian Jackson
2015-09-03 12:44   ` Ian Campbell
2015-09-02 15:45 ` [OSSTEST PATCH 13/13] Planner: ms-queuedaemon: Restart planning when resources become free Ian Jackson
2015-09-03 12:59   ` Ian Campbell
2015-09-03 11:49 ` [OSSTEST PATCH 14/13] Planning reports: Break out return-plan-to-client Ian Jackson
2015-09-03 11:49   ` [OSSTEST PATCH 15/13] Plan reporting: Provide get-last-plan queuedaemon command Ian Jackson
2015-09-03 13:05     ` Ian Campbell
2015-09-03 15:51       ` Ian Jackson
2015-09-03 15:52         ` Ian Jackson
2015-09-03 16:12           ` Ian Campbell
2015-09-03 13:01   ` [OSSTEST PATCH 14/13] Planning reports: Break out return-plan-to-client Ian Campbell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1441208719-31336-9-git-send-email-ian.jackson@eu.citrix.com \
    --to=ian.jackson@eu.citrix.com \
    --cc=ian.campbell@citrix.com \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.