1 /*==========================================================================
2 SeqAn - The Library for Sequence Analysis
4 ============================================================================
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 3 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 ============================================================================
18 $Id: basic_profile.h,v 1.1 2008/08/25 16:20:02 langmead Exp $
19 ==========================================================================*/
21 //SEQAN_NO_GENERATED_FORWARDS: no forwards are generated for this file
23 #ifndef SEQAN_HEADER_BASIC_PROFILE_H
24 #define SEQAN_HEADER_BASIC_PROFILE_H
26 // todo: substitute defines with inlines
29 #define SEQAN_PROSET(i,v)
30 #define SEQAN_PROADD(i,v)
31 #define SEQAN_PROSUB(i,v)
32 #define SEQAN_PROVAL(i) 0
33 #define SEQAN_PROEXTRAS(i)
34 #define SEQAN_PROMARK(m)
35 #define SEQAN_PROENDMARK(m)
36 #define SEQAN_PRORESET
37 #define SEQAN_PROGETTIME 0
38 #define SEQAN_PROTIMESTART(a)
39 #define SEQAN_PROTIMEDIFF(a) 0
40 // replace malloc and free in external tools
41 // with SEQAN_PROMALLOC and SEQAN_PROFREE to profile
43 #define SEQAN_PROMALLOC(s) malloc(s)
44 #define SEQAN_PROFREE(p) free(p)
48 #define SEQAN_PROSET(i,v) _proSet(i,v)
49 #define SEQAN_PROADD(i,v) _proAdd(i,v)
50 #define SEQAN_PROSUB(i,v) _proSub(i,v)
51 #define SEQAN_PROVAL(i) (_proData<>::_proValue[i])
52 #define SEQAN_PROEXTRAS(i) {_proData<>::_proExtraCount = i;}
53 #define SEQAN_PROMARK(m) _proMark(m)
54 #define SEQAN_PROENDMARK(m) _proEndMark(m)
55 #define SEQAN_PRORESET _proReset()
56 #define SEQAN_PROGETTIME sysTime()
57 #define SEQAN_PROTIMESTART(a) _proFloat a = sysTime()
58 #define SEQAN_PROTIMEDIFF(a) (sysTime() - a)
59 #define SEQAN_PROMALLOC(s) _proMalloc(s)
60 #define SEQAN_PROFREE(p) _proFree(p)
64 #ifdef PLATFORM_WINDOWS
65 typedef __int64 _proInt;
67 typedef int64_t _proInt;
70 typedef double _proFloat;
73 typedef _proFloat _proTValue;
76 SEQAN_PROPAGESIZE = 4096, // B in byte
80 SEQAN_PROTYPEMASK = 3,
87 SEQAN_PROMEMORY = 2, // current memory usage (state value)
88 SEQAN_PROIO = 3, // IOs done (measured in Blocks of size B)
89 SEQAN_PROIORANDOM = 4, // IOs calls done (read/write calls done)
90 SEQAN_PROIOVOLUME = 5, // current disk usage (state value)
91 SEQAN_PRODEPTH = 6, // algorithmic rec. depth or loop count
92 SEQAN_PROOPENFILES = 7, // currently opened files
93 SEQAN_PROIWAIT = 8, // waiting time (initiating)
94 SEQAN_PROCWAIT = 9, // waiting time (completing)
98 SEQAN_PROINDEXCOUNT = 13,
99 SEQAN_PROEXTRACOUNT = 3
102 const char _proValueType[] = {
105 SEQAN_PROINT + SEQAN_PROSTATE,
108 SEQAN_PROINT + SEQAN_PROSTATE,
109 SEQAN_PROINT + SEQAN_PROSTATE,
110 SEQAN_PROINT + SEQAN_PROSTATE,
113 SEQAN_PROFLOAT + SEQAN_PROSTATE,
114 SEQAN_PROFLOAT + SEQAN_PROSTATE,
115 SEQAN_PROFLOAT + SEQAN_PROSTATE
118 typedef _proTValue _proTStates[SEQAN_PROINDEXCOUNT];
119 typedef _proFloat _proTTimes[SEQAN_PROINDEXCOUNT];
125 template <typename T = void>
128 static _proTStates _proValue;
129 static _proTTimes _proLastUpdate;
130 static int _proExtraCount;
132 static clock_t _proCpuTimeLast; // clock_t wraps around every 72mins
133 static _proInt _proCpuTimeOffset; // we have to work around this
135 static _proFile* _proPFile;
136 static _proFile* _proPFileStream;
139 template <typename T> _proTStates _proData<T>::_proValue = {};
140 template <typename T> _proTStates _proData<T>::_proLastUpdate = {};
141 template <typename T> int _proData<T>::_proExtraCount = 0;
142 template <typename T> clock_t _proData<T>::_proCpuTimeLast = 0;
143 template <typename T> _proInt _proData<T>::_proCpuTimeOffset = 0;
144 template <typename T> _proFile* _proData<T>::_proPFile = NULL;
145 template <typename T> _proFile* _proData<T>::_proPFileStream = NULL;
148 inline _proFile* & _proPFile() { return _proData<>::_proPFile; }
149 inline _proFile* & _proPFileStream() { return _proData<>::_proPFileStream; }
152 // HINT: The unit of all time functions is second.
153 inline _proFloat cpuTime() {
154 clock_t now = clock();
155 if (_proData<>::_proCpuTimeLast > now) { // test for time wrap
156 _proData<>::_proCpuTimeOffset += (~0u); // got one
157 _proData<>::_proCpuTimeOffset ++;
158 // printf("\n!!WRAP!! old:%d, now:%d ofs:%d\n",_proData<>::_proCpuTimeLast,now,_proData<>::_proCpuTimeOffset);
160 _proData<>::_proCpuTimeLast = now;
161 return (_proData<>::_proCpuTimeOffset + now) / (_proFloat)CLOCKS_PER_SEC;
164 #ifdef PLATFORM_WINDOWS
165 // inline _proFloat sysTime() { return GetTickCount() * 1e-3; }
166 inline _proFloat sysTime() { return ( (_proFloat) clock() ) / CLOCKS_PER_SEC; }
170 #if _POSIX_TIMERS > 0
171 #ifndef SEQAN_USE_CLOCKGETTIME
172 #define SEQAN_USE_CLOCKGETTIME
176 #ifndef SEQAN_USE_CLOCKGETTIME
177 /* some systems e.g. darwin have no clock_gettime */
179 #include <sys/time.h>
181 inline _proFloat sysTime() {
183 gettimeofday(&tp, NULL);
184 return tp.tv_sec + tp.tv_usec * 1e-6;
189 inline _proFloat sysTime() {
190 /*struct timespec tp;
191 clock_gettime(CLOCK_MONOTONIC, &tp);
192 return tp.tv_sec + tp.tv_nsec * 1e-9;*/
193 return 0; // BTL: to compile under cygwin
206 _proFloat dumpStep; // 0 .. manual dump mode, >0 .. live stream
209 _proTStates all, last;
217 _proFile(char const *fname, _proFloat _dumpStep = 300.0) { // five minutes default dump interval
219 start(fname, _dumpStep);
226 inline void start(char const *fname, _proFloat _dumpStep = 300.0, bool append = false) {
228 out = fopen(fname, "a");
230 out = fopen(fname, "w");
234 if (!out) printf("WARNING: proFile could not be opened.\n");
236 setTime(_proData<>::_proValue);
241 dumpStep = _dumpStep;
242 dumpNext = sysTime();
250 mark = "Zusammenfassung";
257 inline void syncTime(_proTStates &dst) {
258 memcpy(dst, _proData<>::_proValue, 2 * sizeof(_proTValue));
261 inline void sync(_proTStates &dst) {
262 memcpy(&(dst[2]), &(_proData<>::_proValue[2]), sizeof(_proTStates) - 2 * sizeof(_proTValue));
265 inline void syncAll(_proTStates &dst) {
266 memcpy(dst, _proData<>::_proValue, sizeof(_proTStates));
269 inline static void setTime(_proTStates &dst) {
274 inline void maximize(_proTStates &dst, _proTStates const &src) {
275 for(int i = 0; i < SEQAN_PROINDEXCOUNT; ++i)
276 if (((_proValueType[i] & SEQAN_PROSTATE) != 0))
281 inline void dumpTab() {
287 inline void dumpEndl() { fprintf(out, "\n"); }
289 inline void dumpHeader() {
290 fprintf(out, "\"Echtzeit\"\t\"CPU-Zeit\"\t\"Speicher\"\t\"I/O-Zugriffe\"\t\"wahlfreie I/Os\"\t\"I/O-Volumen\"\t\"Rekursionstiefe\"\t\"Offene Dateien\"\t\"Idle-Zeit vor I/O\"\t\"Idle-Zeit nach I/O\"\n");
293 inline void dumpTime(_proFloat seconds) {
298 int secs = (int)seconds;
299 int mins = secs/60; secs -= 60*mins;
300 int hours = mins/60; mins -= 60*hours;
301 fprintf(out, "%d:%02d:%02d", hours, mins, secs);
304 inline void dumpTimeEx(_proFloat seconds) {
305 int milli = (int)(seconds * 1000.0);
306 int secs = (int)seconds;
307 int mins = secs/60; secs -= 60*mins;
308 int hours = mins/60; mins -= 60*hours;
309 fprintf(out, "%d:%02d:%02d.%03d", hours, mins, secs, milli);
312 inline void dumpValue(_proTStates &stat, int valNum) {
313 _proFloat f = stat[valNum];
314 if ((_proValueType[valNum] & SEQAN_PROSTATE) == 0)
315 f = _proData<>::_proValue[valNum] - f;
317 switch (_proValueType[valNum] & SEQAN_PROTYPEMASK) {
318 case SEQAN_PROINT: // state value -> print last seen maximum
319 fprintf(out, "%.0f", f);
323 fprintf(out, "%f", f);
331 inline void dumpSysValues(_proTStates &stat) {
332 for(int i = 0; i < SEQAN_PROINDEXCOUNT - SEQAN_PROEXTRACOUNT; ++i) {
338 inline void dumpExtraValues(_proTStates &stat) {
339 for(int i = 0; i < _proData<>::_proExtraCount; ++i) {
341 dumpValue(stat, SEQAN_PROINDEXCOUNT - SEQAN_PROEXTRACOUNT + i);
345 inline void dumpMark() {
348 fprintf(out, "\"%s\"", mark.c_str());
353 inline void dump(_proTStates &stat) {
354 setTime(_proData<>::_proValue);
355 dumpNext += dumpStep;
357 bool _flush = ((dumpStep == 0.0)) || ((lines & 16) == 0);
360 dumpExtraValues(stat);
363 if (_flush) fflush(out);
367 inline void signalDumpTest(_proFloat now) {
368 if (dumpStep > 0 && now > dumpNext && running) {
375 inline void signalNewMax(int valNum) {
377 if (last[valNum] < _proData<>::_proValue[valNum])
378 last[valNum] = _proData<>::_proValue[valNum];
381 inline void setMark(const char *text) {
384 if (dumpStep == 0.0) {
385 dump(last); // manual dump;
392 inline void reset() {
396 inline void setEndMark(const char *text) {
405 bool bol; // begin of line
411 inline void _proSignalDumpTest(_proFloat now);
412 inline void _proSignalNewMax(int valNum);
413 inline void _proMark(const char *text);
414 inline void _proEndMark(const char *text);
415 inline void _proReset();
417 inline void _proSet(int valNum, _proFloat value);
418 inline void _proAdd(int valNum, _proFloat value);
419 inline void _proSub(int valNum, _proFloat value);
421 // simple interface for external programs
422 inline void *_proMalloc(size_t size);
423 inline void _proFree(void *_ptr);
426 inline void _proSignalDumpTest(_proFloat now) {
427 if (_proData<>::_proPFileStream) _proData<>::_proPFileStream->signalDumpTest(now);
430 inline void _proSignalNewMax(int valNum) {
431 if (((_proValueType[valNum] & SEQAN_PROSTATE) != 0)) {
432 if (_proData<>::_proPFileStream) _proData<>::_proPFileStream->signalNewMax(valNum);
433 if (_proData<>::_proPFile) _proData<>::_proPFile->signalNewMax(valNum);
437 inline void _proMark(const char *text) {
438 if (_proData<>::_proPFileStream) _proData<>::_proPFileStream->setMark(text);
439 if (_proData<>::_proPFile) _proData<>::_proPFile->setMark(text);
442 inline void _proEndMark(const char *text) {
443 if (_proData<>::_proPFileStream) { _proData<>::_proPFileStream->setEndMark(text); }
444 if (_proData<>::_proPFile) { _proData<>::_proPFile->setEndMark(text); }
447 inline void _proReset() {
448 if (_proData<>::_proPFileStream) { _proData<>::_proPFileStream->reset(); }
449 if (_proData<>::_proPFile) { _proData<>::_proPFile->reset(); }
455 inline void _proSet(_proValueIndex valNum, _proFloat value) {
456 _proFloat now = sysTime();
457 _proData<>::_proLastUpdate[valNum] = now;
458 if (_proData<>::_proValue[valNum] < value) {
459 _proData<>::_proValue[valNum] = value;
460 _proSignalNewMax(valNum);
462 _proData<>::_proValue[valNum] = value;
463 _proSignalDumpTest(now);
466 inline void _proAdd(_proValueIndex valNum, _proFloat value) {
467 _proFloat now = sysTime();
468 _proData<>::_proValue[valNum] += value;
469 _proData<>::_proLastUpdate[valNum] = now;
470 if (valNum == SEQAN_PROIO) _proAdd(SEQAN_PROIORANDOM, 1);
471 _proSignalNewMax(valNum);
472 _proSignalDumpTest(now);
475 inline void _proSub(_proValueIndex valNum, _proFloat value) {
476 _proFloat now = sysTime();
477 _proData<>::_proValue[valNum] -= value;
478 _proData<>::_proLastUpdate[valNum] = now;
479 _proSignalDumpTest(now);
482 // simple interface for external programs
483 inline void *_proMalloc(size_t size) {
484 size_t *ptr = reinterpret_cast<size_t*>(malloc(size + sizeof(size_t)));
486 _proAdd(SEQAN_PROMEMORY, *ptr = size);
487 // printf("_proMalloc %x size %d\n", ptr, size);
493 inline void _proFree(void *_ptr) {
494 size_t *ptr = reinterpret_cast<size_t*>(_ptr);
497 // printf("_proFree %x size %d\n", _ptr, *ptr);
498 _proSub(SEQAN_PROMEMORY, *ptr);