/* * perfos.c -- Perfos modules. * * Authors : Patrick Lecoanet. * Creation date : * * $Id$ */ /* * Copyright (c) 1993 - 2000 CENA, Patrick Lecoanet -- * * This code is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This code 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this code; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "perfos.h" #include "List.h" #include "Types.h" #include static const char rcsid[] = "$Id$"; static const char compile_id[]="$Compile: " __FILE__ " " __DATE__ " " __TIME__ " $"; static ZnList Chronos = NULL; /* ********************************************************************************** * * HardwareSynchronize - Synchronise Xwindow. * ********************************************************************************** */ static void HardwareSynchronize(Display *test_display, Drawable test_window) { XImage *image; /* Synchronize yourself with the drawing engine by sending a XGetImage one pixel square. */ image = XGetImage(test_display, test_window, 0, 0, 1, 1, ~0, ZPixmap); XDestroyImage(image); } /* ********************************************************************************** * * GetUCTime - Return machine time. This is the sum of user and system * times for the process so far. * ********************************************************************************** */ static long GetUCTime(void) { struct tms time; times(&time); return time.tms_utime + time.tms_stime; } /* ********************************************************************************** * * GetCurrentTime - Return current time. * ********************************************************************************** */ static long GetCurrentTime(void) { struct timeval start; gettimeofday(&start, NULL); return((start.tv_sec * 100) + (start.tv_usec / 10000)); } /* ********************************************************************************** * * XGetCurrentTime - return current time after Xwindow synchronize. * ********************************************************************************** */ static long XGetCurrentTime(Display *display, Drawable window) { HardwareSynchronize(display, window); return(GetCurrentTime()); } /* ********************************************************************************** * * XCorrectionValue - Evaluate the correction value to apply * to counter the client-server round trip * time. * ********************************************************************************** */ static long XCorrectionValue(Display *display, Drawable window) { int i; long start, stop; start = GetCurrentTime(); for (i = 0; i < 5; i++) { HardwareSynchronize(display, window); } stop = GetCurrentTime(); return((stop - start) / 5); } /* ********************************************************************************** * * XStartChrono - Start a perf chrono with X synchronize. * ********************************************************************************** */ void XStartChrono(Chrono chrono, Display *display, Drawable window) { chrono->current_correction = XCorrectionValue(display, window); chrono->current_delay = XGetCurrentTime(display, window); } /* ********************************************************************************** * * XStopChrono - Stop a perf chrono with X synchronize. * ********************************************************************************** */ void XStopChrono(Chrono chrono, Display *display, Drawable window) { chrono->total_delay = chrono->total_delay + (XGetCurrentTime(display, window) - chrono->current_delay - chrono->current_correction); chrono->actions++; } /* ********************************************************************************** * * StartChrono - Start a perf chrono in user time. * ********************************************************************************** */ void StartChrono(Chrono chrono) { chrono->current_delay = GetCurrentTime(); } /* ********************************************************************************** * * StopChrono - Stop a perf chrono in user time. * ********************************************************************************** */ void StopChrono(Chrono chrono) { chrono->total_delay = chrono->total_delay + (GetCurrentTime() - chrono->current_delay); chrono->actions++; } /* ********************************************************************************** * * StartUCChrono - Start a perf chrono in uc time. * ********************************************************************************** */ void StartUCChrono(Chrono chrono) { chrono->current_delay = GetUCTime(); } /* ********************************************************************************** * * StopUCChrono - Stop a perf chrono in uc time. * ********************************************************************************** */ void StopUCChrono(Chrono chrono) { chrono->total_delay = chrono->total_delay + (GetUCTime() - chrono->current_delay); chrono->actions++; } /* ********************************************************************************** * * PrintChronos - Print the currently available stats on all * chronos registered so far. * ********************************************************************************** */ void PrintChronos(void) { int i, cnt; Chrono *chrs; cnt = ZnListSize(Chronos); chrs = (Chrono *) ZnListArray(Chronos); for (i = 0; i < cnt; i++) { if (chrs[i]->actions != 0) { printf("%s : %ld ms on %d times\n", chrs[i]->message, chrs[i]->total_delay * 10 / chrs[i]->actions, chrs[i]->actions); } } } /* ********************************************************************************** * * GetChrono - Return the number of runs and the total time of the Chrono. * ********************************************************************************** */ void GetChrono(Chrono chrono, long *time, int *actions) { if (time) { *time = chrono->total_delay*10; } if (actions) { *actions = chrono->actions; } } /* ********************************************************************************** * * ResetChronos - Reset all chronos or only the specified. * ********************************************************************************** */ void ResetChronos(Chrono chrono) { int i, cnt; Chrono *chrs; if (chrono) { chrono->actions = 0; chrono->total_delay = 0; } else { cnt = ZnListSize(Chronos); chrs = (Chrono *) ZnListArray(Chronos); for (i = 0; i < cnt; i++) { chrs[i]->actions = 0; chrs[i]->total_delay = 0; } } } /* ********************************************************************************** * * NewChrono - Return a new initialized chrono associated with * message. * ********************************************************************************** */ Chrono NewChrono(char *message) { Chrono new; if (!Chronos) { Chronos = ZnListNew(8, sizeof(Chrono)); } new = (Chrono) ZnMalloc(sizeof(ChronoRec)); new->actions = 0; new->total_delay = 0; new->message = message; ZnListAdd(Chronos, &new, ZnListTail); return new; } /* ********************************************************************************** * * FreeChrono - Free the resources of a chrono. * ********************************************************************************** */ void FreeChrono(Chrono chrono) { int i; Chrono *chrs = ZnListArray(Chronos); ZnFree(chrono); for (i = ZnListSize(Chronos)-1; i >= 0; i--) { if (chrs[i] == chrono) { ZnListDelete(Chronos, i); break; } } }