#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <conio.h>
#include <io.h>
/* прототипы используемых функций */
__int64  round_msec(__int64 time);
void sys_time(char *str);
void proc_stat(char * print, __int64 &Tall, __int64 &Tcpu, __int64 &Twait, double &Pusing);
/***********************************/

/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/* процедура имитирует "фоновый" процесс - CPU burst ......              */
/*                                                                       */
/*************************************************************************/
void fon_proc(long int k, int print)
/*************************************************************************/
{ double x=0.9, y; long int i,j;
  for(j=0; j<k; j++)
       {   y= exp(x);
           if (print == 1){
               printf(" %20d  %g \n",j, y);
               if  ( (kbhit() != 0) && (getch() == 27) )  return;
                           };
       };
  return;  
}
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/
/* входные параметры - 1-й параметр - сколько раз повторить в цикле      */
/*                                    подпрограмму моделирующюю процесс  */
/*                                    (умолчание = 1)                    */
/*                     2-й параметр - его присутствие требует от         */          
/*                                    подпрограммы модели процесса       */
/*                                    выполнять вывод на консоль.        */
/*************************************************************************/
int main(int argc, char *argv[])
/*************************************************************************/
{
  __int64 Tall, Tcpu,  Twait; double Pusing;
    int kmax;
    int p1;
   sys_time("Начало процесса ");
  if (argc <= 1 ) kmax=1; else  sscanf(argv[1], "%d" , &kmax);

  if (argc <= 2 ) p1=0; else  p1=1;

  printf("коэффициент повторения цикла CPU burst k=%d\n", kmax);
  printf("=============Начали.....\n"); 
  for(int k=1; k<=kmax; k++)
  {
     fon_proc(0x0007FFFF, p1);
     //Sleep(2000);
     if  ( (kbhit() != 0) && (getch() == 27) )  break;
   };
  printf("=============Кончили..................\n");

  proc_stat("PRINT", Tall,  Tcpu,  Twait,  Pusing);

  sys_time("Конец процесса ");

  getchar();
  return 0;
}          

/**************************************************************************/
/* округляет 100 доли наносекунд в милисекунды                            */
/* вход  - время 100 долях наноСек (в формате двойного слова __int64)     */
/* выход - время милиСек (в формате двойного слова __int64)               */  
/*                                                                        */
/**************************************************************************/
__int64  round_msec(__int64 time)
/**************************************************************************/
{
   __int64 msec;
     int  ost_msec;
   msec=time/10; 
   ost_msec=(int) (time-msec*10);
   if (ost_msec >= 5 ) msec=msec+1;
   return msec; 
};
/*************************************************************************/
/* выводит на cout значение системного времени в виде                    */
/* str "Час=%02d, Мин=%02d, Сек=%02d, милиСек=%03d\n"                        */
/* вход  - str - текстовая строка                                        */
/* выход - void                                                          */
/*                                                                       */
/*************************************************************************/
void sys_time(char *str)
/*************************************************************************/
{
  SYSTEMTIME  SystemTime;  // текущее астрономическое время
 /*  получить астрономическое время....  */
 GetSystemTime(&SystemTime); //The GetSystemTime function retrieves the current 
                          //system date and time. 
                          //The system time is expressed in Coordinated Universal Time (UTC). 
 printf("%s", str);
 printf( " Час=%02d, Мин=%02d, Сек=%02d, милиСек=%03d\n", 
               SystemTime.wHour, 
               SystemTime.wMinute, 
               SystemTime.wSecond, 
               SystemTime.wMilliseconds
             );
   return;
};
/******************************************************************************/
/******************************************************************************/
/* выводит на cout значения:                                                  */
/*                       1) затраченного процессорного времени  Tcpu          */
/*                          от начала выполнения текущего процесса            */
/*                          до момента вызова этой процедуры                  */
/*                       2) затраченного астрономическогого времени Tall      */
/*                          от начала выполнения текущего процесса            */
/*                          до момента вызова этой процедуры                  */
/*                       3) значение времени нахождения процесса в  Twait     */
/*                          не активном состоянии                             */
/*                          от начала выполнения текущего процесса            */
/*                          до момента вызова этой процедуры                  */
/*                       4) процент использования процессора - отношение      */
/*                           (double) Pusing=(Tcpu/Tall)*100%                 */
/*                                                                            */
/* время выводится в микросекундах (хранится в формате двойного слова __int64)*/
/*                                                                            */
/* вход   -  1-й параметр может принимать значение                            */
/*           "PRINT" -  выводить значение времени, "NOPRINT" - не выводить    */
/*            (при др. значении параметра - не выводить)                      */  
/*                                                                            */
/*           2-й, 3-й, 4-й и 5-й  параметры - выходные - ссылки на            */
/*                           &Tall, &Tcpu, &Twait, &Pusing                    */
/* возвращаемых значений нет (void)                                           */
/******************************************************************************/
void proc_stat(char * print, __int64 &Tall, __int64 &Tcpu, __int64 &Twait, double &Pusing)
/******************************************************************************/
{
   HANDLE hProcess;  
   // The FILETIME structure is a 64-bit value representing the number of 100-nanosecond
   FILETIME CreationTime;	// when the process was created
   FILETIME ExitTime;		// when the process exited 
   FILETIME KernelTime;		// time the process has spent in kernel mode 
   FILETIME UserTime;	 	// time the process has spent in user mode 

   SYSTEMTIME  SysTime;         // текущее астрономическое время
//   unsigned __int64 x,y;
   unsigned __int64 vTall, vTcpu, vTwait;
   double  vPusing, temp;

   FILETIME Start, Stop;

   union { FILETIME x; unsigned __int64 ix;};
   union { FILETIME y; unsigned __int64 iy;};
 //  union { FILETIME z; unsigned __int64 iz;};
   union {
         FILETIME time;
         unsigned __int64 itime;
         };
   /*The GetCurrentProcess function returns a pseudohandle for the current process.*/
   hProcess=GetCurrentProcess();
   if (  ! GetProcessTimes(
                            hProcess,		// specifies the process of interest 
                            &CreationTime,	// when the process was created
                            &ExitTime,		// when the process exited 
                            &KernelTime,	// time the process has spent in kernel mode 
                            &UserTime 		// time the process has spent in user mode 
                                      )
           ) { printf("***** Error in GetProcessTimes(proc_stat) *******\n"); exit (666);};
   Start=CreationTime;  //время старта процесса.....   в 100 долях наносек.
   x=KernelTime;  // ix=itime;
   y=UserTime;   //  iy=itime;
   itime=ix+iy;
   vTcpu=itime;  // время использования процессора  100 доли наносек.

   /*  получить астрономическое время....  */
   GetSystemTime(&SysTime);
   /* преобразовать в форму FILETIME и запомнить в Stop  */
   if ( ! SystemTimeToFileTime(
                                &SysTime,	// address of system time to convert 
                                &Stop 	// address of buffer for converted file time 
                                ) ) { printf("***** Error in SystemTimeToFileTime(proc_stat) *****\n");  
                                         exit(666);
                                       };
     
   x=Stop;   // ix= время стопа   в 100 наносекундах.
   y=Start;  // iy= время старта  в 100 наносекундах.
   vTall=ix-iy; // астрономическое время в 100 наносекундах.

   vTwait=vTall-vTcpu; // время ожидания в 100 наносекундах.

   if (vTall != 0)  vPusing =  100 * (double) vTcpu/ (double) vTall;
              else  vPusing =  100.0; 

   vTcpu=  round_msec(vTcpu);
   vTwait= round_msec(vTwait);
   vTall = round_msec(vTall);

  if (strcmp("PRINT", print) == 0 )
    {
      temp=(double) vTcpu / 1000000l;
      printf("***** cpuTime    = %10I64d микроСек (%lf сек)\n", vTcpu, temp);
      temp=(double) vTwait / 1000000l;
      printf("***** waitTime   = %10I64d микроСек (%lf сек)\n", vTwait, temp);
      temp=(double) vTall / 1000000l;
      printf("***** AllprocTime= %10I64d микроСек (%lf сек)\n", vTall, temp);
      //printf("\n");
      printf("***** Process CPU using  = %lf \% \n", vPusing);
    };

  Tcpu=vTcpu;
  Twait=vTwait;
  Tall=vTall;
  Pusing=vPusing;
  return;
};
                  		