Mini Shell

Direktori : /usr/bin/
Upload File :
Current File : //usr/bin/ptaskset

#!/usr/libexec/platform-python -s
# -*- python -*-
# -*- coding: utf-8 -*-
#   Copyright (C) 2008 Red Hat Inc.
#
#   Arnaldo Carvalho de Melo <acme@redhat.com>
#
#   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.

from __future__ import print_function
import os
import schedutils
import sys


def usage():
    print('''ptaskset (python-schedutils)
usage: ptaskset [options] [mask | cpu-list] [pid | cmd [args...]]
set or get the affinity of a process

  -p, --pid                  operate on existing given pid
  -c, --cpu-list             display and specify cpus in list format
  -h, --help                 display this help''')

    return


def hexbitmask(l):
    hexbitmask = []
    bit = 0
    mask = 0
    nr_entries = 1 << max(l)
    for entry in range(nr_entries):
        if entry in l:
            mask |= (1 << bit)
        bit += 1
        if bit == 32:
            bit = 0
            hexbitmask.insert(0, mask)
            mask = 0

    if bit < 32 and mask != 0:
        hexbitmask.insert(0, mask)

    return hexbitmask


def find_last_bit(n, wordsize=32):
    bit = wordsize - 1
    while bit != 0:
        if n & (1 << bit):
            return bit
        bit -= 1
    return 0


def bitmasklist(line):
    fields = line.strip().split(",")
    bitmasklist = []
    while int(fields[0], 16) == 0:
        fields.pop(0)

    if not fields:
        return []

    nr_entries = (len(fields) - 1) * 32 + find_last_bit(int(fields[0], 16)) + 1

    entry = 0
    for i in range(len(fields) - 1, -1, -1):
        mask = int(fields[i], 16)
        while mask != 0:
            if mask & 1:
                bitmasklist.append(entry)
            mask >>= 1
            entry += 1
            if entry == nr_entries:
                break
        if entry == nr_entries:
            break
    return bitmasklist


def cpustring_to_list(cpustr):
    """Convert a string of numbers to an integer list.

    Given a string of comma-separated numbers and number ranges,
    return a simple sorted list of the integers it represents.

    This function will throw exceptions for badly-formatted strings.

    Returns a list of integers."""

    fields = cpustr.strip().split(",")
    cpu_list = []
    for field in fields:
        ends = field.split("-")
        if len(ends) > 2:
            raise "Syntax error"
        if len(ends) == 2:
            cpu_list += list(range(int(ends[0]), int(ends[1]) + 1))
        else:
            cpu_list += [int(ends[0])]
    return list(set(cpu_list))


def show_settings(pid, when, cpu_list_mode):
    affinity = schedutils.get_affinity(pid)
    if cpu_list_mode:
        mask = ",".join([str(a) for a in affinity])
    else:
        mask = ",".join(["%x" % a for a in hexbitmask(affinity)])
    print("pid %d's %s affinity mask: %s" % (pid, when, mask))


def change_settings(pid, affinity, cpu_list_mode):
    if cpu_list_mode:
        try:
            affinity = [int(a) for a in affinity.split(",")]
        except:
            affinity = cpustring_to_list(affinity)
    else:
        affinity = bitmasklist(affinity)

    try:
        schedutils.set_affinity(pid, affinity)
    except SystemError as err:
        print("sched_setaffinity: %s" % err[1])
        print("failed to set pid %d's affinity" % pid)


def main():

    args = sys.argv[1:]
    if not args:
        usage()
        return

    cpu_list_mode = False
    while True:
        o = args.pop(0)

        if o in ("-h", "--help"):
            usage()
            return
        elif o in ("-c", "--cpu-list"):
            cpu_list_mode = True
        elif o in ("-p", "--pid"):
            if len(args) > 1:
                affinity = args.pop(0)
                pid = int(args.pop(0))
                show_settings(pid, "current", cpu_list_mode)
                change_settings(pid, affinity, cpu_list_mode)
                show_settings(pid, "new", cpu_list_mode)
            else:
                pid = int(args.pop(0))
                show_settings(pid, "current", cpu_list_mode)
            return
        else:
            break

    affinity = o
    change_settings(0, affinity, cpu_list_mode)
    os.execvp(args[0], args)


if __name__ == '__main__':
    main()

Zerion Mini Shell 1.0