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::DEMODIR:
return Path::join (libexec_installdir +
"/media/Demos", segment);
72 case RPath::LADSPADIRS:
return Path::join (construct_ladspa_path(), segment);
78construct_ladspa_path()
82 const char *ladspa_path =
getenv (
"LADSPA_PATH");
84 sp = Path::searchpath_split (ladspa_path);
101 return Path::searchpath_join (sv);
106initialized_ase_gettext_domain()
108 static const char *
const gettexttextdomain = [] () {
109 const char *
const gtdomain = ase_gettext_domain;
111 bind_textdomain_codeset (gtdomain,
"UTF-8");
114 return gettexttextdomain;
119(
_) (
const char *
string)
121 return dgettext (initialized_ase_gettext_domain(),
string);
128 return _ (
string.c_str());
133(
_) (
const char *
string,
const char *plural, int64_t n)
136 const ulong l = u >= 2147483647 ? 2147483647 : u;
137 return dcngettext (initialized_ase_gettext_domain(),
string, plural, l, LC_MESSAGES);
144 return _ (
string.c_str(), plural.c_str(), n);
148namespace AnsiColors {
156 atomic_store (&colorize_cache, colorize);
165 const Colorize colcache = atomic_load (&colorize_cache);
167 const char *ev =
getenv (
"ASE_COLOR");
174 atomic_store (&colorize_cache, Colorize::ALWAYS);
179 atomic_store (&colorize_cache, Colorize::NEVER);
184 atomic_store (&colorize_cache, tty_output ? Colorize::ALWAYS : Colorize::NEVER);
210 case NONE:
return "";
211 case RESET:
return "\033[0m";
212 case BOLD:
return "\033[1m";
213 case BOLD_OFF:
return "\033[22m";
214 case ITALICS:
return "\033[3m";
215 case ITALICS_OFF:
return "\033[23m";
216 case UNDERLINE:
return "\033[4m";
217 case UNDERLINE_OFF:
return "\033[24m";
218 case INVERSE:
return "\033[7m";
219 case INVERSE_OFF:
return "\033[27m";
220 case STRIKETHROUGH:
return "\033[9m";
221 case STRIKETHROUGH_OFF:
return "\033[29m";
222 case FG_BLACK:
return "\033[30m";
223 case FG_RED:
return "\033[31m";
224 case FG_GREEN:
return "\033[32m";
225 case FG_YELLOW:
return "\033[33m";
226 case FG_BLUE:
return "\033[34m";
227 case FG_MAGENTA:
return "\033[35m";
228 case FG_CYAN:
return "\033[36m";
229 case FG_WHITE:
return "\033[37m";
230 case FG_DEFAULT:
return "\033[39m";
231 case BG_BLACK:
return "\033[40m";
232 case BG_RED:
return "\033[41m";
233 case BG_GREEN:
return "\033[42m";
234 case BG_YELLOW:
return "\033[43m";
235 case BG_BLUE:
return "\033[44m";
236 case BG_MAGENTA:
return "\033[45m";
237 case BG_CYAN:
return "\033[46m";
238 case BG_WHITE:
return "\033[47m";
239 case BG_DEFAULT:
return "\033[49m";
255#elif defined __s390__
257#elif defined __m32c__
261#elif defined __m32r__
263#elif defined __x86_64__ || defined __amd64__
265#elif defined __ia64__
266 return "Intel Itanium";
267#elif defined __m68k__
269#elif defined __powerpc__ || defined PPC || defined powerpc || defined __PPC__
275#elif defined __mips__ || defined mips
277#elif defined __tune_i686__ || defined __i686__
279#elif defined __tune_i586__ || defined __i586__
281#elif defined __tune_i486__ || defined __i486__
283#elif defined i386 || defined __i386__
286 return "unknown-arch";
287#warning platform.cc needs updating for this processor type
298 uint x86_fpu : 1, x86_ssesys : 1, x86_tsc : 1, x86_htt : 1;
299 uint x86_mmx : 1, x86_mmxext : 1, x86_3dnow : 1, x86_3dnowext : 1;
300 uint x86_sse : 1, x86_sse2 : 1, x86_sse3 : 1, x86_ssse3 : 1;
301 uint x86_cx16 : 1, x86_sse4_1 : 1, x86_sse4_2 : 1, x86_rdrand : 1;
304static jmp_buf cpu_info_jmp_buf;
306static void ASE_NORETURN
307cpu_info_sigill_handler (
int dummy)
313# define x86_has_cpuid() ({ \
314 unsigned int __eax = 0, __ecx = 0; \
315 __asm__ __volatile__ \
318 "pushf ; pop %0 ; mov %0, %1 \n\t" \
320 "xor $0x200000, %0 ; push %0 ; popf \n\t" \
322 "pushf ; pop %0 \n\t" \
323 : "=a" (__eax), "=c" (__ecx) \
327 bool __result = (__eax ^ __ecx) & 0x00200000; \
331# define x86_cpuid(input, count, eax, ebx, ecx, edx) \
332 __asm__ __volatile__ ( \
334 "mov %%ebx, %%esi \n\t" \
338 "xchg %%ebx, %%esi" \
339 : "=a" (eax), "=S" (ebx), \
340 "=c" (ecx), "=d" (edx) \
341 : "0" (input), "2" (count) \
343#elif defined __x86_64__ || defined __amd64__
349# define x86_has_cpuid() (1)
351# define x86_cpuid(input, count, eax, ebx, ecx, edx) \
352 __asm__ __volatile__ ( \
354 "mov %%rbx, %%rsi \n\t" \
358 "xchg %%rbx, %%rsi" \
359 : "=a" (eax), "=S" (ebx), \
360 "=c" (ecx), "=d" (edx) \
361 : "0" (input), "2" (count) \
364# define x86_has_cpuid() (false)
365# define x86_cpuid(input, count, eax, ebx, ecx, edx) do {} while (0)
369get_x86_cpu_features (
CPUInfo *ci)
371 memset (ci, 0,
sizeof (*ci));
373 if (!x86_has_cpuid ())
377 unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
378 x86_cpuid (0, 0, eax, ebx, ecx, edx);
379 unsigned int v_ebx = ebx, v_ecx = ecx, v_edx = edx;
380 char *vendor = ci->cpu_vendor;
381 *((
unsigned int*) &vendor[0]) = ebx;
382 *((
unsigned int*) &vendor[4]) = edx;
383 *((
unsigned int*) &vendor[8]) = ecx;
387 x86_cpuid (1, 0, eax, ebx, ecx, edx);
391 ci->x86_ssse3 =
true;
395 ci->x86_sse4_1 =
true;
397 ci->x86_sse4_2 =
true;
399 ci->x86_rdrand =
true;
409 ci->x86_mmxext =
true;
421 x86_cpuid (0x80000000, 0, eax, ebx, ecx, edx);
422 if (eax >= 0x80000001 &&
423 v_ebx == 0x68747541 &&
424 v_ecx == 0x444d4163 && v_edx == 0x69746e65)
426 x86_cpuid (0x80000001, 0, eax, ebx, ecx, edx);
428 ci->x86_3dnow =
true;
430 ci->x86_mmxext =
true;
432 ci->x86_3dnowext =
true;
442 action.sa_handler = cpu_info_sigill_handler;
444 action.sa_flags = SA_NOMASK;
445 sigaction (SIGILL, &action, &old_action);
446 if (setjmp (cpu_info_jmp_buf) == 0)
448#if defined __i386__ || defined __x86_64__ || defined __amd64__
450 __asm__ __volatile__ (
"stmxcsr %0 ; sfence ; emms" :
"=m" (mxcsr));
452 ci->x86_ssesys =
true;
469 return get_arch_name();
482 static String cpu_info_string = []() {
484 if (!get_x86_cpu_features (&
cpu_info))
502 info +=
" CMPXCHG16B";
533 return cpu_info_string;
537static clockid_t monotonic_clockid = CLOCK_REALTIME;
538static uint64 monotonic_start = 0;
539static uint64 monotonic_resolution = 1000;
540static uint64 realtime_start = 0;
545 static const bool initialize = [] () {
547 struct timespec tp = { 0, 0 };
548 if (clock_getres (CLOCK_REALTIME, &tp) >= 0)
549 monotonic_resolution = tp.tv_sec * 1000000000ULL + tp.tv_nsec;
550 uint64 mstart = realtime_start;
551#ifdef CLOCK_MONOTONIC
554 if (monotonic_clockid == CLOCK_REALTIME && clock_getres (CLOCK_MONOTONIC, &tp) >= 0)
556 monotonic_clockid = CLOCK_MONOTONIC;
557 monotonic_resolution = tp.tv_sec * 1000000000ULL + tp.tv_nsec;
561 monotonic_start = mstart;
566namespace {
static struct Timestamper { Timestamper() { timestamp_init_(); } } realtime_startup; }
573 return realtime_start;
580 struct timespec tp = { 0, 0 };
582 return tp.tv_sec * 1000000ULL + tp.tv_nsec / 1000;
585 struct timeval now = { 0, 0 };
587 return now.tv_sec * 1000000ULL + now.tv_usec;
596 return monotonic_resolution;
603 struct timespec tp = { 0, 0 };
607 stamp = tp.tv_sec * 1000000000ULL + tp.tv_nsec;
608 stamp -= monotonic_start;
613 stamp -=
std::min (stamp, monotonic_start);
622 const size_t fieldwidth =
std::max (maxlength, 1U);
626 if (r.
size() < fieldwidth)
628 if (r.
size() < fieldwidth)
638 return global_monotonic_counter++;
671 return (end_ - start_) * 0.000001;
678 return (end_ - start_) * 0.001;
693 char system_result[max_size + 1 + 1] = { 0, };
694 ssize_t system_result_size = -1;
696#if defined __linux__ || defined __CYGWIN__ || defined __MSYS__
697 system_result_size =
readlink (
"/proc/self/exe", system_result, max_size);
698 if (system_result_size < 0)
700 strcpy (system_result,
"/proc/self/exe");
701 system_result_size = 0;
703#elif defined __APPLE__
706 if (_NSGetExecutablePath (system_result, &bufsize) == 0 &&
708 system_result_size = bufsize;
712 system_result_size = GetModuleFileNameA (0, system_result, max_size);
713 if (system_result_size <= 0 || system_result_size >= max_size)
714 system_result_size = -1;
717 system_result[system_result_size] = 0;
720 while ((winslash = strchr (system_result,
'\\')) != NULL)
724#error "Platform lacks executable_path() implementation"
727 if (system_result_size < 0)
728 system_result[0] = 0;
736 static std::string cached_executable_path = get_executable_path();
737 return cached_executable_path;
744 static std::string cached_executable_name = [] () {
747 return slash ? slash + 1 : path;
749 return cached_executable_name;
752void fatal_system_error (
const char *file,
uint line,
const char *format, ...) __attribute__ ((__format__ (printf, 3, 4), __noreturn__));
755fatal_system_error (const
char *file,
uint line, const
char *format, ...)
757 const int maxbuffer = 8 * 1024;
758 char buffer[maxbuffer + 2] = { 0, }, *b = buffer, *e = b + maxbuffer;
760 snprintf (b, e - b,
"%s:%u: fatal: ", file, line);
762 snprintf (b, e - b,
"%s: fatal: ", file);
768 const int plen =
vsnprintf (b, e - b, format, argv);
772 if (b > buffer && b[-1] !=
'\n')
775 fputs (buffer, stderr);
783find_text_file (ptrdiff_t symbol_address)
785 const char *
const self_maps =
"/proc/self/maps";
787 maps.
open (self_maps);
793 size_t start = 0,
end = 0, offset = 0, inode = 0, pos = 0;
794 char perms[22 + 1], device[22 + 1] =
"";
795 int count =
sscanf (cxxline.
c_str(),
"%zx-%zx %22s %zx %22s %zu %zn", &start, &end, perms, &offset, device, &inode, &pos);
796 if (count != 6 || pos == 0)
798 if (cxxline[pos] ==
'/' && symbol_address >= start && symbol_address < end &&
799 strncmp (perms,
"r-xp", 4) == 0)
800 return cxxline.
substr (pos);
808determine_anklangsynthengine_installdir (
bool *using_objdir)
811 const ptrdiff_t address = ptrdiff_t (&determine_anklangsynthengine_installdir);
812 String pathname = find_text_file (address);
813 const char *path = pathname.
c_str(), *e =
strrchr (path,
'/');
818 if (strncmp (e,
"/lt-", 4) == 0 &&
819 e - path >= 1 + ods &&
820 e[-(1 + ods)] ==
'/' &&
821 strncmp (e - ods, LIBTOOL_OBJDIR, ods) == 0)
822 pathname = pathname.
substr (0, e - ods - 1 - path);
824 pathname = pathname.
substr (0, e - path);
828 pathname = pathname.
substr (0, pathname.
size() - 4);
829 if (pathname.
empty())
830 fatal_system_error (
"AnklangSynthEngine", 0,
"failed to find executable for symbol: %p", (
void*) address);
837 return ase_version_short;
843 return ase_version_long;
846static String cached_program_alias;
858 cached_program_alias = customname;
861static String cached_application_name;
873 cached_application_name = desktopname;
880 return cached_program_cwd;
886 static_assert (
sizeof (mem_) >=
sizeof (sem_t),
"");
887 sem_t &sem = *(sem_t*) mem_;
888 const int ret =
sem_init (&sem, 0 , 0 );
895 sem_t &sem = *(sem_t*) mem_;
898 return ret ?
errno : 0;
904 sem_t &sem = *(sem_t*) mem_;
907 return ret ?
errno : 0;
910ScopedSemaphore::~ScopedSemaphore () noexcept
912 sem_t &sem = *(sem_t*) mem_;
924 if (level == -1 &&
errno)
925 PDEBUG (
"getpriority(%d) failed: %s", tid,
strerror (
errno));
926 return level == -1 &&
errno ? 0 : level;
934 return setpriority (PRIO_PROCESS, tid, nicelevel) >= 0;
946 const int level = DBus::rtkit_get_min_nice_level();
948 emsg = DBus::rtkit_make_high_priority (tid, level);
951 PDEBUG (
"acquired low latency scheduling for pid=%d: %d", tid,
sched_get_priority (tid));
953 PDEBUG (
"failed to acquire low latency scheduling for pid=%d: %s", tid, emsg);
959 process_id (pid), task_id (tid >= 0 ? tid : pid), state (UNKNOWN), processor (-1), priority (0),
960 utime (0), stime (0), cutime (0), cstime (0),
961 ac_stamp (0), ac_utime (0), ac_stime (0), ac_cutime (0), ac_cstime (0)
967 static long clk_tck = 0;
970 clk_tck =
sysconf (_SC_CLK_TCK);
974 int pid = -1, ppid = -1, pgrp = -1, session = -1, tty_nr = -1, tpgid = -1;
975 int exit_signal = 0, processor = 0;
976 long cutime = 0, cstime = 0, priority = 0,
nice = 0, dummyld = 0;
977 long itrealvalue = 0, rss = 0;
978 unsigned long flags = 0, minflt = 0, cminflt = 0, majflt = 0, cmajflt = 0;
979 unsigned long utime = 0, stime = 0, vsize = 0, rlim = 0, startcode = 0;
980 unsigned long endcode = 0, startstack = 0, kstkesp = 0, kstkeip = 0;
982 unsigned long wchan = 0, nswap = 0, cnswap = 0, rt_priority = 0, policy = 0;
983 unsigned long long starttime = 0;
984 char state = 0, command[8192 + 1] = { 0 };
992 "%lu %lu %lu %lu %lu %lu %lu "
993 "%ld %ld %ld %ld %ld %ld "
995 "%lu %lu %lu %lu %lu "
996 "%lu %lu %lu %lu %lu "
999 &pid, command, &state,
1000 &ppid, &pgrp, &session, &tty_nr, &tpgid,
1001 &flags, &minflt, &cminflt, &majflt, &cmajflt, &utime, &stime,
1002 &cutime, &cstime, &priority, &nice, &dummyld, &itrealvalue,
1003 &starttime, &vsize, &rss,
1004 &rlim, &startcode, &endcode, &startstack, &kstkesp,
1005 &kstkeip, &signal, &blocked, &sigignore, &sigcatch,
1006 &wchan, &nswap, &cnswap, &exit_signal, &processor,
1007 &rt_priority, &policy
1010 const double jiffies_to_usecs = 1000000.0 / clk_tck;
1012 self.
state = TaskStatus::State (state);
1015 self.ac_utime =
utime * jiffies_to_usecs;
1016 self.ac_stime = stime * jiffies_to_usecs;
1020 self.ac_cutime = cutime * jiffies_to_usecs;
1021 self.ac_cstime = cstime * jiffies_to_usecs;
1030#define ACCOUNTING_MSECS 50
1037 if (
ac_stamp + ACCOUNTING_MSECS * 1000 >= now)
1039 if (!update_task_status (*
this))
1041 const double delta = 1000000.0 /
MAX (1, now -
ac_stamp);
1054 string_format (
"pid=%d task=%d state=%c processor=%d priority=%d perc=%.2f%% utime=%.3fms stime=%.3fms cutime=%.3f cstime=%.3f",
1077 for (
auto it = task_registry_tasks_.
begin(); it != task_registry_tasks_.
end(); it++)
1078 if (it->task_id == tid)
1080 task_registry_tasks_.
erase (it);
1090 for (
auto &task : task_registry_tasks_)
1098 return task_registry_tasks_;
1102TaskRegistry::setup_ase (
const String &name16chars)
1107 this_thread_set_name (name16chars);
1120this_thread_set_name (
const String &name16chars)
1122 if (name16chars.
find (
" ") != name16chars.npos)
1128this_thread_get_name ()
1130 char buffer[1024] = { 0, };
1131 pthread_getname_np (
pthread_self(), buffer,
sizeof (buffer) - 1);
1132 buffer[
sizeof (buffer) - 1] = 0;
1137this_thread_getpid ()
1143this_thread_gettid ()
1147 tid = syscall (SYS_gettid);
1150 tid = this_thread_getpid();
1155this_thread_online_cpus ()
1157 static int cpus = 0;
1159 cpus =
sysconf (_SC_NPROCESSORS_ONLN);
1171get_pwd_user (
int uid)
1174 struct passwd spwd = {
nullptr, }, *pp =
nullptr;
1176 if (getpwuid_r (pu.uid, &spwd, buffer, sizeof (buffer), &pp) != 0)
1178 pu.user_name = pp && pp->pw_name && pp->pw_name[0] ? pp->pw_name :
"_unknown";
1179 if (pp && pp->pw_gecos && pp->pw_gecos[0])
1181 memset (buffer, 0,
sizeof (buffer));
1196 return current_user().uid;
1202 return current_user().user_name;
1208 const PwdUser &pu = current_user();
1209 return pu.real_name.
empty() ? pu.user_name : pu.real_name;
1214struct EarlyStartup {
1221static EarlyStartup _early_startup __attribute__ ((init_priority (101)));
1233ase_test_timestamps()
1241 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()
Retrieve string identifying the runtime CPU type.
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)
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.