Project

General

Profile

Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (3.76 KB)

1
//==========================================================================
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

    
144