-
Notifications
You must be signed in to change notification settings - Fork 107
/
Copy pathswapview.ss
executable file
·78 lines (69 loc) · 2.61 KB
/
swapview.ss
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
(import (chezscheme))
(define-record process-info (pid swap-usage command-line))
(define (filesize size)
(let lp ((units '(B KiB MiB GiB TiB))
(size size))
(if (and (> size 1100) (not (null? units)))
(lp (cdr units) (/ size 1024))
(if (eq? (car units) 'B)
(format #f "~dB" (inexact->exact size))
(format #f "~,1f~a" size (car units))))))
(define-syntax try
(syntax-rules (catch)
((_ body (catch catcher))
(call-with-current-continuation
(lambda (exit)
(with-exception-handler
(lambda (condition)
(exit catcher))
(lambda () body)))))))
(define (get-command-line pid)
(let* [(port (open-input-file (format #f "/proc/~a/cmdline" pid)))
(raw-commandline (get-string-all port))
(raw (if (eof-object? raw-commandline) "" raw-commandline))
(len (- (string-length raw) 1))
(_ (if (char=? (string-ref raw len) #\nul)
(string-truncate! raw len)))]
(list->string
(map (lambda (x) (if (char=? x #\nul) #\space x))
(string->list raw)))))
(define (find-number str)
(list->string
(filter (lambda (x) (and (char>=? x #\0) (char<=? x #\9)))
(string->list str))))
(define (getSwapFor pid)
(try
(let ((smaps (open-input-file (format #f "/proc/~a/smaps" pid))))
(let lp ((size 0)
(line (get-line smaps)))
(cond ((eof-object? line)
(close-input-port smaps)
(and (not (zero? size))
(make-process-info
pid (* 1024 size) (get-command-line pid))))
(else
(lp (if (string=? (substring line 0 5) "Swap:")
(+ size (string->number (find-number line)))
size)
(get-line smaps))))))
(catch #f)))
(define (getSwap)
(sort (lambda (a b) (< (process-info-swap-usage a) (process-info-swap-usage b)))
(filter (lambda (x) (and x (> (process-info-swap-usage x) 0)))
(map (lambda (x) (and (string->number x) (getSwapFor x)))
(directory-list "/proc")))))
(define (main)
(let ([FORMATSTR "~7@a ~9@a ~@a~%"]
[total 0.0])
(format #t FORMATSTR "PID" "SWAP" "COMMAND")
(for-each
(lambda (item)
(begin
(set! total (+ total (process-info-swap-usage item)))
(format #t FORMATSTR
(process-info-pid item)
(filesize (process-info-swap-usage item))
(process-info-command-line item))))
(getSwap))
(format #t "Total: ~10@a~%" (filesize total))))
(main)