diff options
author | bd <bdunahu@operationnull.com> | 2025-04-19 12:18:14 -0400 |
---|---|---|
committer | bd <bdunahu@operationnull.com> | 2025-04-19 12:18:14 -0400 |
commit | 5ad39ec769fa09b9ac4dcc8f66232ef51384a3c6 (patch) | |
tree | 76291c5284711f5e371134439dce2c4c48432528 | |
parent | 24de6faf71c85e0281b32fb899fcbe4fe82380c4 (diff) |
Safely delete old controller object when re-initializing
-rw-r--r-- | gui/gui.cc | 25 | ||||
-rw-r--r-- | gui/gui.h | 5 | ||||
-rw-r--r-- | gui/gui.ui | 93 | ||||
-rw-r--r-- | gui/messages.h | 12 | ||||
-rw-r--r-- | gui/resources/styles.qss | 9 | ||||
-rw-r--r-- | gui/worker.cc | 42 | ||||
-rw-r--r-- | gui/worker.h | 10 |
7 files changed, 84 insertions, 112 deletions
@@ -18,9 +18,6 @@ GUI::GUI(QWidget *parent) : QMainWindow(parent), ui(new Ui::GUI) worker = new Worker(); worker->moveToThread(&workerThread); - // Connect worker thread lifecycle - // connect(&workerThread, &QThread::started, worker, &Worker::doWork); - // display clock cycles and PC connect(worker, &Worker::clock_cycles, this, &GUI::onWorkerClockCycles); @@ -49,19 +46,6 @@ GUI::GUI(QWidget *parent) : QMainWindow(parent), ui(new Ui::GUI) this, &GUI::sendConfigure, worker, &Worker::configure, Qt::QueuedConnection); - // // Refresh DRAM from worker thread - // connect(this, &GUI::sendRefreshDram, worker, &Worker::refreshDram, - // Qt::QueuedConnection); - - // // Refresh Cache from worker thread - // connect(this, &GUI::sendRefreshCache, worker, &Worker::refreshCache, - // Qt::QueuedConnection); - - // Refresh Registers from worker thread - connect( - this, &GUI::sendRefreshRegisters, worker, &Worker::refreshRegisters, - Qt::QueuedConnection); - // Advance controller by some steps connect( this, &GUI::sendRunSteps, worker, &Worker::runSteps, @@ -303,10 +287,17 @@ void GUI::on_enable_pipeline_checkbox_checkStateChanged( void GUI::on_step_btn_clicked() { qDebug() << "Run step button clicked."; + // try to configure first + if (!this->ready) + this->on_config_clicked(); + // try again if (!this->ready) - return this->on_config_clicked(); + return; + + this->set_status(get_running); int steps = step_values[ui->step_slider->value()]; emit sendRunSteps(steps); + this->set_status(get_waiting); } void GUI::on_save_program_state_btn_clicked() @@ -38,9 +38,6 @@ class GUI : public QMainWindow void set_status(const std::function<std::string()> &func); signals: - void sendRefreshDram(); - void sendRefreshCache(); - void sendRefreshRegisters(); void sendRunSteps(int steps); void sendConfigure( std::vector<unsigned int> ways, @@ -110,7 +107,7 @@ class GUI : public QMainWindow /** * If this stage is pipelined or not. */ - bool is_pipelined = false; + bool is_pipelined = true; /** * The possible step slider values. @@ -604,60 +604,23 @@ <item> <layout class="QVBoxLayout" name="verticalLayout_6"> <item> - <layout class="QHBoxLayout" name="horizontalLayout_11"> - <item> - <widget class="QSlider" name="step_slider"> - <property name="minimum"> - <number>0</number> - </property> - <property name="maximum"> - <number>6</number> - </property> - <property name="pageStep"> - <number>1</number> - </property> - <property name="orientation"> - <enum>Qt::Orientation::Horizontal</enum> - </property> - <property name="tickPosition"> - <enum>QSlider::TickPosition::NoTicks</enum> - </property> - <property name="tickInterval"> - <number>1</number> - </property> - </widget> - </item> - <item> - <widget class="Line" name="line_9"> - <property name="orientation"> - <enum>Qt::Orientation::Vertical</enum> - </property> - </widget> - </item> - <item> - <layout class="QVBoxLayout" name="verticalLayout_10"> - <item> - <widget class="QLabel" name="label_15"> - <property name="font"> - <font> - <bold>true</bold> - </font> - </property> - <property name="text"> - <string>Program State</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="cycles_label"> - <property name="text"> - <string>Clock Cycles</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> + <widget class="QLabel" name="label_15"> + <property name="font"> + <font> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Program State</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="cycles_label"> + <property name="text"> + <string>Clock Cycles</string> + </property> + </widget> </item> <item> <widget class="Line" name="line_10"> @@ -667,6 +630,28 @@ </widget> </item> <item> + <widget class="QSlider" name="step_slider"> + <property name="minimum"> + <number>0</number> + </property> + <property name="maximum"> + <number>6</number> + </property> + <property name="pageStep"> + <number>1</number> + </property> + <property name="orientation"> + <enum>Qt::Orientation::Horizontal</enum> + </property> + <property name="tickPosition"> + <enum>QSlider::TickPosition::NoTicks</enum> + </property> + <property name="tickInterval"> + <number>1</number> + </property> + </widget> + </item> + <item> <widget class="QPushButton" name="step_btn"> <property name="minimumSize"> <size> diff --git a/gui/messages.h b/gui/messages.h index c2a86b9..2b31037 100644 --- a/gui/messages.h +++ b/gui/messages.h @@ -9,14 +9,19 @@ #define RANDOM_MESSAGE(v) (v[std::rand() % v.size()]) const std::vector<std::string> waiting = { - "WAITING FOR USER", "FRIENDS MISSING", "BORED", "SLEEPING"}; + "WAITING FOR USER", "BORED", "SLEEPING", "TIRED", "IDLE", "EXCITED"}; +const std::vector<std::string> running = { + "CALCULATING", "COMPUTING", + "EXTERMINATE" + "WORKING", + "BUSY"}; const std::vector<std::string> load_file = { "FILE LOADED", "FINISHED READING DATA. EAGERLY WAITING"}; const std::vector<std::string> no_instructions = { "NO PROGRAM PROVIDED", "INSTRUCTIONS NOT INCLUDED", "NOTHING TO DO, GIVING UP"}; const std::vector<std::string> bad_cache = { - "INVALID NUMBER OF WAYS", "WAYS CANNOT BE BELOW 0 OR ABOVE 5"}; + "WAYS CANNOT BE BELOW 0 OR ABOVE 5"}; const std::vector<std::string> no_pipeline = { "PIPELINE--HUMANS PROBABLY WORKED HARD ON THAT", "I WOULD PREFER YOU LEAVE THE PIPE ON", "SLOW MODE ENABLED", @@ -26,9 +31,10 @@ const std::vector<std::string> no_cache = { const std::vector<std::string> initialize = {"SIMULATION READY"}; /** - * @return an unsolicited waiting message + * @return an unsolicited status messages */ std::string get_waiting() { return RANDOM_MESSAGE(waiting); } +std::string get_running() { return RANDOM_MESSAGE(running); } /** * @return confirmation of file upload diff --git a/gui/resources/styles.qss b/gui/resources/styles.qss index 9b63249..59d36ca 100644 --- a/gui/resources/styles.qss +++ b/gui/resources/styles.qss @@ -2,7 +2,8 @@ font-family: "BigBlueTermPlusNerdFontMono", "monospace"; font-size: 20pt; color: "#00cc00"; - background-color: "#000004"; + background-color: "#000200"; + border: 0px solid "#000200"; } /* main window */ @@ -12,7 +13,6 @@ QWidget { QGroupBox { text-decoration: underline "#00cc00"; font-size: 17pt; - background-color: "#000004"; border: 4px solid ; border-radius: 0px; margin-top: 1ex; /* leave space at the top for the title */ @@ -38,11 +38,10 @@ QLineEdit { QTextEdit, QListView { font-size: 10pt; - background-color: "#000004"; } QPushButton { - color: "#000004"; + color: "#000200"; background-color: "#00cc00"; border-radius: 0px; padding: 1px; @@ -51,7 +50,7 @@ QPushButton { QPushButton:pressed { color: "#00cc00"; - background-color: "#000004"; + background-color: "#000200"; } QPushButton:flat { diff --git a/gui/worker.cc b/gui/worker.cc index cd79821..88248e8 100644 --- a/gui/worker.cc +++ b/gui/worker.cc @@ -18,21 +18,23 @@ void Worker::configure( { Dram *d; Storage *s; + Stage *old; int i; + this->ct_mutex.lock(); if (ways.size() != 0) { // will ensure the largest cache is only half of DRAM this->size_inc = (MEM_LINE_SPEC / ways.size()) / 2; } d = new Dram(DRAM_DELAY); - s = (Storage *)d; + s = static_cast<Storage *>(d); this->s.push_front(s); d->load(program); for (i = ways.size(); i > 0; --i) { - s = (Storage *)new Cache( - s, this->size_inc * (i), ways.at(i - 1), CACHE_DELAY + i); + s = static_cast<Storage *>(new Cache( + s, this->size_inc * (i), ways.at(i - 1), CACHE_DELAY + i)); this->s.push_front(s); } @@ -41,37 +43,26 @@ void Worker::configure( this->ex_stage = new EX(id_stage); this->mm_stage = new MM(ex_stage); this->wb_stage = new WB(mm_stage); - this->ct = - new Controller(wb_stage, s, is_pipelined); - emit clock_cycles(this->ct->get_clock_cycle(), this->ct->get_pc()); -} - -void Worker::refreshDram() -{ - qDebug() << "Refreshing Dram"; - emit dram_storage(this->s.back()->view(0, 255)); -} - -void Worker::refreshCache() -{ - qDebug() << "Refreshing Cache"; - if(this->s.size() > 0) { - emit cache_storage(this->s.at(0)->view(0, 1 << this->size_inc)); - } -} + old = static_cast<Stage *>(this->ct); + this->ct = new Controller(wb_stage, s, is_pipelined); + if (old) + delete old; + this->ct_mutex.unlock(); -void Worker::refreshRegisters() -{ - qDebug() << "Refreshing Registers"; - emit register_storage(this->ct->get_gprs()); + emit clock_cycles(this->ct->get_clock_cycle(), this->ct->get_pc()); } void Worker::runSteps(int steps) { + this->ct_mutex.lock(); qDebug() << "Running for " << steps << "steps"; this->ct->run_for(steps); + // TODO move these to separate functions emit dram_storage(this->s.back()->view(0, 255)); + if (this->s.size() > 1) { + emit cache_storage(this->s.at(0)->view(0, 1 << this->size_inc)); + } emit register_storage(this->ct->get_gprs()); emit clock_cycles(this->ct->get_clock_cycle(), this->ct->get_pc()); emit if_info(this->if_stage->stage_info()); @@ -79,4 +70,5 @@ void Worker::runSteps(int steps) emit ex_info(this->ex_stage->stage_info()); emit mm_info(this->mm_stage->stage_info()); emit wb_info(this->wb_stage->stage_info()); + this->ct_mutex.unlock(); } diff --git a/gui/worker.h b/gui/worker.h index acfffcf..20a9838 100644 --- a/gui/worker.h +++ b/gui/worker.h @@ -12,6 +12,7 @@ #include <QDebug> #include <QObject> #include <QThread> +#include <QMutex> #include <deque> class Worker : public QObject @@ -28,7 +29,10 @@ class Worker : public QObject EX *ex_stage; MM *mm_stage; WB *wb_stage; - Controller *ct; + + Controller *ct = nullptr; + QMutex ct_mutex; + /** * The size each progressive cache level increases by. */ @@ -37,11 +41,9 @@ class Worker : public QObject public: explicit Worker(QObject *parent = nullptr); ~Worker(); + QMutex& get_ct_mutex() { return ct_mutex; } public slots: - void refreshDram(); - void refreshCache(); - void refreshRegisters(); void runSteps(int steps); void configure( std::vector<unsigned int> ways, |