summaryrefslogtreecommitdiffstats
path: root/tapset/queue_stats.stp
blob: f2fd8dc6acd67ad531a2f33b0fcc1d4b9a24fa74 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# qstats.stp: Queue statistics gathering tapset

# ------------------------------------------------------------------------

# The default timing function: microseconds.  This function could
# go into a separate file (say, qstats_qs_time.stp), so that a user
# script can override it with another definition.

function qs_time () { return gettimeofday_us () }

# ------------------------------------------------------------------------

global qs_wtime, qs_wlentime, qs_wcount
global qs_rtime, qs_rlentime, qs_rcount
global qs_stime, qs_utime, qs_dcount

# ------------------------------------------------------------------------

function _qs_update (qname) {
  now = qs_time ()
  then = qs_utime[qname]; if (! then) { then = now }
  delta = now-then

  qs_wtime[qname] += qs_wcount[qname] ? delta : 0
  qs_wlentime[qname] += qs_wcount[qname] * delta
  qs_rtime[qname] += qs_rcount[qname] ? delta : 0
  qs_rlentime[qname] += qs_rcount[qname] * delta
  qs_utime[qname] = now  
}

function qs_wait (qname) { # enqueueing request
   _qs_update (qname)
   qs_wcount[qname] ++
}

function qs_run (qname) { # starting to service request
  _qs_update (qname)
  if (qs_wcount[qname] > 0) {
    qs_wcount[qname] --
    qs_rcount[qname] ++
  }
}

function qs_done (qname) { # done servicing request
  _qs_update (qname)
  if (qs_rcount[qname] > 0) {
    qs_rcount[qname] --
    qs_dcount[qname] ++
  }
}

# ------------------------------------------------------------------------

function qsq_start (qname) {  # reset statistics for new baseline
  qs_rcount[qname] = 0
  delete qs_rtime[qname]
  delete qs_rlentime[qname]
  qs_wcount[qname] = 0
  delete qs_wtime[qname]
  delete qs_wlentime[qname]
  delete qs_dcount[qname]
  delete qs_utime[qname]
  qs_stime[qname] = qs_time ()
}

# ------------------------------------------------------------------------
# Various query functions.  Each returns the average, taken over the time
# interval from the last qsq_start().  Most deal with fractions, and so
# also take a scale parameter (use 100 for percent).

# fraction of time that any request was being serviced
function qsq_utilization (qname, scale) {
  _qs_update (qname)
  elapsed = qs_time() - qs_stime[qname]
  return (scale * qs_rtime[qname]) / elapsed
}

# fraction of time that any request was blocked in the wait queue
function qsq_blocked (qname, scale) {
  _qs_update (qname)
  elapsed = qs_time() - qs_stime[qname]
  return (scale * qs_wtime[qname]) / elapsed
}

# length of wait queue 
function qsq_wait_queue_length (qname, scale) {
  _qs_update (qname)
  elapsed = qs_time() - qs_stime[qname]
  return (scale * qs_wlentime[qname]) / elapsed
}

# service time (amount of time per request service)
function qsq_service_time (qname, scale) {
  _qs_update (qname)
  return (scale * qs_rlentime[qname]) / qs_dcount[qname]
}

# wait time (amount of time in queue + service per request)
function qsq_wait_time (qname, scale) {
  _qs_update (qname)
  return (scale * (qs_rlentime[qname] + qs_wlentime[qname]))
    / qs_dcount[qname]
}

# service rate (number of requests served per unit time)
function qsq_throughput (qname, scale) {
  _qs_update (qname)
  elapsed = qs_time() - qs_stime[qname]
  return (scale * qs_dcount[qname]) / elapsed
}


# ------------------------------------------------------------------------

function qsq_print (qname) {
  qt = qsq_throughput (qname, 1000000000) # 1000 * (number of requests served per second)
  qwl = qsq_wait_queue_length (qname, 1000)
  printf("%s: %d.%03d ops/s, %d.%03d qlen, %d await, %d svctm, %d%% wait, %d%% util\n",
    qname,
    qt/1000, qt%1000,
    qwl/1000, qwl%1000,
    qsq_wait_time (qname, 1),
    qsq_service_time (qname, 1),
    qsq_blocked (qname, 100),
    qsq_utilization (qname, 100))
}