My only comment is that the two /usr/bin scripts (pchrt and ptaskset) have a python2 shebang and so would have to be aliased with 'python3 /usr/bin/pchrt' e.g. to /usr/bin/pchrt3 to make them run with python3. We could also package them as pchrt3 and ptaskset3 with the python3 shebang and install them with python3-schedutils (so they do not conflict with the python2 versions).

On Wed, Nov 15, 2017 at 6:00 AM, Jiri Kastner <jkastner@redhat.com> wrote:
looks good, i'll push it soon
[root@localhost ~]# rpm -q python{2,}-{schedutils,linux-procfs}
python2-schedutils-0.5-6.fc27.x86_64
python2-linux-procfs-0.4.10-5.fc27.noarch
package python-schedutils is not installed
package python-linux-procfs is not installed
[root@localhost ~]# tuna -CP | tail -10
  30076  OTHER     0  0,1,2,3         1            0           gmain
  30077  OTHER     0  0,1,2,3        70            0           gdbus
 30152   OTHER     0  0,1,2,3       329            1            bash
 30626   OTHER     0  0,1,2,3        42            6  gvfsd-metadata
  30627  OTHER     0  0,1,2,3         1            0           gmain
  30628  OTHER     0  0,1,2,3        43            0           gdbus
 31956   OTHER     0  0,1,2,3       866            5            bash
 32018   OTHER     0  0,1,2,3      4125           63            bash
 32339   OTHER     0  0,1,2,3        48            0            bash
 32400   OTHER     0  0,1,2,3     10227          181            mutt
[root@localhost ~]# pchrt -p 1027
pid 1027's current scheduling policy: SCHED_FIFO
pid 1027's current scheduling priority: 50
[root@localhost ~]# rpm -qf $(which pchrt)
python3-schedutils-0.5-6.fc27.x86_64
[root@localhost ~]# ptaskset -p 1027
pid 1027's current affinity mask: f
[root@localhost ~]# ptaskset -c -p 1027
pid 1027's current affinity mask: 0,1,2,3
[root@localhost ~]# rpm -qf $(which ptaskset)
python3-schedutils-0.5-6.fc27.x86_64


On Fri, 10 Nov 2017 14:05:39 +0100, Lumir Balhar wrote:

> Hello.
>
> I've ported another Tuna/Tuned dependency to Python 3 compatible form -
> python-schedutils. I've tested it in epel 6 and fedora 28 mock and
> everything looks good to me.
>
> Github repository with python3 branch is here:
> https://github.com/frenzymadness/python-schedutils/tree/python3
> Successful COPR build compatible with epel 6 and epel 7 is here:
> https://copr.fedorainfracloud.org/coprs/g/realtime/testing/build/660503/
>
> Let me know if I can provide something more.
>
> Have a nice day.
>
> Lumír
>
> From 50fd6a695875c16d5d3e6e9e03d901bf58af535c Mon Sep 17 00:00:00 2001
> From: Lumir Balhar <lbalhar@redhat.com>
> Date: Fri, 10 Nov 2017 09:30:59 +0100
> Subject: [PATCH 5/6] Use builtin macro for returning None
>
> Signed-off-by: Lumir Balhar <lbalhar@redhat.com>
> ---
>  python-schedutils/schedutils.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/python-schedutils/schedutils.c b/python-schedutils/schedutils.c
> index 79fb0bd..a82b878 100644
> --- a/python-schedutils/schedutils.c
> +++ b/python-schedutils/schedutils.c
> @@ -220,8 +220,7 @@ static PyObject *set_scheduler(PyObject *self __unused, PyObject *args)
>       if (sched_setscheduler(pid, policy, &param) < 0)
>               return PyErr_SetFromErrno(PyExc_OSError);
>
> -     Py_INCREF(Py_None);
> -     return Py_None;
> +     Py_RETURN_NONE;
>  }
>
>  static PyObject *get_priority(PyObject *self __unused, PyObject *args)
> --
> 2.13.6
>
> From 328e4b51e3aca4852cd95e269662bf40f68310ec Mon Sep 17 00:00:00 2001
> From: Lumir Balhar <lbalhar@redhat.com>
> Date: Fri, 10 Nov 2017 09:30:29 +0100
> Subject: [PATCH 4/6] python3: Make schedutils Python 3 compatible
>
> Signed-off-by: Lumir Balhar <lbalhar@redhat.com>
> ---
>  python-schedutils/schedutils.c | 19 +++++++++++++++----
>  1 file changed, 15 insertions(+), 4 deletions(-)
>
> diff --git a/python-schedutils/schedutils.c b/python-schedutils/schedutils.c
> index be38e18..79fb0bd 100644
> --- a/python-schedutils/schedutils.c
> +++ b/python-schedutils/schedutils.c
> @@ -1,4 +1,5 @@
>  #include <Python.h>
> +#include "py3compat.h"
>  #include <sched.h>
>  #include <errno.h>
>  #include <syscall.h>
> @@ -266,7 +267,7 @@ static PyObject *schedstr(PyObject *self __unused, PyObject *args)
>       default:          s = "UNKNOWN";     break;
>       }
>
> -     return PyString_FromString(s);
> +     return PyStr_FromString(s);
>  }
>
>  static PyObject *schedfromstr(PyObject *self __unused, PyObject *args)
> @@ -378,11 +379,19 @@ static struct PyMethodDef PySchedutilsModuleMethods[] = {
>       {       .ml_name = NULL, },
>  };
>
> -PyMODINIT_FUNC initschedutils(void)
> +static struct PyModuleDef moduledef = {
> +    PyModuleDef_HEAD_INIT,
> +    .m_name = "schedutils",
> +    .m_doc = NULL,
> +    .m_size = -1,
> +    .m_methods = PySchedutilsModuleMethods,
> +};
> +
> +MODULE_INIT_FUNC(schedutils)
>  {
> -     PyObject *m = Py_InitModule("schedutils", PySchedutilsModuleMethods);
> +     PyObject *m = PyModule_Create(&moduledef);
>       if (m == NULL)
> -             return;
> +             return NULL;
>
>       PyModule_AddIntConstant(m, "SCHED_OTHER", SCHED_OTHER);
>       PyModule_AddIntConstant(m, "SCHED_FIFO", SCHED_FIFO);
> @@ -391,5 +400,7 @@ PyMODINIT_FUNC initschedutils(void)
>       PyModule_AddIntConstant(m, "SCHED_IDLE", SCHED_IDLE);
>          PyModule_AddIntConstant(m, "SCHED_DEADLINE", SCHED_DEADLINE);
>       PyModule_AddIntConstant(m, "SCHED_RESET_ON_FORK", SCHED_RESET_ON_FORK);
> +
> +     return m;
>  }
>
> --
> 2.13.6
>
> From 0963592cbfa1518757261bded13178aa7c49f450 Mon Sep 17 00:00:00 2001
> From: Lumir Balhar <lbalhar@redhat.com>
> Date: Fri, 10 Nov 2017 09:27:30 +0100
> Subject: [PATCH 3/6] python3: Add compatibility header file with necessary
>  macros
>
> Signed-off-by: Lumir Balhar <lbalhar@redhat.com>
> ---
>  python-schedutils/py3compat.h | 60 +++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 60 insertions(+)
>  create mode 100644 python-schedutils/py3compat.h
>
> diff --git a/python-schedutils/py3compat.h b/python-schedutils/py3compat.h
> new file mode 100644
> index 0000000..625cddf
> --- /dev/null
> +++ b/python-schedutils/py3compat.h
> @@ -0,0 +1,60 @@
> +/*
> +   Python 3 compatibility macros
> +   Copyright (C) Petr Viktorin <pviktori@redhat.com> 2015
> +*/
> +
> +#include <Python.h>
> +
> +#if PY_MAJOR_VERSION >= 3
> +
> +/***** Python 3 *****/
> +
> +#define IS_PY3 1
> +
> +/* Ints */
> +
> +#define PyInt_AsLong PyLong_AsLong
> +
> +/* Strings */
> +
> +#define PyStr_FromString PyUnicode_FromString
> +
> +/* Module init */
> +
> +#define MODULE_INIT_FUNC(name) \
> +    PyMODINIT_FUNC PyInit_ ## name(void); \
> +    PyMODINIT_FUNC PyInit_ ## name(void)
> +
> +#else
> +
> +/***** Python 2 *****/
> +
> +#define IS_PY3 0
> +
> +/* Strings */
> +
> +#define PyStr_FromString PyString_FromString
> +
> +/* Module init */
> +
> +#define PyModuleDef_HEAD_INIT 0
> +
> +typedef struct PyModuleDef {
> +    int m_base;
> +    const char* m_name;
> +    const char* m_doc;
> +    Py_ssize_t m_size;
> +    PyMethodDef *m_methods;
> +} PyModuleDef;
> +
> +#define PyModule_Create(def) \
> +    Py_InitModule3((def)->m_name, (def)->m_methods, (def)->m_doc)
> +
> +#define MODULE_INIT_FUNC(name) \
> +    static PyObject *PyInit_ ## name(void); \
> +    void init ## name(void); \
> +    void init ## name(void) { PyInit_ ## name(); } \
> +    static PyObject *PyInit_ ## name(void)
> +
> +
> +#endif
> --
> 2.13.6
>
> From df30c2455d3ea1138e8b57d07d59d69eb0c1ab2e Mon Sep 17 00:00:00 2001
> From: Lumir Balhar <lbalhar@redhat.com>
> Date: Thu, 9 Nov 2017 14:48:04 +0100
> Subject: [PATCH 2/6] python3: Fix incompatible prints and exceptions
>
> Signed-off-by: Lumir Balhar <lbalhar@redhat.com>
> ---
>  pchrt.py    | 22 ++++++++++++----------
>  ptaskset.py | 15 ++++++++-------
>  2 files changed, 20 insertions(+), 17 deletions(-)
>
> diff --git a/pchrt.py b/pchrt.py
> index c590b37..ddb1265 100755
> --- a/pchrt.py
> +++ b/pchrt.py
> @@ -14,13 +14,14 @@
>  #   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 '''pchrt (python-schedutils)
> +    print('''pchrt (python-schedutils)
>  usage: pchrt [options] [prio] [pid | cmd [args...]]
>  manipulate real-time attributes of a process
>    -b, --batch                        set policy to SCHED_BATCH
> @@ -35,16 +36,16 @@ manipulate real-time attributes of a process
>
>  You must give a priority if changing policy.
>
> -Report bugs and send patches to <tuna-devel@lists.fedorahosted.org>'''
> +Report bugs and send patches to <tuna-devel@lists.fedorahosted.org>''')
>      return
>
>
>  def show_priority_limits(policy):
> -    print "%-32.32s: %d/%d" % (
> +    print("%-32.32s: %d/%d" % (
>          "%s min/max priority" % schedutils.schedstr(policy),
>          schedutils.get_priority_min(policy),
>          schedutils.get_priority_max(policy)
> -    )
> +    ))
>
>
>  def show_all_priority_limits():
> @@ -60,14 +61,15 @@ def show_settings(pid):
>      reset_on_fork = ""
>      if policy & schedutils.SCHED_RESET_ON_FORK:
>          reset_on_fork = "|SCHED_RESET_ON_FORK"
> -    print '''pid %d's current scheduling policy: %s%s
> -pid %d's current scheduling priority: %d''' % (pid, spolicy, reset_on_fork, pid, rtprio)
> +    print('''pid %d's current scheduling policy: %s%s
> +pid %d's current scheduling priority: %d''' % (pid, spolicy, reset_on_fork,
> +                                               pid, rtprio))
>
>
>  def valid_policy_flag(policy, policy_flag):
>      if policy_flag == schedutils.SCHED_RESET_ON_FORK and \
>         policy not in (schedutils.SCHED_RR, schedutils.SCHED_FIFO):
> -        print "SCHED_RESET_ON_FORK flag is supported for SCHED_FIFO and SCHED_RR policies only"
> +        print("SCHED_RESET_ON_FORK flag is supported for SCHED_FIFO and SCHED_RR policies only")
>          return False
>      return True
>
> @@ -75,9 +77,9 @@ def valid_policy_flag(policy, policy_flag):
>  def change_settings(pid, policy, policy_flag, rtprio):
>      try:
>          schedutils.set_scheduler(pid, policy | policy_flag, rtprio)
> -    except SystemError, err:
> -        print "sched_setscheduler: %s" % err[1]
> -        print "failed to set pid %d's policy" % pid
> +    except SystemError as err:
> +        print("sched_setscheduler: %s" % err[1])
> +        print("failed to set pid %d's policy" % pid)
>
>
>  def main():
> diff --git a/ptaskset.py b/ptaskset.py
> index de925a9..56fe7af 100755
> --- a/ptaskset.py
> +++ b/ptaskset.py
> @@ -14,19 +14,20 @@
>  #   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)
> +    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'''
> +  -h, --help                 display this help''')
>
>      return
>
> @@ -103,7 +104,7 @@ def cpustring_to_list(cpustr):
>          if len(ends) > 2:
>              raise "Syntax error"
>          if len(ends) == 2:
> -            cpu_list += range(int(ends[0]), int(ends[1]) + 1)
> +            cpu_list += list(range(int(ends[0]), int(ends[1]) + 1))
>          else:
>              cpu_list += [int(ends[0])]
>      return list(set(cpu_list))
> @@ -115,7 +116,7 @@ def show_settings(pid, when, 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)
> +    print("pid %d's %s affinity mask: %s" % (pid, when, mask))
>
>
>  def change_settings(pid, affinity, cpu_list_mode):
> @@ -129,9 +130,9 @@ def change_settings(pid, affinity, cpu_list_mode):
>
>      try:
>          schedutils.set_affinity(pid, affinity)
> -    except SystemError, err:
> -        print "sched_setaffinity: %s" % err[1]
> -        print "failed to set pid %d's affinity" % pid
> +    except SystemError as err:
> +        print("sched_setaffinity: %s" % err[1])
> +        print("failed to set pid %d's affinity" % pid)
>
>
>  def main():
> --
> 2.13.6
>
> From 96d8d005658077ee7a64e5728f0abddec93a8569 Mon Sep 17 00:00:00 2001
> From: Lumir Balhar <lbalhar@redhat.com>
> Date: Thu, 9 Nov 2017 14:32:45 +0100
> Subject: [PATCH 1/6] Fix code style - spaces instead of tabs, indentaion,
>  imports, blank lines etc.
>
> Signed-off-by: Lumir Balhar <lbalhar@redhat.com>
> ---
>  pchrt.py    | 170 +++++++++++++++++++++-------------------
>  ptaskset.py | 253 +++++++++++++++++++++++++++++++-----------------------------
>  2 files changed, 223 insertions(+), 200 deletions(-)
>
> diff --git a/pchrt.py b/pchrt.py
> index 0761792..c590b37 100755
> --- a/pchrt.py
> +++ b/pchrt.py
> @@ -14,10 +14,13 @@
>  #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>  #   General Public License for more details.
>
> -import os, schedutils, sys
> +import os
> +import schedutils
> +import sys
> +
>
>  def usage():
> -     print '''pchrt (python-schedutils)
> +    print '''pchrt (python-schedutils)
>  usage: pchrt [options] [prio] [pid | cmd [args...]]
>  manipulate real-time attributes of a process
>    -b, --batch                        set policy to SCHED_BATCH
> @@ -33,97 +36,106 @@ manipulate real-time attributes of a process
>  You must give a priority if changing policy.
>
>  Report bugs and send patches to <tuna-devel@lists.fedorahosted.org>'''
> -     return
> +    return
> +
>
>  def show_priority_limits(policy):
> -     print "%-32.32s: %d/%d" % ("%s min/max priority" % schedutils.schedstr(policy),
> -                                schedutils.get_priority_min(policy),
> -                                schedutils.get_priority_max(policy))
> +    print "%-32.32s: %d/%d" % (
> +        "%s min/max priority" % schedutils.schedstr(policy),
> +        schedutils.get_priority_min(policy),
> +        schedutils.get_priority_max(policy)
> +    )
> +
>
>  def show_all_priority_limits():
> -     for policy in (schedutils.SCHED_OTHER, schedutils.SCHED_FIFO,
> -                    schedutils.SCHED_RR, schedutils.SCHED_BATCH):
> -             show_priority_limits(policy)
> +    for policy in (schedutils.SCHED_OTHER, schedutils.SCHED_FIFO,
> +                   schedutils.SCHED_RR, schedutils.SCHED_BATCH):
> +        show_priority_limits(policy)
> +
>
>  def show_settings(pid):
> -     policy = schedutils.get_scheduler(pid)
> -     spolicy = schedutils.schedstr(policy)
> -     rtprio = schedutils.get_priority(pid)
> -     reset_on_fork = ""
> -     if policy & schedutils.SCHED_RESET_ON_FORK:
> -             reset_on_fork = "|SCHED_RESET_ON_FORK"
> -     print '''pid %d's current scheduling policy: %s%s
> +    policy = schedutils.get_scheduler(pid)
> +    spolicy = schedutils.schedstr(policy)
> +    rtprio = schedutils.get_priority(pid)
> +    reset_on_fork = ""
> +    if policy & schedutils.SCHED_RESET_ON_FORK:
> +        reset_on_fork = "|SCHED_RESET_ON_FORK"
> +    print '''pid %d's current scheduling policy: %s%s
>  pid %d's current scheduling priority: %d''' % (pid, spolicy, reset_on_fork, pid, rtprio)
>
> +
>  def valid_policy_flag(policy, policy_flag):
> -     if policy_flag == schedutils.SCHED_RESET_ON_FORK and \
> -        policy not in (schedutils.SCHED_RR, schedutils.SCHED_FIFO):
> -             print "SCHED_RESET_ON_FORK flag is supported for SCHED_FIFO and SCHED_RR policies only"
> -             return False
> -     return True
> +    if policy_flag == schedutils.SCHED_RESET_ON_FORK and \
> +       policy not in (schedutils.SCHED_RR, schedutils.SCHED_FIFO):
> +        print "SCHED_RESET_ON_FORK flag is supported for SCHED_FIFO and SCHED_RR policies only"
> +        return False
> +    return True
> +
>
>  def change_settings(pid, policy, policy_flag, rtprio):
> -     try:
> -             schedutils.set_scheduler(pid, policy | policy_flag, rtprio)
> -     except SystemError, err:
> -             print "sched_setscheduler: %s" % err[1]
> -             print "failed to set pid %d's policy" % pid
> +    try:
> +        schedutils.set_scheduler(pid, policy | policy_flag, rtprio)
> +    except SystemError, err:
> +        print "sched_setscheduler: %s" % err[1]
> +        print "failed to set pid %d's policy" % pid
> +
>
>  def main():
>
> -     args = sys.argv[1:]
> -     if not args:
> -             usage()
> -             return
> -
> -     policy = schedutils.SCHED_RR
> -     policy_flag = 0
> -     while True:
> -             o = args.pop(0)
> -             try:
> -                     priority = int(o)
> -                     break
> -             except:
> -                     pass
> -
> -             if o in ("-h", "--help"):
> -                     usage()
> -                     return
> -             elif o in ("-b", "--batch"):
> -                     policy = schedutils.SCHED_BATCH
> -             elif o in ("-f", "--fifo"):
> -                     policy = schedutils.SCHED_FIFO
> -             elif o in ("-i", "--idle"):
> -                     policy = schedutils.SCHED_IDLE
> -             elif o in ("-m", "--max"):
> -                     show_all_priority_limits()
> -                     return
> -             elif o in ("-o", "--other"):
> -                     policy = schedutils.SCHED_OTHER
> -             elif o in ("-r", "--rr"):
> -                     policy = schedutils.SCHED_RR
> -             elif o in ("-R", "--reset-on-fork"):
> -                     policy_flag |= schedutils.SCHED_RESET_ON_FORK
> -             elif o in ("-p", "--pid"):
> -                     if len(args) > 1:
> -                             priority = int(args.pop(0))
> -                             pid = int(args.pop(0))
> -                             if not valid_policy_flag(policy, policy_flag):
> -                                     return
> -                             change_settings(pid, policy, policy_flag, priority)
> -                     else:
> -                             pid = int(args.pop(0))
> -                             show_settings(pid)
> -                     return
> -             else:
> -                     usage()
> -                     return
> -
> -     if not valid_policy_flag(policy, policy_flag):
> -             return
> -
> -     schedutils.set_scheduler(0, policy | policy_flag, priority)
> -     os.execvp(args[0], args)
> +    args = sys.argv[1:]
> +    if not args:
> +        usage()
> +        return
> +
> +    policy = schedutils.SCHED_RR
> +    policy_flag = 0
> +    while True:
> +        o = args.pop(0)
> +        try:
> +            priority = int(o)
> +            break
> +        except:
> +            pass
> +
> +        if o in ("-h", "--help"):
> +            usage()
> +            return
> +        elif o in ("-b", "--batch"):
> +            policy = schedutils.SCHED_BATCH
> +        elif o in ("-f", "--fifo"):
> +            policy = schedutils.SCHED_FIFO
> +        elif o in ("-i", "--idle"):
> +            policy = schedutils.SCHED_IDLE
> +        elif o in ("-m", "--max"):
> +            show_all_priority_limits()
> +            return
> +        elif o in ("-o", "--other"):
> +            policy = schedutils.SCHED_OTHER
> +        elif o in ("-r", "--rr"):
> +            policy = schedutils.SCHED_RR
> +        elif o in ("-R", "--reset-on-fork"):
> +            policy_flag |= schedutils.SCHED_RESET_ON_FORK
> +        elif o in ("-p", "--pid"):
> +            if len(args) > 1:
> +                priority = int(args.pop(0))
> +                pid = int(args.pop(0))
> +                if not valid_policy_flag(policy, policy_flag):
> +                    return
> +                change_settings(pid, policy, policy_flag, priority)
> +            else:
> +                pid = int(args.pop(0))
> +                show_settings(pid)
> +            return
> +        else:
> +            usage()
> +            return
> +
> +    if not valid_policy_flag(policy, policy_flag):
> +        return
> +
> +    schedutils.set_scheduler(0, policy | policy_flag, priority)
> +    os.execvp(args[0], args)
> +
>
>  if __name__ == '__main__':
>      main()
> diff --git a/ptaskset.py b/ptaskset.py
> index afd1847..de925a9 100755
> --- a/ptaskset.py
> +++ b/ptaskset.py
> @@ -14,10 +14,13 @@
>  #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>  #   General Public License for more details.
>
> -import os, schedutils, sys
> +import os
> +import schedutils
> +import sys
> +
>
>  def usage():
> -     print '''ptaskset (python-schedutils)
> +    print '''ptaskset (python-schedutils)
>  usage: ptaskset [options] [mask | cpu-list] [pid | cmd [args...]]
>  set or get the affinity of a process
>
> @@ -25,138 +28,146 @@ set or get the affinity of a process
>    -c, --cpu-list             display and specify cpus in list format
>    -h, --help                 display this help'''
>
> -     return
> +    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
> +    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
> +    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 += range(int(ends[0]), int(ends[1])+1)
> -             else:
> -                     cpu_list += [int(ends[0])]
> -     return list(set(cpu_list))
> +    """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 += 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)
> +    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, err:
> -             print "sched_setaffinity: %s" % err[1]
> -             print "failed to set pid %d's affinity" % pid
> +    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, 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)
> +    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()
> --
> 2.13.6
>
> From 8204200377935a825d872e10f6a53d1ebdabf96a Mon Sep 17 00:00:00 2001
> From: Lumir Balhar <lbalhar@redhat.com>
> Date: Fri, 10 Nov 2017 11:40:59 +0100
> Subject: [PATCH 6/6] python3: Provide necessary flag for function with no args
>
> Signed-off-by: Lumir Balhar <lbalhar@redhat.com>
> ---
>  python-schedutils/schedutils.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/python-schedutils/schedutils.c b/python-schedutils/schedutils.c
> index a82b878..304de0f 100644
> --- a/python-schedutils/schedutils.c
> +++ b/python-schedutils/schedutils.c
> @@ -374,6 +374,7 @@ static struct PyMethodDef PySchedutilsModuleMethods[] = {
>       {
>               .ml_name = "get_max_number_of_cpus",
>               .ml_meth = (PyCFunction)get_max_number_of_cpus,
> +             .ml_flags = METH_NOARGS,
>       },
>       {       .ml_name = NULL, },
>  };

_______________________________________________
tuna-devel mailing list -- tuna-devel@lists.fedorahosted.org
To unsubscribe send an email to tuna-devel-leave@lists.fedorahosted.org