Implemented full snapshot saving in the GUI.
[aesalon.git] / gui / src / ActiveSessionMemory.cpp
blob1d80e920643f78fb8562be9971478adb031034ce
1 #include <QTimer>
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() {
49 delete storage;
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);
57 quint64 value = 0;
58 /* NOTE: this is an unrolled loop, doesn't have to be like this. */
59 value |= (uchar)data[7];
60 value <<= 8;
61 value |= (uchar)data[6];
62 value <<= 8;
63 value |= (uchar)data[5];
64 value <<= 8;
65 value |= (uchar)data[4];
66 value <<= 8;
67 value |= (uchar)data[3];
68 value <<= 8;
69 value |= (uchar)data[2];
70 value <<= 8;
71 value |= (uchar)data[1];
72 value <<= 8;
73 value |= (uchar)data[0];
74 return value;
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();
96 save_snapshot();
99 void ActiveSessionMemory::process_data(QByteArray data) {
100 enum {
101 /* block type is zero for allocations */
102 BLOCK_EVENT_ALLOC = 0,
103 /* block type is one for reallocations */
104 BLOCK_EVENT_REALLOC,
105 /* block type is two for deallocations */
106 BLOCK_EVENT_FREE
108 unprocessed += data;
109 while(unprocessed.size()) {
110 char type = unprocessed[0];
111 unprocessed.remove(0, 1);
112 if(type & 0x01) {
113 /* block event */
114 quint64 address = 0;
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);
129 if(!block) continue;
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);
140 if(!block) continue;
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());