17#include <sys/resource.h>
18#include <sys/syscall.h>
26#include <mach-o/dyld.h>
31#define LIBTOOL_OBJDIR "_libs"
33#define LIBTOOL_OBJDIR ".libs"
36#define PDEBUG(...) Ase::debug ("Platform", __VA_ARGS__)
41static std::string determine_anklangsynthengine_installdir (
bool *using_objdir);
48 const char *anklanghomeenv =
getenv (
"ANKLANG_HOME_DIR");
49 String anklangdir = anklanghomeenv && anklanghomeenv[0] ? anklanghomeenv :
50 Path::join (Path::xdg_dir (
"DOCUMENTS"),
"Anklang");
52 anklangdir = Path::join (anklangdir, subdir);
60 static bool using_objdir =
false;
61 static const std::string libexec_installdir = determine_anklangsynthengine_installdir (&using_objdir);
63 const char *objdir = using_objdir ?
"/" LIBTOOL_OBJDIR :
"";
66 case RPath::PREFIXDIR:
return Path::join (libexec_prefixdir, segment);
67 case RPath::INSTALLDIR:
return Path::join (libexec_installdir, segment);
68 case RPath::LOCALEDIR:
return Path::join (libexec_installdir +
"/locale", segment);
69 case RPath::LIBDIR:
return Path::join (libexec_installdir +
"/lib" + objdir, segment);
70 case RPath::ELECTRONDIR:
return Path::join (libexec_installdir +
"/electron", segment);
71 case RPath::LADSPADIRS:
return Path::join (construct_ladspa_path(), segment);
72 case RPath::SAMPLEDIR:
return Path::join (libexec_installdir +
"/media/Samples", segment);
73 case RPath::DEMODIR:
return Path::join (libexec_installdir +
"/media/Demos", segment);
79construct_ladspa_path()
83 const char *ladspa_path =
getenv (
"LADSPA_PATH");
85 sp = Path::searchpath_split (ladspa_path);
102 return Path::searchpath_join (sv);
107initialized_ase_gettext_domain()
109 static const char *
const gettexttextdomain = [] () {
110 const char *
const gtdomain = ase_gettext_domain;
112 bind_textdomain_codeset (gtdomain,
"UTF-8");
115 return gettexttextdomain;
120(
_) (
const char *
string)
122 return dgettext (initialized_ase_gettext_domain(),
string);
129 return _ (
string.c_str());
134(
_) (
const char *
string,
const char *plural, int64_t n)
137 const ulong l = u >= 2147483647 ? 2147483647 : u;
138 return dcngettext (initialized_ase_gettext_domain(),
string, plural, l, LC_MESSAGES);
145 return _ (
string.c_str(), plural.c_str(), n);
149namespace AnsiColors {
157 atomic_store (&colorize_cache, colorize);
166 const Colorize colcache = atomic_load (&colorize_cache);
168 const char *ev =
getenv (
"ASE_COLOR");
175 atomic_store (&colorize_cache, Colorize::ALWAYS);
180 atomic_store (&colorize_cache, Colorize::NEVER);
185 atomic_store (&colorize_cache, tty_output ? Colorize::ALWAYS : Colorize::NEVER);
211 case NONE:
return "";
212 case RESET:
return "\033[0m";
213 case BOLD:
return "\033[1m";
214 case BOLD_OFF:
return "\033[22m";
215 case ITALICS:
return "\033[3m";
216 case ITALICS_OFF:
return "\033[23m";
217 case UNDERLINE:
return "\033[4m";
218 case UNDERLINE_OFF:
return "\033[24m";
219 case INVERSE:
return "\033[7m";
220 case INVERSE_OFF:
return "\033[27m";
221 case STRIKETHROUGH:
return "\033[9m";
222 case STRIKETHROUGH_OFF:
return "\033[29m";
223 case FG_BLACK:
return "\033[30m";
224 case FG_RED:
return "\033[31m";
225 case FG_GREEN:
return "\033[32m";
226 case FG_YELLOW:
return "\033[33m";
227 case FG_BLUE:
return "\033[34m";
228 case FG_MAGENTA:
return "\033[35m";
229 case FG_CYAN:
return "\033[36m";
230 case FG_WHITE:
return "\033[37m";
231 case FG_DEFAULT:
return "\033[39m";
232 case BG_BLACK:
return "\033[40m";
233 case BG_RED:
return "\033[41m";
234 case BG_GREEN:
return "\033[42m";
235 case BG_YELLOW:
return "\033[43m";
236 case BG_BLUE:
return "\033[44m";
237 case BG_MAGENTA:
return "\033[45m";
238 case BG_CYAN:
return "\033[46m";
239 case BG_WHITE:
return "\033[47m";
240 case BG_DEFAULT:
return "\033[49m";
256#elif defined __s390__
258#elif defined __m32c__
262#elif defined __m32r__
264#elif defined __x86_64__ || defined __amd64__
266#elif defined __ia64__
267 return "Intel Itanium";
268#elif defined __m68k__
270#elif defined __powerpc__ || defined PPC || defined powerpc || defined __PPC__
276#elif defined __mips__ || defined mips
278#elif defined __tune_i686__ || defined __i686__
280#elif defined __tune_i586__ || defined __i586__
282#elif defined __tune_i486__ || defined __i486__
284#elif defined i386 || defined __i386__
287 return "unknown-arch";
288#warning platform.cc needs updating for this processor type
299 uint x86_fpu : 1, x86_ssesys : 1, x86_tsc : 1, x86_htt : 1;
300 uint x86_mmx : 1, x86_mmxext : 1, x86_3dnow : 1, x86_3dnowext : 1;
301 uint x86_sse : 1, x86_sse2 : 1, x86_sse3 : 1, x86_ssse3 : 1;
302 uint x86_cx16 : 1, x86_sse4_1 : 1, x86_sse4_2 : 1, x86_rdrand : 1;
305static jmp_buf cpu_info_jmp_buf;
307static void ASE_NORETURN
308cpu_info_sigill_handler (
int dummy)
314# define x86_has_cpuid() ({ \
315 unsigned int __eax = 0, __ecx = 0; \
316 __asm__ __volatile__ \
319 "pushf ; pop %0 ; mov %0, %1 \n\t" \
321 "xor $0x200000, %0 ; push %0 ; popf \n\t" \
323 "pushf ; pop %0 \n\t" \
324 : "=a" (__eax), "=c" (__ecx) \
328 bool __result = (__eax ^ __ecx) & 0x00200000; \
332# define x86_cpuid(input, count, eax, ebx, ecx, edx) \
333 __asm__ __volatile__ ( \
335 "mov %%ebx, %%esi \n\t" \
339 "xchg %%ebx, %%esi" \
340 : "=a" (eax), "=S" (ebx), \
341 "=c" (ecx), "=d" (edx) \
342 : "0" (input), "2" (count) \
344#elif defined __x86_64__ || defined __amd64__
350# define x86_has_cpuid() (1)
352# define x86_cpuid(input, count, eax, ebx, ecx, edx) \
353 __asm__ __volatile__ ( \
355 "mov %%rbx, %%rsi \n\t" \
359 "xchg %%rbx, %%rsi" \
360 : "=a" (eax), "=S" (ebx), \
361 "=c" (ecx), "=d" (edx) \
362 : "0" (input), "2" (count) \
365# define x86_has_cpuid() (false)
366# define x86_cpuid(input, count, eax, ebx, ecx, edx) do {} while (0)
370get_x86_cpu_features (
CPUInfo *ci)
372 memset (ci, 0,
sizeof (*ci));
374 if (!x86_has_cpuid ())
378 unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
379 x86_cpuid (0, 0, eax, ebx, ecx, edx);
380 unsigned int v_ebx = ebx, v_ecx = ecx, v_edx = edx;
381 char *vendor = ci->cpu_vendor;
382 *((
unsigned int*) &vendor[0]) = ebx;
383 *((
unsigned int*) &vendor[4]) = edx;
384 *((
unsigned int*) &vendor[8]) = ecx;
388 x86_cpuid (1, 0, eax, ebx, ecx, edx);
392 ci->x86_ssse3 =
true;
396 ci->x86_sse4_1 =
true;
398 ci->x86_sse4_2 =
true;
400 ci->x86_rdrand =
true;
410 ci->x86_mmxext =
true;
422 x86_cpuid (0x80000000, 0, eax, ebx, ecx, edx);
423 if (eax >= 0x80000001 &&
424 v_ebx == 0x68747541 &&
425 v_ecx == 0x444d4163 && v_edx == 0x69746e65)
427 x86_cpuid (0x80000001, 0, eax, ebx, ecx, edx);
429 ci->x86_3dnow =
true;
431 ci->x86_mmxext =
true;
433 ci->x86_3dnowext =
true;
443 action.sa_handler = cpu_info_sigill_handler;
445 action.sa_flags = SA_NOMASK;
446 sigaction (SIGILL, &action, &old_action);
447 if (setjmp (cpu_info_jmp_buf) == 0)
449#if defined __i386__ || defined __x86_64__ || defined __amd64__
451 __asm__ __volatile__ (
"stmxcsr %0 ; sfence ; emms" :
"=m" (mxcsr));
453 ci->x86_ssesys =
true;
470 return get_arch_name();
483 static String cpu_info_string = []() {
485 if (!get_x86_cpu_features (&
cpu_info))
503 info +=
" CMPXCHG16B";
534 return cpu_info_string;
538static clockid_t monotonic_clockid = CLOCK_REALTIME;
539static uint64 monotonic_start = 0;
540static uint64 monotonic_resolution = 1000;
541static uint64 realtime_start = 0;
546 static const bool initialize = [] () {
548 struct timespec tp = { 0, 0 };
549 if (clock_getres (CLOCK_REALTIME, &tp) >= 0)
550 monotonic_resolution = tp.tv_sec * 1000000000ULL + tp.tv_nsec;
551 uint64 mstart = realtime_start;
552#ifdef CLOCK_MONOTONIC
555 if (monotonic_clockid == CLOCK_REALTIME && clock_getres (CLOCK_MONOTONIC, &tp) >= 0)
557 monotonic_clockid = CLOCK_MONOTONIC;
558 monotonic_resolution = tp.tv_sec * 1000000000ULL + tp.tv_nsec;
562 monotonic_start = mstart;
567namespace {
static struct Timestamper { Timestamper() { timestamp_init_(); } } realtime_startup; }
574 return realtime_start;
581 struct timespec tp = { 0, 0 };
583 return tp.tv_sec * 1000000ULL + tp.tv_nsec / 1000;
586 struct timeval now = { 0, 0 };
588 return now.tv_sec * 1000000ULL + now.tv_usec;
597 return monotonic_resolution;
604 struct timespec tp = { 0, 0 };
608 stamp = tp.tv_sec * 1000000000ULL + tp.tv_nsec;
609 stamp -= monotonic_start;
614 stamp -=
std::min (stamp, monotonic_start);
623 const size_t fieldwidth =
std::max (maxlength, 1U);
627 if (r.
size() < fieldwidth)
629 if (r.
size() < fieldwidth)
639 return global_monotonic_counter++;
672 return (end_ - start_) * 0.000001;
679 return (end_ - start_) * 0.001;
694 char system_result[max_size + 1 + 1] = { 0, };
695 ssize_t system_result_size = -1;
697#if defined __linux__ || defined __CYGWIN__ || defined __MSYS__
698 system_result_size =
readlink (
"/proc/self/exe", system_result, max_size);
699 if (system_result_size < 0)
701 strcpy (system_result,
"/proc/self/exe");
702 system_result_size = 0;
704#elif defined __APPLE__
707 if (_NSGetExecutablePath (system_result, &bufsize) == 0 &&
709 system_result_size = bufsize;
713 system_result_size = GetModuleFileNameA (0, system_result, max_size);
714 if (system_result_size <= 0 || system_result_size >= max_size)
715 system_result_size = -1;
718 system_result[system_result_size] = 0;
721 while ((winslash = strchr (system_result,
'\\')) != NULL)
725#error "Platform lacks executable_path() implementation"
728 if (system_result_size < 0)
729 system_result[0] = 0;
737 static std::string cached_executable_path = get_executable_path();
738 return cached_executable_path;
745 static std::string cached_executable_name = [] () {
748 return slash ? slash + 1 : path;
750 return cached_executable_name;
753void fatal_system_error (
const char *file,
uint line,
const char *format, ...) __attribute__ ((__format__ (printf, 3, 4), __noreturn__));
756fatal_system_error (const
char *file,
uint line, const
char *format, ...)
758 const int maxbuffer = 8 * 1024;
759 char buffer[maxbuffer + 2] = { 0, }, *b = buffer, *e = b + maxbuffer;
761 snprintf (b, e - b,
"%s:%u: fatal: ", file, line);
763 snprintf (b, e - b,
"%s: fatal: ", file);
769 const int plen =
vsnprintf (b, e - b, format, argv);
773 if (b > buffer && b[-1] !=
'\n')
776 fputs (buffer, stderr);
784find_text_file (ptrdiff_t symbol_address)
786 const char *
const self_maps =
"/proc/self/maps";
788 maps.
open (self_maps);
794 size_t start = 0,
end = 0, offset = 0, inode = 0, pos = 0;
795 char perms[22 + 1], device[22 + 1] =
"";
796 int count =
sscanf (cxxline.
c_str(),
"%zx-%zx %22s %zx %22s %zu %zn", &start, &end, perms, &offset, device, &inode, &pos);
797 if (count != 6 || pos == 0)
799 if (cxxline[pos] ==
'/' && symbol_address >= start && symbol_address < end &&
800 strncmp (perms,
"r-xp", 4) == 0)
801 return cxxline.
substr (pos);
809determine_anklangsynthengine_installdir (
bool *using_objdir)
812 const ptrdiff_t address = ptrdiff_t (&determine_anklangsynthengine_installdir);
813 String pathname = find_text_file (address);
814 const char *path = pathname.
c_str(), *e =
strrchr (path,
'/');
819 if (strncmp (e,
"/lt-", 4) == 0 &&
820 e - path >= 1 + ods &&
821 e[-(1 + ods)] ==
'/' &&
822 strncmp (e - ods, LIBTOOL_OBJDIR, ods) == 0)
823 pathname = pathname.
substr (0, e - ods - 1 - path);
825 pathname = pathname.
substr (0, e - path);
829 pathname = pathname.
substr (0, pathname.
size() - 4);
830 if (pathname.
empty())
831 fatal_system_error (
"AnklangSynthEngine", 0,
"failed to find executable for symbol: %p", (
void*) address);
838 return ase_version_short;
844 return ase_version_long;
847static String cached_program_alias;
859 cached_program_alias = customname;
862static String cached_application_name;
874 cached_application_name = desktopname;
881 return cached_program_cwd;
887 static_assert (
sizeof (mem_) >=
sizeof (sem_t),
"");
888 sem_t &sem = *(sem_t*) mem_;
889 const int ret =
sem_init (&sem, 0 , 0 );
896 sem_t &sem = *(sem_t*) mem_;
899 return ret ?
errno : 0;
905 sem_t &sem = *(sem_t*) mem_;
908 return ret ?
errno : 0;
911ScopedSemaphore::~ScopedSemaphore () noexcept
913 sem_t &sem = *(sem_t*) mem_;
925 if (level == -1 &&
errno)
926 PDEBUG (
"getpriority(%d) failed: %s", tid,
strerror (
errno));
927 return level == -1 &&
errno ? 0 : level;
935 return setpriority (PRIO_PROCESS, tid, nicelevel) >= 0;
947 const int level = DBus::rtkit_get_min_nice_level();
949 emsg = DBus::rtkit_make_high_priority (tid, level);
952 PDEBUG (
"acquired low latency scheduling for pid=%d: %d", tid,
sched_get_priority (tid));
954 PDEBUG (
"failed to acquire low latency scheduling for pid=%d: %s", tid, emsg);
960 process_id (pid), task_id (tid >= 0 ? tid : pid), state (UNKNOWN), processor (-1), priority (0),
961 utime (0), stime (0), cutime (0), cstime (0),
962 ac_stamp (0), ac_utime (0), ac_stime (0), ac_cutime (0), ac_cstime (0)
968 static long clk_tck = 0;
971 clk_tck =
sysconf (_SC_CLK_TCK);
975 int pid = -1, ppid = -1, pgrp = -1, session = -1, tty_nr = -1, tpgid = -1;
976 int exit_signal = 0, processor = 0;
977 long cutime = 0, cstime = 0, priority = 0,
nice = 0, dummyld = 0;
978 long itrealvalue = 0, rss = 0;
979 unsigned long flags = 0, minflt = 0, cminflt = 0, majflt = 0, cmajflt = 0;
980 unsigned long utime = 0, stime = 0, vsize = 0, rlim = 0, startcode = 0;
981 unsigned long endcode = 0, startstack = 0, kstkesp = 0, kstkeip = 0;
983 unsigned long wchan = 0, nswap = 0, cnswap = 0, rt_priority = 0, policy = 0;
984 unsigned long long starttime = 0;
985 char state = 0, command[8192 + 1] = { 0 };
993 "%lu %lu %lu %lu %lu %lu %lu "
994 "%ld %ld %ld %ld %ld %ld "
996 "%lu %lu %lu %lu %lu "
997 "%lu %lu %lu %lu %lu "
1000 &pid, command, &state,
1001 &ppid, &pgrp, &session, &tty_nr, &tpgid,
1002 &flags, &minflt, &cminflt, &majflt, &cmajflt, &utime, &stime,
1003 &cutime, &cstime, &priority, &nice, &dummyld, &itrealvalue,
1004 &starttime, &vsize, &rss,
1005 &rlim, &startcode, &endcode, &startstack, &kstkesp,
1006 &kstkeip, &signal, &blocked, &sigignore, &sigcatch,
1007 &wchan, &nswap, &cnswap, &exit_signal, &processor,
1008 &rt_priority, &policy
1011 const double jiffies_to_usecs = 1000000.0 / clk_tck;
1013 self.
state = TaskStatus::State (state);
1016 self.ac_utime =
utime * jiffies_to_usecs;
1017 self.ac_stime = stime * jiffies_to_usecs;
1021 self.ac_cutime = cutime * jiffies_to_usecs;
1022 self.ac_cstime = cstime * jiffies_to_usecs;
1031#define ACCOUNTING_MSECS 50
1038 if (
ac_stamp + ACCOUNTING_MSECS * 1000 >= now)
1040 if (!update_task_status (*
this))
1042 const double delta = 1000000.0 /
MAX (1, now -
ac_stamp);
1055 string_format (
"pid=%d task=%d state=%c processor=%d priority=%d perc=%.2f%% utime=%.3fms stime=%.3fms cutime=%.3f cstime=%.3f",
1078 for (
auto it = task_registry_tasks_.
begin(); it != task_registry_tasks_.
end(); it++)
1079 if (it->task_id == tid)
1081 task_registry_tasks_.
erase (it);
1091 for (
auto &task : task_registry_tasks_)
1099 return task_registry_tasks_;
1103TaskRegistry::setup_ase (
const String &name16chars)
1108 this_thread_set_name (name16chars);
1122this_thread_set_name (
const String &name16chars)
1124 if (name16chars.
find (
" ") != name16chars.npos)
1130this_thread_get_name ()
1132 char buffer[1024] = { 0, };
1133 pthread_getname_np (
pthread_self(), buffer,
sizeof (buffer) - 1);
1134 buffer[
sizeof (buffer) - 1] = 0;
1139this_thread_getpid ()
1145this_thread_gettid ()
1149 tid = syscall (SYS_gettid);
1152 tid = this_thread_getpid();
1157this_thread_online_cpus ()
1159 static int cpus = 0;
1161 cpus =
sysconf (_SC_NPROCESSORS_ONLN);
1173get_pwd_user (
int uid)
1176 struct passwd spwd = {
nullptr, }, *pp =
nullptr;
1178 if (getpwuid_r (pu.uid, &spwd, buffer, sizeof (buffer), &pp) != 0)
1180 pu.user_name = pp && pp->pw_name && pp->pw_name[0] ? pp->pw_name :
"_unknown";
1181 if (pp && pp->pw_gecos && pp->pw_gecos[0])
1183 memset (buffer, 0,
sizeof (buffer));
1198 return current_user().uid;
1204 return current_user().user_name;
1210 const PwdUser &pu = current_user();
1211 return pu.real_name.
empty() ? pu.user_name : pu.real_name;
1216struct EarlyStartup {
1223static EarlyStartup _early_startup __attribute__ ((init_priority (101)));
1235ase_test_timestamps()
1243 for (
size_t i = 0; i < 999999; i++)
int wait() noexcept
Unlock ScopedSemaphore.
ScopedSemaphore() noexcept
Create a process-local semaphore.
int post() noexcept
Unlock ScopedSemaphore.
~Stopwatch()
Stop and print a previous msg if still running.
void stop(const String &msg="")
Stop stop watch, print msg.
Stopwatch(const String &msg="")
Automatically start stop watch.
double seconds() const
Provide seconds elapsed between start() and stop().
void start(const String &msg="")
Start or restart stop watch, printing msg later on.
double milliseconds() const
Provide milliseconds elapsed between start() and stop().
static void add(const std::string &name, int pid, int tid=-1)
Add process/thread to registry for runtime profiling.
static void update()
Issue TaskStatus.update on all tasks in registry.
static bool remove(int tid)
Remove process/thread based on thread_id.
static List list()
Retrieve a copy to the list of all tasks in registry.
#define assert_return(expr,...)
Return from the current function if expr is unmet and issue an assertion warning.
#define return_unless(cond,...)
Return silently if cond does not evaluate to true with return value ...
#define _(...)
Retrieve the translation of a C or C++ string.
#define TEST_INTEGRITY(FUNC)
Register func as an integrity test.
#define MAX(a, b)
Yield maximum of a and b.
#define ISLIKELY(cond)
Hint to the compiler to optimize for cond == TRUE.
std::string color(Colors acolor, Colors c1, Colors c2, Colors c3, Colors c4, Colors c5, Colors c6)
Return ANSI code for the specified color if stdout & stderr should be colorized, see colorize_tty().
Colors
ANSI color symbols.
@ RESET
Reset combines BOLD_OFF, ITALICS_OFF, UNDERLINE_OFF, INVERSE_OFF, STRIKETHROUGH_OFF.
void configure(Colorize colorize)
Override the environment variable $ASE_COLOR (which may contain "always", "never" or "auto").
bool colorize_tty(int fd)
Check whether the tty fd should use colorization, checks ASE_COLOR if fd == -1.
const char * color_code(Colors acolor)
Return ANSI code for the specified color.
String cwd()
Return the current working directoy, including symlinks used in $PWD if available.
String realpath(const String &path)
Resolve links and directory references in path and provide a canonicalized absolute pathname.
String dirname(const String &path)
Retrieve the directory part of the filename path.
bool check(const String &file, const String &mode)
The Anklang C++ API namespace.
std::string string_format(const char *format, const Args &...args) __attribute__((__format__(__printf__
Format a string similar to sprintf(3) with support for std::string and std::ostringstream convertible...
uint64 timestamp_resolution()
Provide resolution of timestamp_benchmark() in nano-seconds.
uint64_t uint64
A 64-bit unsigned integer, use PRI*64 in format strings.
String cpu_info()
The returned string contains: number of online CPUs, a string describing the CPU architecture,...
void assertion_failed(const char *msg, const char *file, int line, const char *func) noexcept
Print instructive message, handle "breakpoint", "backtrace" and "fatal-warnings" in $ASE_DEBUG.
uint64 monotonic_counter()
A monotonically increasing counter, increments are atomic and visible in all threads.
String application_name()
Retrieve the localized program name intended for user display.
StringS string_split(const String &string, const String &splitter, size_t maxn)
Split a string, using splitter as delimiter.
uint64 timestamp_benchmark()
Returns benchmark timestamp in nano-seconds, clock starts around program startup.
std::string executable_path()
Retrieve the path to the currently running executable.
void program_alias_init(String customname)
Set program_alias to a non-localized alias other than program_argv0 if desired.
void application_name_init(String desktopname)
Set the application_name to a name other than program_alias if desired.
std::string anklang_runpath(RPath rpath, const String &segment)
Retrieve various resource paths at runtime.
bool sched_set_priority(int tid, int nicelevel)
Try to set the nice level of process or thread tid to nicelevel.
String program_cwd()
The current working directory during startup.
String anklang_home_dir(const String &subdir)
Get Anklang home dir, possibly adding subdir.
std::string cpu_arch()
Retrieve string identifying the CPU architecture.
bool sched_fast_priority(int tid)
Try to acquire low latency scheduling priority, returns true if nice level is < 0.
String program_alias()
Retrieve the program name as used for logging or debug messages.
const char * ase_version()
Provide a string containing the package version.
std::string String
Convenience alias for std::string.
std::string executable_name()
Retrieve the name part of executable_path().
uint32_t uint
Provide 'uint' as convenience type.
bool string_endswith(const String &string, const String &fragment)
Returns whether string ends with fragment.
int sched_get_priority(int tid)
Retrieve the nice level of process or thread tid.
uint64 timestamp_startup()
Provides the timestamp_realtime() value from program startup.
uint64 timestamp_realtime()
Return the current time as uint64 in µseconds.
String timestamp_format(uint64 stamp, uint maxlength)
Convert stamp into a string, adding µsecond fractions if space permits.
const char * ase_build_id()
Provide a string containing the ASE library build id.
Acquire information about the runtime architecture and CPU type.
Acquire information about a task (process or thread) at runtime.
int priority
Priority or nice value.
String string()
Retrieve string representation of the status information.
uint64 utime
Userspace time.
uint64 ac_stamp
Accounting stamp.
uint64 cutime
Userspace time of dead children.
TaskStatus(int pid, int tid=-1)
Construct from process ID and optionally thread ID.
int processor
Rrunning processor number.
uint64 cstime
System time of dead children.
bool update()
Update status information, might return false if called too frequently.
int process_id
Process ID.
int task_id
Process ID or thread ID.
String name
Thread name (set by user).
#define TASSERT(cond)
Unconditional test assertion, enters breakpoint if not fullfilled.