• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2016 Catalysts GmbH
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14import ctypes as ct
15import sys
16import traceback
17import warnings
18
19from .libbcc import lib
20
21def _read_cpu_range(path):
22    cpus = []
23    with open(path, 'r') as f:
24        cpus_range_str = f.read()
25        for cpu_range in cpus_range_str.split(','):
26            rangeop = cpu_range.find('-')
27            if rangeop == -1:
28                cpus.append(int(cpu_range))
29            else:
30                start = int(cpu_range[:rangeop])
31                end = int(cpu_range[rangeop+1:])
32                cpus.extend(range(start, end+1))
33    return cpus
34
35def get_online_cpus():
36    return _read_cpu_range('/sys/devices/system/cpu/online')
37
38def get_possible_cpus():
39    return _read_cpu_range('/sys/devices/system/cpu/possible')
40
41def detect_language(candidates, pid):
42    res = lib.bcc_procutils_language(pid)
43    language = ct.cast(res, ct.c_char_p).value.decode()
44    return language if language in candidates else None
45
46FILESYSTEMENCODING = sys.getfilesystemencoding()
47
48def printb(s, file=sys.stdout, nl=1):
49    """
50    printb(s)
51
52    print a bytes object to stdout and flush
53    """
54    buf = file.buffer if hasattr(file, "buffer") else file
55
56    buf.write(s)
57    if nl:
58        buf.write(b"\n")
59    file.flush()
60
61class ArgString(object):
62    """
63    ArgString(arg)
64
65    encapsulate a system argument that can be easily coerced to a bytes()
66    object, which is better for comparing to kernel or probe data (which should
67    never be en/decode()'ed).
68    """
69    def __init__(self, arg):
70        if sys.version_info[0] >= 3:
71            self.s = arg
72        else:
73            self.s = arg.decode(FILESYSTEMENCODING)
74
75    def __bytes__(self):
76        return self.s.encode(FILESYSTEMENCODING)
77
78    def __str__(self):
79        return self.__bytes__()
80
81def warn_with_traceback(message, category, filename, lineno, file=None, line=None):
82    log = file if hasattr(file, "write") else sys.stderr
83    traceback.print_stack(f=sys._getframe(2), file=log)
84    log.write(warnings.formatwarning(message, category, filename, lineno, line))
85
86# uncomment to get full tracebacks for invalid uses of python3+str in arguments
87#warnings.showwarning = warn_with_traceback
88
89_strict_bytes = False
90def _assert_is_bytes(arg):
91    if arg is None:
92        return arg
93    if _strict_bytes:
94        assert type(arg) is bytes, "not a bytes object: %r" % arg
95    elif type(arg) is not bytes:
96        warnings.warn("not a bytes object: %r" % arg, DeprecationWarning, 2)
97        return ArgString(arg).__bytes__()
98    return arg
99
100