OS/2 codes: How to get information about CPUs
OS/2 provides various APIs to get information of CPU, from number of CPUs to CPU time snapshot.
1. Number of CPUs
1.1 DosQuerySysInfo( QSV_NUMPROCESSORS )
DosQuerySysInfo() returns the requested system information. If passing QSV_NUMPROCESSORS, number of CPUs are returned to the buffer. Look:
1.2 DosGetProcessorStatus()
DosGetProcessorStatus() returns the status of the given CPU ID starting from 1. If CPU ID is valid, that is, ID-th CPU exists, it returns PROC_ONLINE or PROC_OFFLINE according to the status of that CPU. PROC_ONLINE means that the given CPU is available for running work. PROC_OFFLINE means that the given CPU is not available. Whereas the given CPU does not exist, it returns an error, ERROR_INVALID_PARAMETER. After all, number of CPUs can be caculated if counting from 1 until an error is returned.
If checking the status, it's possible to count workable or not workable CPUs, respectively.
1.3 DosPerfSysCall( 0x41 )
DosPerfSysCall() retrives system performance information. 0x41 command retrives CPU count. Look:
2. CPU time snapshot
CPU monitors show CPU loads. CPU loads are calculated from CPU time snapshots. These snapshots can be got by DosPerfSysCall( 0x63/* CMD_KI_RDCNT */). Look:
pCpuTime is a pointer to the variable of CPUTIME structure. CPUTIME structure looks like:
Note that DosPerfSysCall( 0x63 ) returns the time snapshots of all CPUs. Therefore, it's required to allocate a buffer of enough size to hold those information before calling DosPerfSysCall( 0x63 ). Otherwise, an application may crash.
By the way, OS/2 supports 16 CPUs at most. Because of this, using array of CPUTIME with 16 elements may be a good idea:
3. CPU load
To get CPU load, it's needed to get two different snapshots. The load is the result of dividing idle, busy and intr difference by time difference, respectively. For example, the following is the codes calculating non-irq load of CPU0 which is first CPU:
We've found the various ways to get CPU informations. Those informations may be used for CPU monitors, distributing works in multi-threading environments and so on.
Here is the implementation:
1. Number of CPUs
1.1 DosQuerySysInfo( QSV_NUMPROCESSORS )
DosQuerySysInfo() returns the requested system information. If passing QSV_NUMPROCESSORS, number of CPUs are returned to the buffer. Look:
DosQuerySysInfo( QSV_NUMPROCESSORS, QSV_NUMPROCESSORS,
&ulCpus, sizeof( ulCpus ))
1.2 DosGetProcessorStatus()
DosGetProcessorStatus() returns the status of the given CPU ID starting from 1. If CPU ID is valid, that is, ID-th CPU exists, it returns PROC_ONLINE or PROC_OFFLINE according to the status of that CPU. PROC_ONLINE means that the given CPU is available for running work. PROC_OFFLINE means that the given CPU is not available. Whereas the given CPU does not exist, it returns an error, ERROR_INVALID_PARAMETER. After all, number of CPUs can be caculated if counting from 1 until an error is returned.
for( ulProcId = 1, ulCpuCount = 0; ; ulProcId++ )
{
rc = DosGetProcessorStatus( ulProcId, &ulStatus );
if( rc )
break;
ulCpuCount++;
}
if( ulCpuCount == 0 )
ulCpuCount = 1;
If checking the status, it's possible to count workable or not workable CPUs, respectively.
1.3 DosPerfSysCall( 0x41 )
DosPerfSysCall() retrives system performance information. 0x41 command retrives CPU count. Look:
if( DosPerfSysCall( 0x41, 0, ( ULONG )&ulCpuCount, 0 ))
ulCpuCount = 1;
2. CPU time snapshot
CPU monitors show CPU loads. CPU loads are calculated from CPU time snapshots. These snapshots can be got by DosPerfSysCall( 0x63/* CMD_KI_RDCNT */). Look:
DosPerfSysCall( 0x63, ( ULONG )pCpuTime, 0, 0 );
pCpuTime is a pointer to the variable of CPUTIME structure. CPUTIME structure looks like:
typedef struct tagCPUTIME
{
uint64_t time; /**< total time snapshot */
uint64_t idle; /**< idle time snapshot */
uint64_t busy; /**< busy time snapshot */
uint64_t intr; /**< interrupt time snapshot */
} CPUTIME, *PCPUTIME;
Note that DosPerfSysCall( 0x63 ) returns the time snapshots of all CPUs. Therefore, it's required to allocate a buffer of enough size to hold those information before calling DosPerfSysCall( 0x63 ). Otherwise, an application may crash.
By the way, OS/2 supports 16 CPUs at most. Because of this, using array of CPUTIME with 16 elements may be a good idea:
CPUTIME cpuTime[ 16 ];
DosPerfSysCall( 0x63, ( ULONG )&cpuTime[0], 0, 0 );
3. CPU load
To get CPU load, it's needed to get two different snapshots. The load is the result of dividing idle, busy and intr difference by time difference, respectively. For example, the following is the codes calculating non-irq load of CPU0 which is first CPU:
( current[ 0 ].busy - prev[ 0 ].busy ) /
( current[ 0 ].time - prev[ 0 ].time )
We've found the various ways to get CPU informations. Those informations may be used for CPU monitors, distributing works in multi-threading environments and so on.
Here is the implementation:
- source: https://github.com/komh/os2codes/blob/master/system/cpu.c
- header: https://github.com/komh/os2codes/blob/master/system/cpu.h
- test: https://github.com/komh/os2codes/blob/master/system/cpu-test.c
댓글
댓글 쓰기