blob: 7d5b296c07520477e36ef10fdfa9fb3f4e64149e [file] [log] [blame]
#! /usr/bin/python
# -*- python -*-
# -*- coding: utf-8 -*-
# tuna - Application Tuning Gru
# Copyright (C) 2008 Red Hat Inc.
#
# This application is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; version 2.
#
# This application is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
import getopt, procfs, sys
from tuna import tuna
try:
from sets import Set as set
except:
# OK, we're modern, having sets as first class citizens
pass
# FIXME: ETOOMANYGLOBALS, we need a class!
nr_cpus = None
ps = None
def usage():
print '''Usage: tuna [OPTIONS]
-h, --help Give this help list
-g, --gui Start the GUI
-c, --cpus=CPU-LIST CPU-LIST affected by commands
-C, --affect_children Operation will affect children threads
-f, --filter Display filter the selected entities
-i, --isolate Move all threads away from CPU-LIST
-I, --include Allow all threads to run on CPU-LIST
-K, --no_kthreads Operations will not affect kernel threads
-m, --move move selected entities to CPU-LIST
-p, --priority=[POLICY]:RTPRIO set thread scheduler POLICY and RTPRIO
-s, --save=FILENAME save kthreads sched tunables to FILENAME
-t, --threads=THREAD-LIST THREAD-LIST affected by commands
-U, --no_uthreads Operations will not affect user threads
-W, --what_is Provides help about selected entities'''
def get_nr_cpus():
global nr_cpus
if nr_cpus:
return nr_cpus
nr_cpus = procfs.cpuinfo().nr_cpus
return nr_cpus
def thread_help(tid):
global ps
if not ps:
ps = procfs.pidstats()
if not ps.has_key(tid):
print "tuna: thread %d doesn't exists!" % tid
return
pinfo = ps[tid]
cmdline = procfs.process_cmdline(pinfo)
help, title = tuna.kthread_help_plain_text(tid, cmdline)
print "%s\n\n%s" % (title, help)
def save(cpus, threads, filename):
kthreads = tuna.get_kthread_sched_tunings()
for name in kthreads.keys():
kt = kthreads[name]
if (cpus and not set(kt.affinity).intersection(set(cpus))) or \
(threads and kt.pid not in threads) :
del kthreads[name]
tuna.generate_rtgroups(filename, kthreads)
def main():
try:
opts, args = getopt.getopt(sys.argv[1:],
"c:CfghiIKmp:s:t:UW",
("cpus=", "affect_children",
"filter", "gui", "help",
"isolate", "include",
"no_kthreads",
"move", "priority",
"save=", "threads=",
"no_uthreads", "what_is"))
except getopt.GetoptError, err:
usage()
print str(err)
sys.exit(2)
run_gui = not opts
kthreads = True
uthreads = True
cpus = None
threads = None
filter = False
affect_children = False
for o, a in opts:
if o in ("-h", "--help"):
usage()
return
elif o in ("-c", "--cpus"):
cpus = map(lambda cpu: int(cpu), a.split(","))
elif o in ("-C", "--affect_children"):
affect_children = True
elif o in ("-t", "--threads"):
threads = map(lambda cpu: int(cpu), a.split(","))
elif o in ("-f", "--filter"):
filter = True
elif o in ("-g", "--gui"):
run_gui = True
elif o in ("-i", "--isolate"):
if not cpus:
print "tuna: --isolate requires a cpu list!"
sys.exit(2)
tuna.isolate_cpus(cpus, get_nr_cpus())
elif o in ("-I", "--include"):
if not cpus:
print "tuna: --include requires a cpu list!"
sys.exit(2)
for cpu in cpus:
tuna.include_cpu(cpu, get_nr_cpus())
elif o in ("-p", "--priority"):
tuna.threads_set_priority(threads, a, affect_children)
elif o in ("-m", "--move"):
if not cpus:
print "tuna: --move requires a cpu list!"
sys.exit(2)
if not threads:
print "tuna: --move requires a thread list!"
sys.exit(2)
tuna.move_threads_to_cpu(cpus, threads)
elif o in ("-s", "--save"):
save(cpus, threads, a)
elif o in ("-K", "--no_kthreads"):
kthreads = False
elif o in ("-U", "--no_uthreads"):
uthreads = False
elif o in ("-W", "--what_is"):
if not threads:
print "tuna: --what_is requires a thread list!"
sys.exit(2)
for tid in threads:
thread_help(tid)
if run_gui:
try:
from tuna import tuna_gui
except ImportError:
# gui packages not installed
usage()
return
try:
cpus_filtered = filter and cpus or []
app = tuna_gui.gui(kthreads, uthreads, cpus_filtered)
app.run()
except KeyboardInterrupt:
pass
if __name__ == '__main__':
main()