Patch title: Release 93 bulk changes
Abstract:
File: /linux/kernel/statistics.pli
Key:
    Removed line
    Added line
   
module "/pliant/language/compiler.pli"
module "/pliant/language/context.pli"
module "/pliant/language/stream.pli"
module "/pliant/language/schedule/daemon.pli"
module "/pliant/language/compiler.pli"
module "/pliant/language/context.pli"
module "/pliant/language/stream.pli"
module "/pliant/language/schedule/daemon.pli"
module "/pliant/fullpliant/this_computer.pli"

constant resolution 5 # in reconds

constant resolution 5 # in reconds
constant logical this_computer:env:"pliant":"system":"medium"="logical"


if not logical


type KernelStatRecord
  field DateTime timestamp
  field (Dictionary Str Intn) net_in net_out
  field (Dictionary Str Intn) disk_read disk_write
  field Intn interrupts
  field Intn cpu


gvar Sem sem
gvar DateTime last_timestamp
gvar (Dictionary Str uInt) net_in_mark net_out_mark
gvar (Dictionary Str Intn) net_in_total net_out_total
gvar (Dictionary Str uInt) disk_read_mark disk_write_mark
gvar (Dictionary Str Intn) disk_read_total disk_write_total
gvar uInt interrupts_mark := 0
gvar Intn interrupts_total := 0
gvar Intn cpu_total := 0
gvar List:KernelStatRecord stat


function pick_net_marks in_mark out_mark
  arg_w (Dictionary Str uInt) in_mark out_mark
  in_mark := var (Dictionary Str uInt) empty_dictionary ; ou
  (var Stream proc) open "file:/proc/net/dev" in+safe
  while not proc:atend
    if (proc:readline parse any:(var Str device) ":" (var uI
      in_mark insert device r_bytes ; out_mark insert device

function pick_disk_marks read_mark write_mark interrupts
  arg_w (Dictionary Str uInt) read_mark write_mark ; arg_w u
  read_mark := var (Dictionary Str uInt) empty_dictionary ; 
  interrupts := 0
  (var Stream proc) open "file:/proc/stat" in+safe
  while not proc:atend
    var Str l := proc readline
    if (l parse word:"disk_io" ":" any:(var Str disks))
      while (disks parse "(" any:(var Str disk) ")" ":" "(" 
  type KernelStatRecord
    field DateTime timestamp
    field (Dictionary Str Intn) net_in net_out
    field (Dictionary Str Intn) disk_read disk_write
    field Intn interrupts
    field Intn cpu
  
  
  gvar Sem sem
  gvar DateTime last_timestamp
  gvar (Dictionary Str uInt) net_in_mark net_out_mark
  gvar (Dictionary Str Intn) net_in_total net_out_total
  gvar (Dictionary Str uInt) disk_read_mark disk_write_mark
  gvar (Dictionary Str Intn) disk_read_total disk_write_total
  gvar uInt interrupts_mark := 0
  gvar Intn interrupts_total := 0
  gvar Intn cpu_total := 0
  gvar List:KernelStatRecord stat
  
  
  function pick_net_marks in_mark out_mark
    arg_w (Dictionary Str uInt) in_mark out_mark
    in_mark := var (Dictionary Str uInt) empty_dictionary ; out_mark := var (Dictionary Str uInt) empty_dictionary
    (var Stream proc) open "file:/proc/net/dev" in+safe
    while not proc:atend
      if (proc:readline parse any:(var Str device) ":" (var uInt r_bytes) (var uInt r_packets) (var uInt r_err) (var uInt r_drop) (var uInt r_fifo) (var uInt r_frame) (var uInt r_compressed) (var uInt r_multicast) (var uInt t_bytes) (var uInt t_packets) (var uInt t_err) (var uInt t_drop) (var uInt t_fifo) (var uInt t_colls) (var uInt t_carrier) (var uInt t_compressed))
        in_mark insert device r_bytes ; out_mark insert device t_bytes
  
  function pick_disk_marks read_mark write_mark interrupts
    arg_w (Dictionary Str uInt) read_mark write_mark ; arg_w uInt interrupts
    read_mark := var (Dictionary Str uInt) empty_dictionary ; write_mark := var (Dictionary Str uInt) empty_dictionary
    interrupts := 0
    (var Stream proc) open "file:/proc/stat" in+safe
    while not proc:atend
      var Str l := proc readline
      if (l parse word:"disk_io" ":" any:(var Str disks))
        while (disks parse "(" any:(var Str disk) ")" ":" "(" (var uInt nb_rw) "," (var uInt nb_read) "," (var uInt sec_read) "," (var uInt nb_write) "," (var uInt sec_write) ")" any:(var Str remain))
          read_mark insert disk sec_read ; write_mark insert disk sec_write
          disks := remain
      eif (l parse word:"intr" interrupts any)
        void
    (var Stream proc) open "file:/proc/diskstats" in+safe
    while not proc:atend
      var Str l := proc readline
      if (l parse (var Int major) (var Int minor) _ any:(var Str disk) _ (var uInt nb_read) (var uInt sec_read) (var uInt nb_write)  (var uInt sec_write))
        read_mark insert disk sec_read ; write_mark insert d
        read_mark insert disk sec_read ; write_mark insert d
        disks := remain
    eif (l parse word:"intr" interrupts any)
      void
  (var Stream proc) open "file:/proc/diskstats" in+safe
  while not proc:atend
    var Str l := proc readline
    if (l parse (var Int major) (var Int minor) _ any:(var S
      read_mark insert disk sec_read ; write_mark insert dis

function pick_cpu_load load
  arg_w Float load
  (var Stream proc) open "file:/proc/loadavg" in+safe
  if (proc:readline parse (var Float l1) (var Float l2) (var
    load := l1
  else
    load := 0

function add_stat_record
  pick_net_marks (var (Dictionary Str uInt) net_in) (var (Di
  each m net_in
    var Str d := net_in key m
    net_in_total d 0 += m .-. (net_in_mark d 0)
    net_in_mark d := m
  each m net_out
    var Str d := net_out key m
    net_out_total d 0 += m .-. (net_out_mark d 0)
    net_out_mark d := m
  pick_disk_marks (var (Dictionary Str uInt) disk_read) (var
  each m disk_read
    var Str d := disk_read key m
    disk_read_total d 0 += m .-. (disk_read_mark d 0)
    disk_read_mark d := m
  each m disk_write
    var Str d := disk_write key m
    disk_write_total d 0 += m .-. (disk_write_mark d 0)
    disk_write_mark d := m
  interrupts_total += interrupts .-. interrupts_mark
  interrupts_mark := interrupts
  pick_cpu_load (var Float load)
  var DateTime now := datetime
  var Int sec := cast now:seconds-last_timestamp:seconds Int
  cpu_total += cast sec*load*1000 Int
  last_timestamp := now
  var Link:KernelStatRecord r :> new KernelStatRecord
  r timestamp := now
  r net_in := net_in_total ; r net_out := net_out_total
  r disk_read := disk_read_total ; r disk_write := disk_writ
  r interrupts := interrupts_total
  r cpu := cpu_total
  sem request
  stat += r
  sem release


function filter_stat_records
  var DateTime now := datetime  
  sem request
  var Float mini := resolution
  var Pointer:KernelStatRecord r :> stat last
  while { var Pointer:KernelStatRecord r2 :> stat previous r
    if now:seconds-r2:timestamp:seconds<mini
      stat remove r
  
  function pick_cpu_load load
    arg_w Float load
    (var Stream proc) open "file:/proc/loadavg" in+safe
    if (proc:readline parse (var Float l1) (var Float l2) (var Float l3) any)
      load := l1
    else
    else
      mini := 1.25*mini
    r :> r2
  sem release
 

function gather_statistics
  daemon "gather Linux kernel statistics"
    pick_net_marks net_in_mark net_out_mark
    net_in_total := var (Dictionary Str Intn) empty_dict ; n
    last_timestamp := datetime
    stat := var List:KernelStatRecord empty_list
    add_stat_record
    var Int lap := 0
    while not daemon_emergency
      daemon_sleep resolution
      load := 0
  
  function add_stat_record
    pick_net_marks (var (Dictionary Str uInt) net_in) (var (Dictionary Str uInt) net_out)
    each m net_in
      var Str d := net_in key m
      net_in_total d 0 += m .-. (net_in_mark d 0)
      net_in_mark d := m
    each m net_out
      var Str d := net_out key m
      net_out_total d 0 += m .-. (net_out_mark d 0)
      net_out_mark d := m
    pick_disk_marks (var (Dictionary Str uInt) disk_read) (var (Dictionary Str uInt) disk_write) (var uInt interrupts)
    each m disk_read
      var Str d := disk_read key m
      disk_read_total d 0 += m .-. (disk_read_mark d 0)
      disk_read_mark d := m
    each m disk_write
      var Str d := disk_write key m
      disk_write_total d 0 += m .-. (disk_write_mark d 0)
      disk_write_mark d := m
    interrupts_total += interrupts .-. interrupts_mark
    interrupts_mark := interrupts
    pick_cpu_load (var Float load)
    var DateTime now := datetime
    var Int sec := cast now:seconds-last_timestamp:seconds Int
    cpu_total += cast sec*load*1000 Int
    last_timestamp := now
    var Link:KernelStatRecord r :> new KernelStatRecord
    r timestamp := now
    r net_in := net_in_total ; r net_out := net_out_total
    r disk_read := disk_read_total ; r disk_write := disk_write_total
    r interrupts := interrupts_total
    r cpu := cpu_total
    sem request
    stat += r
    sem release
  
  
  function filter_stat_records
    var DateTime now := datetime  
    sem request
    var Float mini := resolution
    var Pointer:KernelStatRecord r :> stat last
    while { var Pointer:KernelStatRecord r2 :> stat previous r ; exists:r2 }
      if now:seconds-r2:timestamp:seconds<mini
        stat remove r
      else
        mini := 1.25*mini
      r :> r2
    sem release
   
  
  function gather_statistics
    daemon "gather Linux kernel statistics"
      pick_net_marks net_in_mark net_out_mark
      net_in_total := var (Dictionary Str Intn) empty_dict ; net_out_total := var (Dictionary Str Intn) empty_dict ; cpu_total := 0
      last_timestamp := datetime
      stat := var List:KernelStatRecord empty_list
      add_stat_record
      add_stat_record
      lap += 1
      if lap%6=0
        filter_stat_records
gather_statistics
      var Int lap := 0
      while not daemon_emergency
        daemon_sleep resolution
        add_stat_record
        lap += 1
        if lap%6=0
          filter_stat_records
  gather_statistics


else


  module "/pliant/util/encoding/http.pli"


function net_devices -> devices
  arg List:Str devices
  devices := var List:Str empty_list
function net_devices -> devices
  arg List:Str devices
  devices := var List:Str empty_list
  each c net_in_total
    devices += net_in_total key c
  if not logical
    each c net_in_total
      devices += net_in_total key c

function net_statistics device seconds in_bps out_bps
  arg Str device ; arg Float seconds ; arg_w Float in_bps ou

function net_statistics device seconds in_bps out_bps
  arg Str device ; arg Float seconds ; arg_w Float in_bps ou
  sem rd_request
  var Pointer:KernelStatRecord last :> stat last
  var Pointer:KernelStatRecord r :> last
  while last:timestamp:seconds-r:timestamp:seconds<seconds a
    r :> stat previous r
  var Float sec := last:timestamp:seconds-r:timestamp:second
  if sec<1
    sec := 1
  if device<>""
    in_bps := (cast (last:net_in first device 0)-(r:net_in f
    out_bps := (cast (last:net_out first device 0)-(r:net_ou
  if not logical
    sem rd_request
    var Pointer:KernelStatRecord last :> stat last
    var Pointer:KernelStatRecord r :> last
    while last:timestamp:seconds-r:timestamp:seconds<seconds and exists:(stat previous r)
      r :> stat previous r
    var Float sec := last:timestamp:seconds-r:timestamp:seconds
    if sec<1
      sec := 1
    if device<>""
      in_bps := (cast (last:net_in first device 0)-(r:net_in first device 0) Float)*8/sec
      out_bps := (cast (last:net_out first device 0)-(r:net_out first device 0) Float)*8/sec
    else
      in_bps := 0
      each c last:net_in
        var Str d := last:net_in key c
        if d<>"lo"
          in_bps += (cast (last:net_in first d 0)-(r:net_in first d 0) Float)*8/sec
      out_bps := 0
      each c last:net_out
        var Str d := last:net_out key c
        if d<>"lo"
          out_bps += (cast (last:net_out first d 0)-(r:net_out first d 0) Float)*8/sec
    sem rd_release
  else
  else
    in_bps := 0
    each c last:net_in
      var Str d := last:net_in key c
      if d<>"lo"
        in_bps += (cast (last:net_in first d 0)-(r:net_in fi
    out_bps := 0
    each c last:net_out
      var Str d := last:net_out key c
      if d<>"lo"
        out_bps += (cast (last:net_out first d 0)-(r:net_out
  sem rd_release
    (var Stream s) open "tcp://127.0.0.1/client/80" in+out+safe
    s writeline "REPORT_LOAD_STATISTICS "+(http_encode "net "+string:device+" "+string:seconds)+" HTTP/1.1"
    s writeline ""
    if not (s:readline parse any "net" (var Str adevice) (var Float aseconds) in_bps out_bps)
      in_bps := undefined ; out_bps := undefined


function disk_devices -> devices
  arg List:Str devices
  devices := var List:Str empty_list


function disk_devices -> devices
  arg List:Str devices
  devices := var List:Str empty_list
  each c disk_read_total
    devices += disk_read_total key c
  if not logical
    each c disk_read_total
      devices += disk_read_total key c

function disk_statistics device seconds read_bps write_bps
  arg Str device ; arg Float seconds ; arg_w Float read_bps 

function disk_statistics device seconds read_bps write_bps
  arg Str device ; arg Float seconds ; arg_w Float read_bps 
  sem rd_request
  var Pointer:KernelStatRecord last :> stat last
  var Pointer:KernelStatRecord r :> last
  while last:timestamp:seconds-r:timestamp:seconds<seconds a
    r :> stat previous r
  var Float sec := last:timestamp:seconds-r:timestamp:second
  if sec<1
    sec := 1
  if device<>""
    read_bps := (cast (last:disk_read first device 0)-(r:dis
    write_bps := (cast (last:disk_write first device 0)-(r:d
  if not logical
    sem rd_request
    var Pointer:KernelStatRecord last :> stat last
    var Pointer:KernelStatRecord r :> last
    while last:timestamp:seconds-r:timestamp:seconds<seconds and exists:(stat previous r)
      r :> stat previous r
    var Float sec := last:timestamp:seconds-r:timestamp:seconds
    if sec<1
      sec := 1
    if device<>""
      read_bps := (cast (last:disk_read first device 0)-(r:disk_read first device 0) Float)*512*8/sec
      write_bps := (cast (last:disk_write first device 0)-(r:disk_write first device 0) Float)*512*8/sec
    else
      read_bps := 0
      each c last:disk_read
        var Str d := last:disk_read key c
        read_bps += (cast (last:disk_read first d 0)-(r:disk_read first d 0) Float)*512*8/sec
      write_bps := 0
      each c last:disk_write
        var Str d := last:disk_write key c
        write_bps += (cast (last:disk_write first d 0)-(r:disk_write first d 0) Float)*512*8/sec
    sem rd_release
  else
  else
    read_bps := 0
    each c last:disk_read
      var Str d := last:disk_read key c
      read_bps += (cast (last:disk_read first d 0)-(r:disk_r
    write_bps := 0
    each c last:disk_write
      var Str d := last:disk_write key c
      write_bps += (cast (last:disk_write first d 0)-(r:disk
  sem rd_release
    (var Stream s) open "tcp://127.0.0.1/client/80" in+out+safe
    s writeline "REPORT_LOAD_STATISTICS "+(http_encode "disk "+string:device+" "+string:seconds)+" HTTP/1.1"
    s writeline ""
    if not (s:readline parse any "disk" (var Str adevice) (var Float aseconds) read_bps write_bps)
      read_bps := undefined ; write_bps := undefined


function interrupts_statistics seconds -> ips
  arg Float seconds ; arg Float ips


function interrupts_statistics seconds -> ips
  arg Float seconds ; arg Float ips
  sem rd_request
  var Pointer:KernelStatRecord last :> stat last
  var Pointer:KernelStatRecord r :> last
  while last:timestamp:seconds-r:timestamp:seconds<seconds a
    r :> stat previous r
  var Float sec := last:timestamp:seconds-r:timestamp:second
  if sec<1
    sec := 1
  ips := (cast last:interrupts-r:interrupts Float)/sec
  sem rd_release
  if not logical
    sem rd_request
    var Pointer:KernelStatRecord last :> stat last
    var Pointer:KernelStatRecord r :> last
    while last:timestamp:seconds-r:timestamp:seconds<seconds and exists:(stat previous r)
      r :> stat previous r
    var Float sec := last:timestamp:seconds-r:timestamp:seconds
    if sec<1
      sec := 1
    ips := (cast last:interrupts-r:interrupts Float)/sec
    sem rd_release
  else
    (var Stream s) open "tcp://127.0.0.1/client/80" in+out+safe
    s writeline "REPORT_LOAD_STATISTICS "+(http_encode "interrupts "+string:seconds)+" HTTP/1.1"
    s writeline ""
    if not (s:readline parse any "interrupts" (var Float aseconds) ips)
      ips := undefined



function cpu_statistics seconds -> load
  arg Float seconds ; arg Float load
function cpu_statistics seconds -> load
  arg Float seconds ; arg Float load
  sem rd_request
  var Pointer:KernelStatRecord last :> stat last
  var Pointer:KernelStatRecord r :> last
  while last:timestamp:seconds-r:timestamp:seconds<seconds a
    r :> stat previous r
  var Float sec := last:timestamp:seconds-r:timestamp:second
  if sec<1
    sec := 1
  load := (cast last:cpu-r:cpu Float)/1000/sec
  sem rd_release
  if not logical
    sem rd_request
    var Pointer:KernelStatRecord last :> stat last
    var Pointer:KernelStatRecord r :> last
    while last:timestamp:seconds-r:timestamp:seconds<seconds and exists:(stat previous r)
      r :> stat previous r
    var Float sec := last:timestamp:seconds-r:timestamp:seconds
    if sec<1
      sec := 1
    load := (cast last:cpu-r:cpu Float)/1000/sec
    sem rd_release
  else
    (var Stream s) open "tcp://127.0.0.1/client/80" in+out+safe
    s writeline "REPORT_LOAD_STATISTICS "+(http_encode "cpu "+string:seconds)+" HTTP/1.1"
    s writeline ""
    if not (s:readline parse any "cpu" (var Float aseconds) load)
      load := undefined



export net_devices net_statistics
export disk_devices disk_statistics
export interrupts_statistics cpu_statistics

export net_devices net_statistics
export disk_devices disk_statistics
export interrupts_statistics cpu_statistics