The Gaudi Framework  master (69a68366)
Loading...
Searching...
No Matches
System::ProcessDescriptor Class Reference

Provides access to process information. More...

#include </builds/gaudi/Gaudi/GaudiKernel/src/Lib/ProcessDescriptor.h>

Classes

class  ProcessHandle
 

Public Member Functions

 ProcessDescriptor ()=default
 
virtual ~ProcessDescriptor ()=default
 
long query (long pid, InfoType fetch, PROCESS_BASIC_INFORMATION *info)
 
long query (long pid, InfoType fetch, POOLED_USAGE_AND_LIMITS *info)
 
long query (long pid, InfoType fetch, KERNEL_USER_TIMES *info)
 
long query (long pid, InfoType fetch, QUOTA_LIMITS *info)
 
long query (long pid, InfoType fetch, VM_COUNTERS *info)
 
long query (long pid, InfoType fetch, IO_COUNTERS *info)
 
long query (long pid, InfoType fetch, long *info)
 

Detailed Description

Provides access to process information.

Author
M.Frank
Sebastien Ponce

Definition at line 117 of file ProcessDescriptor.h.

Constructor & Destructor Documentation

◆ ProcessDescriptor()

System::ProcessDescriptor::ProcessDescriptor ( )
default

◆ ~ProcessDescriptor()

virtual System::ProcessDescriptor::~ProcessDescriptor ( )
virtualdefault

Member Function Documentation

◆ query() [1/7]

long System::ProcessDescriptor::query ( long pid,
InfoType fetch,
IO_COUNTERS * info )

Definition at line 348 of file ProcessDescriptor.cpp.

348 {
349 if ( info == 0 ) return 0;
350 long status = 1;
351
352 if ( fetch == IO ) {
353#if defined( __linux )
354 linux_proc prc;
355 readProcStat( processID( pid ), prc );
356 rusage usage;
357 getrusage( RUSAGE_SELF, &usage );
358 info->ReadOperationCount = usage.ru_inblock;
359 info->WriteOperationCount = usage.ru_oublock;
360 info->OtherOperationCount = 0;
361 info->ReadTransferCount = usage.ru_inblock;
362 info->WriteTransferCount = usage.ru_oublock;
363 info->OtherTransferCount = 0;
364#else // All Other
365 if ( pid ) {}
366#endif // End ALL OS
367 }
368 return status;
369}
void readProcStat(long pid, linux_proc &pinfo)

◆ query() [2/7]

long System::ProcessDescriptor::query ( long pid,
InfoType fetch,
KERNEL_USER_TIMES * info )

Definition at line 574 of file ProcessDescriptor.cpp.

574 {
575 if ( info == 0 ) return 0;
576 long status = 1;
577
578 if ( fetch == Times ) {
579#if defined( __linux ) // Linux
580 static long long prc_start = 0;
581 bool myself = pid <= 0 || pid == ::getpid(); // avoid unnecessary calls to getpid if pid<0
582 if ( myself && prc_start == 0 ) { // called only once to set prc_start
583 linux_proc prc;
584 readProcStat( processID( pid ), prc );
585 // prc.startup is in ticks since system start, need to offset for absolute time
586 tms tmsb;
587 static long long offset =
588 100 * static_cast<long long>( time( nullptr ) ) - static_cast<long long>( times( &tmsb ) );
589 prc_start = ( prc.starttime + offset ) * TICK_TO_100NSEC;
590 }
591
592 if ( myself ) { // myself
593 tms tmsb;
594 times( &tmsb );
595 info->UserTime = tmsb.tms_utime * TICK_TO_100NSEC;
596 info->KernelTime = tmsb.tms_stime * TICK_TO_100NSEC;
597 info->CreateTime = prc_start;
598 } else { // other process
599 linux_proc prc;
600 readProcStat( processID( pid ), prc );
601 tms tmsb;
602 static long long offset =
603 100 * static_cast<long long>( time( nullptr ) ) - static_cast<long long>( times( &tmsb ) );
604
605 tms t;
606 times( &t );
607 info->UserTime = t.tms_utime * TICK_TO_100NSEC;
608 info->KernelTime = t.tms_stime * TICK_TO_100NSEC;
609 info->CreateTime = ( prc.starttime + offset ) * TICK_TO_100NSEC;
610 }
611 info->ExitTime = 0;
612
613 status = 1;
614
615#elif defined( __APPLE__ )
616 // Use getrusage for user and kernel times on macOS
617 // Track process start time using a static variable initialized on first call
618 static long long prc_start = 0;
619 if ( prc_start == 0 ) {
620 struct timeval tv;
621 gettimeofday( &tv, nullptr );
622 // Convert to 100-nanosecond units: 1 sec = 10,000,000 units, 1 usec = 10 units
623 prc_start = static_cast<long long>( tv.tv_sec ) * 10000000LL + static_cast<long long>( tv.tv_usec ) * 10LL;
624 }
625
626 struct rusage usage;
627 if ( getrusage( RUSAGE_SELF, &usage ) == 0 ) {
628 // Convert timeval to 100-nanosecond units
629 info->UserTime = static_cast<long long>( usage.ru_utime.tv_sec ) * 10000000LL +
630 static_cast<long long>( usage.ru_utime.tv_usec ) * 10LL;
631 info->KernelTime = static_cast<long long>( usage.ru_stime.tv_sec ) * 10000000LL +
632 static_cast<long long>( usage.ru_stime.tv_usec ) * 10LL;
633 info->CreateTime = prc_start;
634 info->ExitTime = 0;
635 status = 1;
636 } else {
637 status = 0;
638 }
639 (void)pid; // suppress unused parameter warning
640#else // no /proc file system: assume sys_start for the first call
641 tms tmsb;
642 static clock_t sys_start = times( 0 );
643 static long long offset = 100 * long long( time( 0 ) ) - sys_start;
644 clock_t now = times( &tmsb );
645 info->CreateTime = offset + now;
646 info->UserTime = tmsb.tms_utime;
647 info->KernelTime = tmsb.tms_stime;
648 info->CreateTime *= TICK_TO_100NSEC;
649 info->UserTime *= TICK_TO_100NSEC;
650 info->KernelTime *= TICK_TO_100NSEC;
651 info->ExitTime = 0;
652 status = 1;
653#endif
654 }
655
656 return status;
657}
unsigned long long starttime

◆ query() [3/7]

long System::ProcessDescriptor::query ( long pid,
InfoType fetch,
long * info )

Definition at line 408 of file ProcessDescriptor.cpp.

408 {
409
410 if ( info == 0 ) return 0;
411 long status = 1;
412
413 switch ( fetch ) {
414 case PriorityBoost:
415 // Not applicable
416 status = 0;
417 *info = 0;
418 status = ( status == 0 ) ? 1 : 0;
419 break;
420 default:
421 status = -1;
422 *info = -1;
423 break;
424 }
425 return status;
426}
@ PriorityBoost
Definition SystemBase.h:15

◆ query() [4/7]

long System::ProcessDescriptor::query ( long pid,
InfoType fetch,
POOLED_USAGE_AND_LIMITS * info )

Definition at line 371 of file ProcessDescriptor.cpp.

371 {
372 if ( info == 0 ) return 0;
373 long status = 1;
374
375 if ( fetch == Quota ) {
376#if defined( __linux ) // Linux
377 // rusage usage;
378 // getrusage(RUSAGE_SELF, &usage);
379 rlimit lim;
380
381 getrlimit( RLIMIT_DATA, &lim );
382 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
383 info->PeakPagedPoolUsage = lim.rlim_cur;
384 info->PagedPoolUsage = lim.rlim_cur;
385 info->PagedPoolLimit = lim.rlim_max;
386
387 getrlimit( RLIMIT_STACK, &lim );
388 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
389 info->PeakNonPagedPoolUsage = lim.rlim_cur;
390 info->NonPagedPoolUsage = lim.rlim_cur;
391 info->NonPagedPoolLimit = lim.rlim_max;
392
393 linux_proc prc;
394 readProcStat( processID( pid ), prc );
395 info->PeakPagefileUsage = prc.rss * pg_size;
396 info->PagefileUsage = prc.rss * pg_size;
397 info->PagefileLimit = 0xFFFFFFFF;
398#elif defined( __APPLE__ )
399 if ( pid ) {}
400#else // All Other
401 if ( pid ) {}
402#endif // End ALL OS
403 }
404
405 return status;
406}

◆ query() [5/7]

long System::ProcessDescriptor::query ( long pid,
InfoType fetch,
PROCESS_BASIC_INFORMATION * info )

Definition at line 548 of file ProcessDescriptor.cpp.

548 {
549 if ( info == 0 ) return 0;
550 long status = 1;
551
552 if ( fetch == ProcessBasics ) {
553#if defined( __linux ) // Linux
554 linux_proc prc;
555 pid = processID( pid );
556 readProcStat( pid, prc );
557 info->ExitStatus = 0;
558 info->PebBaseAddress = (PPEB)prc.startcode;
559 info->BasePriority = 2 * 15 - prc.priority;
560 // std::cout << "Base Priority=" << info->BasePriority << "|"
561 // << prc.priority << std::endl;
562 info->AffinityMask = prc.flags;
563 // std::cout << "Flags =" << info->AffinityMask << "|"
564 // << prc.flags << std::endl;
565 info->UniqueProcessId = pid;
566 info->InheritedFromUniqueProcessId = prc.ppid;
567#else // All Other
568 if ( pid ) {}
569#endif // End ALL OS
570 }
571 return status;
572}
@ ProcessBasics
Definition SystemBase.h:15
struct _PEB * PPEB
Basic Process Information NtQueryInformationProcess using ProcessBasicInfo.
unsigned long startcode

◆ query() [6/7]

long System::ProcessDescriptor::query ( long pid,
InfoType fetch,
QUOTA_LIMITS * info )

Definition at line 507 of file ProcessDescriptor.cpp.

507 {
508 if ( info == 0 ) return 0;
509 long status = 1;
510
511 if ( fetch == Quota ) {
512#if defined( __linux ) // Linux
513 // On linux all this stuff typically is not set
514 // (ie. rlim_max=RLIM_INFINITY...)
515
516 if ( pid > 0 && pid != ::getpid() ) return 0; // only possible for myself
517
518 rlimit lim;
519 getrlimit( RLIMIT_DATA, &lim );
520 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
521 info->PagedPoolLimit = lim.rlim_max;
522
523 getrlimit( RLIMIT_STACK, &lim );
524 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
525 info->NonPagedPoolLimit = lim.rlim_max;
526 info->MinimumWorkingSetSize = 0;
527
528 getrlimit( RLIMIT_RSS, &lim );
529 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
530 info->MaximumWorkingSetSize = lim.rlim_max;
531
532 getrlimit( RLIMIT_AS, &lim );
533 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
534 info->PagefileLimit = lim.rlim_max;
535
536 getrlimit( RLIMIT_CPU, &lim );
537 if ( lim.rlim_max == RLIM_INFINITY ) lim.rlim_max = 0xFFFFFFFF;
538 info->TimeLimit = lim.rlim_max;
539#elif defined( __APPLE__ )
540 if ( pid ) {}
541#else // All Other
542 if ( pid ) {}
543#endif // End ALL OS
544 }
545 return status;
546}

◆ query() [7/7]

long System::ProcessDescriptor::query ( long pid,
InfoType fetch,
VM_COUNTERS * info )

Definition at line 428 of file ProcessDescriptor.cpp.

428 {
429 if ( info == 0 ) return 0;
430 long status = 1;
431
432 if ( fetch == Memory ) {
433#if defined( __linux ) // Linux
434 const ssize_t bufsize = 1024;
435 char buf[bufsize];
436 pid = processID( pid );
437 snprintf( buf, sizeof( buf ), "/proc/%ld/statm", pid );
438 long size, resident, share, trs, lrs, drs, dt;
439 int fd = open( buf, O_RDONLY );
440 ssize_t nread = read( fd, buf, bufsize );
441 close( fd );
442 if ( nread < bufsize && nread >= 0 ) buf[nread] = '\0';
443 fd = sscanf( buf, "%ld %ld %ld %ld %ld %ld %ld", &size, &resident, &share, &trs, &drs, &lrs, &dt );
444 linux_proc prc;
445 readProcStat( pid, prc );
446 info->PeakVirtualSize = prc.vsize;
447 info->VirtualSize = prc.vsize;
448 info->PeakWorkingSetSize = resident * pg_size;
449 info->WorkingSetSize = resident * pg_size;
450 info->QuotaPeakPagedPoolUsage = share * pg_size;
451 info->QuotaPagedPoolUsage = share * pg_size;
452 info->QuotaNonPagedPoolUsage = ( trs + drs ) * pg_size; // drs = data/stack size
453 info->QuotaPeakNonPagedPoolUsage = ( trs + drs ) * pg_size; // trs = VmExe size
454 info->PageFaultCount = prc.majflt + prc.minflt;
455 info->PagefileUsage = prc.vsize - resident * pg_size;
456 info->PeakPagefileUsage = prc.vsize - resident * pg_size;
457#elif defined( __APPLE__ )
458 // Use Mach API to get memory information on macOS
459 // Note: We can only query our own task reliably without special entitlements
460 mach_task_basic_info_data_t taskInfo;
461 mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
462
463 kern_return_t kr = task_info( mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&taskInfo, &infoCount );
464 if ( kr == KERN_SUCCESS ) {
465 info->VirtualSize = taskInfo.virtual_size;
466 info->PeakVirtualSize = taskInfo.virtual_size; // macOS doesn't track peak, use current
467 info->WorkingSetSize = taskInfo.resident_size;
468 info->PeakWorkingSetSize = taskInfo.resident_size_max;
469 info->QuotaPagedPoolUsage = 0;
470 info->QuotaPeakPagedPoolUsage = 0;
471 info->QuotaNonPagedPoolUsage = 0;
472 info->QuotaPeakNonPagedPoolUsage = 0;
473 info->PagefileUsage = taskInfo.virtual_size - taskInfo.resident_size;
474 info->PeakPagefileUsage = taskInfo.virtual_size - taskInfo.resident_size;
475
476 // Get page fault count from getrusage (not available in task_info)
477 struct rusage usage;
478 if ( getrusage( RUSAGE_SELF, &usage ) == 0 ) {
479 info->PageFaultCount = static_cast<unsigned long>( usage.ru_majflt + usage.ru_minflt );
480 } else {
481 info->PageFaultCount = 0;
482 }
483 status = 1;
484 } else {
485 // Zero out the struct on failure so we don't return garbage
486 info->VirtualSize = 0;
487 info->PeakVirtualSize = 0;
488 info->WorkingSetSize = 0;
489 info->PeakWorkingSetSize = 0;
490 info->PageFaultCount = 0;
491 info->QuotaPagedPoolUsage = 0;
492 info->QuotaPeakPagedPoolUsage = 0;
493 info->QuotaNonPagedPoolUsage = 0;
494 info->QuotaPeakNonPagedPoolUsage = 0;
495 info->PagefileUsage = 0;
496 info->PeakPagefileUsage = 0;
497 status = 0;
498 }
499 (void)pid; // suppress unused parameter warning
500#else // All Other
501 if ( pid ) {}
502#endif // End ALL OS
503 }
504 return status;
505}
constexpr auto size(const T &, Args &&...) noexcept
read(f, regex=".*", skipevents=0)
unsigned long vsize
unsigned long majflt
unsigned long minflt

The documentation for this class was generated from the following files: