3 #include "ActiveSessionMemory.h"
4 #include "ActiveSessionMemory.moc"
6 void ActiveSessionMemorySnapshot::add_block(quint64 address
, quint64 size
) {
7 content
.insert(storage
->alloc_new_block(address
, size
)->get_offset());
10 void ActiveSessionMemorySnapshot::add_block(ActiveSessionMemoryBlock
*block
) {
11 content
.insert(block
->get_offset());
14 void ActiveSessionMemorySnapshot::add_block(StorageOffset offset
) {
15 content
.insert(offset
);
18 ActiveSessionMemoryBlock
*ActiveSessionMemorySnapshot::get_block(StorageOffset offset
) const {
19 return storage
->get_block_at(offset
);
22 void ActiveSessionMemorySnapshot::remove_block(ActiveSessionMemoryBlock
*block
) {
23 if(block
== NULL
) return;
24 content
.remove(block
->get_offset());
27 void ActiveSessionMemorySnapshot::copy_into(ActiveSessionMemorySnapshot
*snapshot
) const {
28 snapshot
->content
= content
;
29 snapshot
->allocations
= allocations
;
30 snapshot
->reallocations
= reallocations
;
31 snapshot
->deallocations
= deallocations
;
32 snapshot
->timestamp
= timestamp
;
35 ActiveSessionMemory::ActiveSessionMemory(QObject
*parent
, Session
*session
)
36 : QObject(parent
), session(session
), storage(NULL
), current_memory(NULL
), current_changes(NULL
) {
37 storage
= new ActiveSessionMemoryStorage(ActiveSessionMemoryStorage::ALLOC_MODE_1M
);
39 current_memory
= storage
->alloc_new_snapshot();
40 /*current_memory = new ActiveSessionMemorySnapshot(storage, -1, QDateTime::currentDateTime());*/
41 current_changes
= storage
->alloc_new_snapshot();
43 snapshot_timer
= new QTimer(this);
44 connect(snapshot_timer
, SIGNAL(timeout()), this, SLOT(save_snapshot()));
45 snapshot_timer
->start(session
->get_snapshot_interval());
48 ActiveSessionMemory::~ActiveSessionMemory() {
50 delete current_memory
;
53 quint64
ActiveSessionMemory::pop_uint64() {
54 if(unprocessed
.size() < 8) return -1;
55 QByteArray data
= unprocessed
.left(8);
56 unprocessed
.remove(0, 8);
58 /* NOTE: this is an unrolled loop, doesn't have to be like this. */
59 value
|= (uchar
)data
[7];
61 value
|= (uchar
)data
[6];
63 value
|= (uchar
)data
[5];
65 value
|= (uchar
)data
[4];
67 value
|= (uchar
)data
[3];
69 value
|= (uchar
)data
[2];
71 value
|= (uchar
)data
[1];
73 value
|= (uchar
)data
[0];
77 void ActiveSessionMemory::save_snapshot() {
78 qDebug("Saving snapshot . . .");
79 /* In order to "save" the current snapshot, all that is required is to just
80 allocate a new "changed" snapshot. The old one's already stored. However,
81 store a "full" snapshot once every max_partial_snapshots . . . */
82 StorageOffset last_snapshot
= current_changes
->get_offset();
83 if(!(snapshot_list
.size() % session
->get_full_snapshot_interval())) {
84 last_snapshot
= storage
->copy_snapshot(current_memory
->get_offset())->get_offset();
86 current_changes
= storage
->alloc_new_snapshot();
87 current_changes
->add_block(last_snapshot
);
90 void ActiveSessionMemory::started(QDateTime time
) {
91 snapshot_timer
->start(session
->get_snapshot_interval());
94 void ActiveSessionMemory::finished(QDateTime time
) {
95 snapshot_timer
->stop();
99 void ActiveSessionMemory::process_data(QByteArray data
) {
101 /* block type is zero for allocations */
102 BLOCK_EVENT_ALLOC
= 0,
103 /* block type is one for reallocations */
105 /* block type is two for deallocations */
109 while(unprocessed
.size()) {
110 char type
= unprocessed
[0];
111 unprocessed
.remove(0, 1);
115 int block_type
= (type
& 0x06) >> 1;
116 address
= pop_uint64();
117 if(block_type
== BLOCK_EVENT_ALLOC
) {
118 quint64 size
= pop_uint64();
119 ActiveSessionMemoryBlock
*block
= storage
->alloc_new_block(address
, size
);
120 current_memory
->add_block(block
);
121 current_changes
->add_block(block
);
122 current_memory
->inc_allocations();
123 current_changes
->inc_allocations();
125 else if(block_type
== BLOCK_EVENT_REALLOC
) {
126 quint64 new_size
= pop_uint64();
127 quint64 new_address
= pop_uint64();
128 ActiveSessionMemoryBlock
*block
= current_memory
->get_block(address
);
130 current_memory
->remove_block(block
);
131 current_changes
->add_block(-block
->get_offset());
132 block
= storage
->alloc_new_block(new_address
, new_size
);
133 current_memory
->add_block(block
);
134 current_changes
->add_block(block
);
135 current_memory
->inc_reallocations();
136 current_changes
->inc_reallocations();
138 else if(block_type
== BLOCK_EVENT_FREE
) {
139 ActiveSessionMemoryBlock
*block
= current_memory
->get_block(address
);
141 current_memory
->remove_block(block
);
142 current_changes
->add_block(-block
->get_offset());
143 current_memory
->inc_deallocations();
144 current_changes
->inc_deallocations();
146 /* block type three is unused, and is also known as an error . . . */
147 current_memory
->set_timestamp(QDateTime::currentDateTime());
151 emit
memory_changed(get_current_memory());