| 1 |
|
|---|
| 2 | #define INCL_DOS
|
|---|
| 3 | #include <os2.h>
|
|---|
| 4 |
|
|---|
| 5 | #include <errno.h>
|
|---|
| 6 | #include <sys/types.h>
|
|---|
| 7 | #include <sys/resource.h>
|
|---|
| 8 | #include <stdio.h>
|
|---|
| 9 | #include <time.h>
|
|---|
| 10 |
|
|---|
| 11 | //#include "procstat.h"
|
|---|
| 12 |
|
|---|
| 13 | #define BUFFER_SIZE 64*1024
|
|---|
| 14 |
|
|---|
| 15 | static ULONG timer_interval;
|
|---|
| 16 |
|
|---|
| 17 | //APIRET APIENTRY DosQuerySysState (ULONG EntityList, ULONG EntityLevel,
|
|---|
| 18 | // PID pid, TID tid, PVOID pDataBuf, ULONG cbBuf)
|
|---|
| 19 | int get_proc_state( int pid, struct rusage *usage)
|
|---|
| 20 | {
|
|---|
| 21 | APIRET rc;
|
|---|
| 22 | char* buffer;
|
|---|
| 23 | qsPtrRec_t* qsPtrRec;
|
|---|
| 24 | qsPrec_t* qsPrec;
|
|---|
| 25 | qsTrec_t* qsTrec;
|
|---|
| 26 | ULONG usertime = 0;
|
|---|
| 27 | ULONG systime = 0;
|
|---|
| 28 | int i;
|
|---|
| 29 | double u, s;
|
|---|
| 30 |
|
|---|
| 31 | // query OS interval timer
|
|---|
| 32 | if (timer_interval == 0)
|
|---|
| 33 | DosQuerySysInfo(QSV_TIMER_INTERVAL, QSV_TIMER_INTERVAL,
|
|---|
| 34 | (PVOID)&timer_interval, sizeof(ULONG));
|
|---|
| 35 |
|
|---|
| 36 | // allocate memory
|
|---|
| 37 | buffer = malloc( BUFFER_SIZE);
|
|---|
| 38 | if (buffer == 0)
|
|---|
| 39 | return -1;
|
|---|
| 40 |
|
|---|
| 41 | // get pid process informations (process and threads)
|
|---|
| 42 | rc = DosQuerySysState( QS_PROCESS, 0, pid, 0, buffer, BUFFER_SIZE);
|
|---|
| 43 | if (rc) {
|
|---|
| 44 | free( buffer);
|
|---|
| 45 | return -1;
|
|---|
| 46 | }
|
|---|
| 47 |
|
|---|
| 48 | // evaluate list
|
|---|
| 49 | qsPtrRec = buffer; // global structure
|
|---|
| 50 | qsPrec = qsPtrRec->pProcRec; // process data
|
|---|
| 51 | //printf( "buffer %d\n", buffer);
|
|---|
| 52 | //printf( "qsPrec.RecType %d\n", qsPrec->RecType);
|
|---|
| 53 | //printf( "qsPrec.pid %d\n", qsPrec->pid);
|
|---|
| 54 |
|
|---|
| 55 | qsTrec = qsPrec->pThrdRec; // thread data
|
|---|
| 56 | // sum u/s time for every thread
|
|---|
| 57 | for( i=0; i<qsPrec->cTCB; i++) {
|
|---|
| 58 | //printf( "qsTrec.RecType %d\n", qsTrec[i].RecType);
|
|---|
| 59 | //printf( "qsTrec.tid %d\n", qsTrec[i].tid);
|
|---|
| 60 | usertime += qsTrec[i].usertime;
|
|---|
| 61 | systime += qsTrec[i].systime;
|
|---|
| 62 | }
|
|---|
| 63 | //printf( "usertime %d\n", usertime);
|
|---|
| 64 | //printf( "systime %d\n", systime);
|
|---|
| 65 |
|
|---|
| 66 | // convert timer units into seconds/microseconds
|
|---|
| 67 | u = 10.0 * usertime / timer_interval;
|
|---|
| 68 | s = 10.0 * systime / timer_interval;
|
|---|
| 69 | usage->ru_utime.tv_sec = u;
|
|---|
| 70 | usage->ru_utime.tv_usec = (u - usage->ru_utime.tv_sec) * 1000000;
|
|---|
| 71 | usage->ru_stime.tv_sec = s;
|
|---|
| 72 | usage->ru_stime.tv_usec = (s - usage->ru_stime.tv_sec) * 1000000;
|
|---|
| 73 |
|
|---|
| 74 | free(buffer);
|
|---|
| 75 | }
|
|---|
| 76 |
|
|---|
| 77 | int getrusage(int who, struct rusage *usage)
|
|---|
| 78 | {
|
|---|
| 79 |
|
|---|
| 80 | // only RUSAGE_SELF is supported!
|
|---|
| 81 | if (who != RUSAGE_SELF) {
|
|---|
| 82 | errno = EINVAL;
|
|---|
| 83 | return -1;
|
|---|
| 84 | }
|
|---|
| 85 |
|
|---|
| 86 | // internal query failed
|
|---|
| 87 | if (get_proc_state( getpid(), usage) == -1) {
|
|---|
| 88 | errno = EINVAL;
|
|---|
| 89 | return -1;
|
|---|
| 90 | }
|
|---|
| 91 |
|
|---|
| 92 | return 0;
|
|---|
| 93 | }
|
|---|
| 94 |
|
|---|
| 95 | #ifdef MAIN
|
|---|
| 96 |
|
|---|
| 97 | void main( void)
|
|---|
| 98 | {
|
|---|
| 99 | struct rusage ru;
|
|---|
| 100 | clock_t t1, t2;
|
|---|
| 101 |
|
|---|
| 102 | while( 1) {
|
|---|
| 103 | printf( "clock %d\n", clock());
|
|---|
| 104 | getrusage( RUSAGE_SELF, &ru);
|
|---|
| 105 | printf( "ru %d,%d\n", ru.ru_utime.tv_sec, ru.ru_utime.tv_usec);
|
|---|
| 106 | t1 = clock();
|
|---|
| 107 | while( clock()-t1<CLOCKS_PER_SEC)
|
|---|
| 108 | ;
|
|---|
| 109 | //DosSleep(1*1000);
|
|---|
| 110 | }
|
|---|
| 111 | }
|
|---|
| 112 |
|
|---|
| 113 | #endif
|
|---|
| 114 |
|
|---|