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