⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mk_systrace.cxx

📁 C++ 编写的EROS RTOS
💻 CXX
字号:
/* * Copyright (C) 1998, 1999, Jonathan S. Shapiro. * * This file is part of the EROS Operating System. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2, * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <kerninc/kernel.hxx>#include <kerninc/Key.hxx>#include <kerninc/Invocation.hxx>#include <kerninc/Process.hxx>#include <kerninc/SysTimer.hxx>#include <kerninc/Machine.hxx>#include <kerninc/Thread.hxx>#include <eros/Invoke.h>#include <eros/StdKeyType.h>#include <eros/SysTraceKey.h>extern "C" {  void zapcounters();  uint64_t rdtsc();  uint32_t GetSetupReg();  uint32_t setup_value;};#ifdef OPTION_KERN_STATSKernStats_s  KernStats;#endif#ifdef OPTION_KERN_TIMING_STATSextern uint64_t inv_delta_cy;extern uint32_t inv_delta_reset;extern uint64_t inv_handler_cy;extern uint64_t pf_delta_cy;extern uint64_t kpr_delta_cy;#ifdef OPTION_KERN_EVENT_TRACINGextern uint64_t inv_delta_cnt0;extern uint64_t inv_delta_cnt1;extern uint64_t pf_delta_cnt0;extern uint64_t pf_delta_cnt1;extern uint64_t kpr_delta_cnt0;extern uint64_t kpr_delta_cnt1;#endif#endif#ifdef FAST_IPC_STATSextern uint32_t nFastIpcPath;extern uint32_t nFastIpcFast;extern uint32_t nFastIpcRedSeg;extern uint32_t nFastIpcString;extern uint32_t nFastIpcSmallString;extern uint32_t nFastIpcLargeString;extern uint32_t nFastIpcNoString;extern uint32_t nFastIpcRcvPf;extern uint32_t nFastIpcEnd;extern uint32_t nFastIpcOK;extern uint32_t nFastIpcPrepared;#endifuint32_t src_ok = 0;uint32_t dest_ok = 0;uint32_t copy_ok = 0;uint32_t move_string = 0;uint32_t fast_ok = 0;uint32_t state_ok = 0;uint32_t totmov = 0;uint64_t bytes_moved = 0;voidSysTraceKey(Invocation& inv){  static uint64_t startcy = 0;  static uint64_t startTick = 0ll;  static uint64_t startInvoke = 0ll;  static uint64_t startInter = 0ll;  static int32_t activeMode = 0;  #ifndef OPTION_PURE_EXIT_STRINGS  if (inv.entry.code == OC_SysTrace_ReportCounter)    inv.invokee->SetupExitString(inv, sizeof(struct SysTrace));#endif  COMMIT_POINT();    switch(inv.entry.code) {  case OC_KeyType:    inv.exit.code = RC_OK;    inv.exit.w1 = inv.keyType;    break;  default:    inv.exit.code = RC_UnknownRequest;    break;  case OC_SysTrace_StartCounter:    {      /* Start counted behavior */      startInvoke = KernStats.nInvoke;      startInter = KernStats.nInter;      totmov = move_string = state_ok = fast_ok = 0;      src_ok = dest_ok = copy_ok = 0;       bytes_moved = 0; #ifdef FAST_IPC_STATS      nFastIpcPath = 0;      nFastIpcFast = 0;      nFastIpcRedSeg = 0;      nFastIpcString = 0;      nFastIpcSmallString = 0;      nFastIpcLargeString = 0;      nFastIpcNoString = 0;      nFastIpcRcvPf = 0;      nFastIpcEnd = 0;      nFastIpcOK = 0;      nFastIpcPrepared = 0;#endif#ifdef OPTION_KERN_TIMING_STATS      pf_delta_cy = 0ll;      kpr_delta_cy = 0ll;      inv_delta_cy = 0ll;      inv_delta_reset = 1;      inv_handler_cy = 0ll;#ifdef OPTION_KERN_EVENT_TRACING      pf_delta_cnt0 = 0ll;      pf_delta_cnt1 = 0ll;      kpr_delta_cnt0 = 0ll;      kpr_delta_cnt1 = 0ll;      inv_delta_cnt0 = 0ll;      inv_delta_cnt1 = 0ll;#endif#endif      activeMode = -1;            if (Machine::SetCounterMode(inv.entry.w1) == false) {	inv.exit.code = RC_RequestError;	break;      }            activeMode = inv.entry.w1;            Machine::ClearCounters();      startTick = SysTimer::Now();      startcy = rdtsc();      Machine::EnableCounters();            inv.exit.code = RC_OK;      break;    }  case OC_SysTrace_ReportCounter:    {      struct SysTrace st;      if (activeMode == -1) {	bzero(&st, sizeof(st));	inv.exit.code = RC_NoAccess;	break;      }      Machine::DisableCounters();      uint64_t endcy = rdtsc();      st.mode = activeMode;      st.count0 = Machine::ReadCounter(0);      st.count1 = Machine::ReadCounter(1);      st.cycles = (endcy - startcy);      inv.CopyOut(sizeof(st), &st);            inv.exit.code = RC_OK;      break;    }  case OC_SysTrace_StopCounter:    {      if (activeMode == -1) {	inv.exit.code = RC_NoAccess;	break;      }      Machine::DisableCounters();      uint64_t endcy = rdtsc();      uint64_t cy = endcy - startcy;      uint64_t endInvoke = KernStats.nInvoke - startInvoke;#if 0      uint64_t endIntCount = KernStats.nInter - startInter;#endif    #if 0      printf("startcy 0x%x%08x endcy 0x%x%08x\n",		     (uint32_t) (startcy >> 32),		     (uint32_t) (startcy),		     (uint32_t) (endcy >> 32),		     (uint32_t) (endcy));#endif      const char *modeName = Machine::ModeName(activeMode);      uint64_t cntr0 = Machine::ReadCounter(0);      uint64_t cntr1 = Machine::ReadCounter(1);      printf("Cycles: %13U %-7s S: %13U U+S: %13U IC: %u\n",		     cy,		     modeName, cntr0, cntr1,		     endInvoke);#ifdef FAST_IPC_STATS      printf("FstPth: %u FstFst %u FstNoStr %u FstEnd %u FstOK %u\n",		     nFastIpcPath, nFastIpcFast, nFastIpcNoString,		     nFastIpcEnd, nFastIpcOK);      printf("FstStr: %u FstSmallStr %u FstLrgStr %u FstRcvPf %u\n",		     nFastIpcString, 		     nFastIpcSmallString, 		     nFastIpcLargeString,		     nFastIpcRcvPf);      printf("FstRed: %u  FstPrep %u\n",		     nFastIpcRedSeg, 		     nFastIpcPrepared); #endif#ifdef OPTION_KERN_TIMING_STATS      if (inv_delta_cy)	printf("KeyInv: %13U KeyFn: %13U Kpr: %13U\n",		       inv_delta_cy, inv_handler_cy, kpr_delta_cy);      if (pf_delta_cy)	printf("Pgflt:  %13U\n",		       pf_delta_cy, kpr_delta_cy);#ifdef OPTION_KERN_EVENT_TRACING      if (pf_delta_cnt0)	printf(Evt "KeyInv: %-7s S: %13U U+S: %13U\n",		       modeName,  inv_delta_cnt0, inv_delta_cnt1);      if (pf_delta_cnt0)	printf("Evt Pflt:   %-7s S: %13U U+S: %13U\n",		       modeName,  pf_delta_cnt0, pf_delta_cnt1);      if (kpr_delta_cnt0)	printf("Evt Keeper: %-7s S: %13U U+S: %13U\n",v		       modeName,  kpr_delta_cnt0, kpr_delta_cnt1);#endif#endif#ifdef OPTION_KERN_TIMING_STATS      {	int count = 0;	for (int i = 0; i < KT_NUM_KEYTYPE; i++) {	  uint64_t keycount =	    Invocation::KeyHandlerCounts[i][IT_Call] +	    Invocation::KeyHandlerCounts[i][IT_Reply] + 	    Invocation::KeyHandlerCounts[i][IT_Send];	  uint64_t keycy =	    Invocation::KeyHandlerCycles[i][IT_Call] +	    Invocation::KeyHandlerCycles[i][IT_Reply] + 	    Invocation::KeyHandlerCycles[i][IT_Send];	  if (keycount) {	    printf("  kt%02d: [%8U] %13U",			   i,			   keycount,			   keycy);	    count++;	  }	  if (count == 2) {	    printf("\n");	    count = 0;	  }	}	if (count != 0)	  printf("\n");      }#endif      inv.exit.code = RC_OK;      break;    }  case OC_SysTrace_StopCounterVerbose:    {      if (activeMode == -1) {	inv.exit.code = RC_NoAccess;	break;      }      Machine::DisableCounters();      uint64_t endcy = rdtsc();      uint64_t cy = endcy - startcy;      uint64_t endInter = KernStats.nInter - startInter;      uint64_t endInvoke = KernStats.nInvoke - startInvoke;          const char *modeName = Machine::ModeName(activeMode);      uint64_t cntr0 = Machine::ReadCounter(0);      uint64_t cntr1 = Machine::ReadCounter(1);      uint64_t endTick = SysTimer::Now();      uint64_t dwticks = endTick - startTick;      uint64_t ticks = (uint32_t) dwticks;      uint64_t dms = Machine::TicksToMilliseconds(dwticks);      uint32_t ms = (uint32_t) dms;          printf("Cycles: %13U %-7s S: %13U U+S: %13U IC: %u\n",		     cy,		     modeName,		     cntr0,		     cntr1,		     endInter);#ifdef OPTION_KERN_TIMING_STATS      if (inv_delta_cy)	printf("KeyInv: %13U KeyFn: %13U Kpr: %13U\n",		       inv_delta_cy, inv_handler_cy, kpr_delta_cy);      if (pf_delta_cy)	printf("Pgflt:  %13U\n",		       pf_delta_cy, kpr_delta_cy);#ifdef OPTION_KERN_EVENT_TRACING      if (pf_delta_cnt0)	printf(Evt "KeyInv: %-7s S: %13U U+S: %13U\n",		       modeName,  inv_delta_cnt0, inv_delta_cnt1);      if (pf_delta_cnt0)	printf("Evt Pflt:   %-7s S: %13U U+S: %13U\n",		       modeName,  pf_delta_cnt0, pf_delta_cnt1);      if (kpr_delta_cnt0)	printf("Evt Keeper: %-7s S: %13U U+S: %13U\n",		       modeName,  kpr_delta_cnt0, kpr_delta_cnt1);#endif#endif      printf("  %u ticks %u ms %u stdInvoke: %U\n",		     (uint32_t) ticks, ms, endInvoke);      printf("  state %u fast %u str %u src %u dest %u copy %u move %u\n",		     state_ok, fast_ok, move_string, src_ok, dest_ok,		     copy_ok, totmov);      printf("  bytes moved 0x%08x%08x\n",		     (uint32_t) (bytes_moved>>32), (uint32_t) bytes_moved);#ifdef OPTION_KERN_TIMING_STATS      {	int count = 0;	for (int i = 0; i < PRIMARY_KEY_TYPES; i++) {	  uint64_t keycount =	    Invocation::KeyHandlerCounts[i][IT_Call] +	    Invocation::KeyHandlerCounts[i][IT_Reply] + 	    Invocation::KeyHandlerCounts[i][IT_Send];	  uint64_t keycy =	    Invocation::KeyHandlerCycles[i][IT_Call] +	    Invocation::KeyHandlerCycles[i][IT_Reply] + 	    Invocation::KeyHandlerCycles[i][IT_Send];	  if (keycount) {	    printf("  kt%02d: [%8U] %13U",			   i,			   keycount,			   keycy);	    count++;	  }	  if (count == 2) {	    printf("\n");	    count = 0;	  }	}      }#endif      inv.exit.code = RC_OK;      break;    }  case OC_SysTrace_ClearKstats:    {#ifdef OPTION_KERN_TIMING_STATS      Invocation::ZeroStats();#endif            bzero(&KernStats, sizeof(KernStats));      inv.exit.code = RC_OK;      break;    }  case OC_SysTrace_GetCycle:    {      uint64_t cy = rdtsc();      inv.exit.code = RC_OK;      inv.exit.w1 = (cy >> 32);      inv.exit.w2 = cy;      inv.exit.w3 = 0;    }  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -