Project

General

Profile

Statistics
| Branch: | Revision:

root / src / tkenv / logbuffer.cc @ 3e29b8a0

History | View | Annotate | Download (3.76 KB)

1 01873262 Georg Kunz
//==========================================================================
2
//  LOGBUFFER.CC - part of
3
//
4
//                     OMNeT++/OMNEST
5
//            Discrete System Simulation in C++
6
//
7
//==========================================================================
8
9
/*--------------------------------------------------------------*
10
  Copyright (C) 1992-2008 Andras Varga
11
  Copyright (C) 2006-2008 OpenSim Ltd.
12

13
  This file is distributed WITHOUT ANY WARRANTY. See the file
14
  `license' for details on this and other legal matters.
15
*--------------------------------------------------------------*/
16
17
#include <string.h>
18
#include "tklib.h"
19
#include "logbuffer.h"
20
#include "cmodule.h"
21
22
USING_NAMESPACE
23
24
LogBuffer::Entry::~Entry()
25
{
26
    delete[] moduleIds;
27
    delete[] banner;
28
    for (int i=0; i<(int)lines.size(); i++)
29
        delete[] lines[i];
30
}
31
32
//----
33
34
LogBuffer::LogBuffer(int memoryLimit)
35
{
36
    numEntries =0;
37
    memLimit = memoryLimit;
38
    totalChars = 0;
39
    totalStrings = 0;
40
}
41
42
LogBuffer::~LogBuffer()
43
{
44
}
45
46
void LogBuffer::fillEntry(Entry& entry, eventnumber_t e, simtime_t t, cModule *mod, const char *banner)
47
{
48
    entry.eventNumber = e;
49
    entry.simtime = t;
50
    entry.banner = opp_strdup(banner);
51
    entry.numChars = banner ? strlen(banner) : 0;
52
53
    // store all moduleIds up to the root
54
    if (mod)
55
    {
56
        int depth = 0;
57
        for (cModule *p=mod; p; p=p->getParentModule())
58
            depth++;
59
        entry.moduleIds = new int[depth+1];
60
        int i = 0;
61
        for (cModule *p=mod; p; p=p->getParentModule(), i++)
62
            entry.moduleIds[i] = p->getId();
63
         entry.moduleIds[depth] = 0;
64
    }
65
}
66
67
void LogBuffer::addEvent(eventnumber_t e, simtime_t t, cModule *mod, const char *banner)
68
{
69
    entries.push_back(Entry());
70
    numEntries++;
71
    fillEntry(entries.back(), e, t, mod, banner);
72
    totalStrings++;
73
    totalChars += entries.back().numChars;
74
    discardIfMemoryLimitExceeded();
75
}
76
77
void LogBuffer::addLogLine(const char *text)
78
{
79
    if (entries.empty())
80
    {
81
        // this is likely the initialize() phase -- hence no banner
82
        addEvent(0, 0, NULL, "{}");
83
        Entry& entry = entries.back();
84
        entry.moduleIds = new int[1]; // add empty array, to distinguish entry from an info entry
85
        entry.moduleIds[0] = 0;
86
    }
87
88
    //FIXME if last line is "info" then we cannot append to it! create new entry with empty banner?
89
90
    Entry& entry = entries.back();
91
    entry.lines.push_back(opp_strdup(text));
92
    totalStrings++;
93
    totalChars += strlen(text);
94
95
    discardIfMemoryLimitExceeded();
96
}
97
98
void LogBuffer::addInfo(const char *text)
99
{
100
    entries.push_back(Entry());
101
    numEntries++;
102
    fillEntry(entries.back(), 0, 0, NULL, text);
103
    totalStrings++;
104
    totalChars += entries.back().numChars;
105
    discardIfMemoryLimitExceeded();
106
}
107
108
void LogBuffer::setMemoryLimit(size_t limit)
109
{
110
    memLimit = limit;
111
    discardIfMemoryLimitExceeded();
112
}
113
114
void LogBuffer::discardIfMemoryLimitExceeded()
115
{
116
    while (estimatedMemUsage() > memLimit && numEntries > 1)  // leave at least 1 entry
117
    {
118
        // discard first entry
119
        Entry& entry = entries.front();
120
        totalChars -= entry.numChars;
121
        totalStrings -= entry.lines.size()+1;
122
        entries.pop_front();
123
        numEntries--;
124
    }
125
}
126
127
#define LL  INT64_PRINTF_FORMAT
128
129
void LogBuffer::dump() const
130
{
131
    printf("LogBuffer: %lu entries\n", (unsigned long)numEntries);
132
133
    int k=0;
134
    for (std::list<Entry>::const_iterator it=entries.begin(); it!=entries.end(); it++)
135
    {
136
        const LogBuffer::Entry& entry = *it;
137
        printf("[%d] #%"LL"d t=%s moduleId=%d: %s", k, entry.eventNumber, SIMTIME_STR(entry.simtime), entry.moduleIds?entry.moduleIds[0]:-1, entry.banner);
138
        for (int i=0; i<(int)entry.lines.size(); i++)
139
            printf("\t[l%d]:%s", k, entry.lines[i]);
140
        k++;
141
    }
142
}
143