Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- Napisati konkurentni program koji modeluje ponasanje racunarskog sistema.
- U sistemu se nalaze:
- - magistrala - sabirnica (bus)
- - n-procesora
- - memorija
- - dma kontroler
- Svi procesori, memorija i DMA kontroler su zakaceni na istu magistralu.
- Memorija je predstavljena klasom Memory.
- Pri instanciranju objekta ovog tipa se zadaje velicina memorije.
- Meorija se moze citati (read()) i pisati (write()).
- Obe operacije treba da budu thread safe.
- I citanje iz memorije i pisanje u memoriju traje po 300 ms.
- Magistrala je predstavljena klasom Bus.
- Magistrala ima 3 operacije koje pozivaju procesori (memRead(), memWrite(), dma())
- i jednu koju poziva DMA kontroler (dma_controller_hook()).
- Sve operacije treba da budu thread safe.
- Pre pristupa memoriji neophodno je zakljucati (ekskluzivno) magistralu.
- Zakljucavanje magistrale traje 700ms.
- Po zavrsetku pristupa magistrala se otkljucava (trenutno).
- DMA transfer se obavlja tako sto se magistrala zakljuca jednom,
- obave se svi transferi i na kraju se magistrala otkljuca.
- DMA kontroler je predstavljen funkcijom dmaController.
- Kontroler poziva operaciju Bus::dma_controller_hook() i u njoj ceka
- dok neki procesor ne zatrazi DMA prenos.
- Procesori pri stvaranju dobiju zadat program (u obliku vektora naredbi)
- koji treba da izvrse.
- Naredbe su predstavljene objektima klase MemoryTransfer.
- Moguce naredbe su:
- - pisanja u memoriju,
- - citanje iz memorije i
- - DMA transfer
- Stvoriti nekoliko niti koje pokazuju da program radi ispravno.
- Dato je nekoliko programa (u funkciji main()) za primer, zarad lakseg testiranja.
- */
- #include <iostream>
- #include <thread>
- #include <vector>
- using namespace std;
- class Memory {
- public:
- Memory(int bytes) {
- memory_locations.resize(bytes, -1);
- };
- char read(int address) {
- unique_lock<mutex> l(m);
- this_thread::sleep_for(chrono::milliseconds(300));
- return memory_locations[address];
- };
- void write(int address, char value) {
- unique_lock<mutex> l(m);
- this_thread::sleep_for(chrono::milliseconds(300));
- memory_locations[address] = value;
- };
- private:
- vector<char> memory_locations;
- mutex m;
- };
- class Bus {
- public:
- enum State { FREE, MEM_READ, MEM_WRITE, DMA };
- struct DMAtransfer {
- int from;
- int count;
- int to;
- };
- public:
- Bus(Memory& mem) : transfer_in_progress(false) {
- memory = &mem;
- };
- char memRead(int address) {
- unique_lock<mutex> l(m);
- state = MEM_READ;
- this_thread::sleep_for(chrono::milliseconds(700));
- char read_char = memory->read(address);
- state = FREE;
- return read_char;
- };
- void memWrite(int address, char value) {
- unique_lock<mutex> l(m);
- state = MEM_WRITE;
- this_thread::sleep_for(chrono::milliseconds(700));
- memory->write(address, value);
- state = FREE;
- };
- /*
- DMA transfer se obavlja tako sto se magistrala zakljuca jednom,
- obave se svi transferi i na kraju se magistrala otkljuca.
- DMA kontroler je predstavljen funkcijom dmaController.
- Kontroler poziva operaciju Bus::dma_controller_hook() i u njoj ceka
- dok neki procesor ne zatrazi DMA prenos.
- */
- void dma(DMAtransfer dmaTransfer) {
- unique_lock<mutex> l(m);
- currectDMAtransfer = dmaTransfer;
- dma_cv.notify_one();
- };
- DMAtransfer dma_controller_hook() {
- unique_lock<mutex> l(m);
- while (state != FREE) {
- dma_cv.wait(l);
- }
- state = DMA;
- l.unlock();
- // Do a transfer
- for (int i = 0; i < currectDMAtransfer.count; i++) {
- char byte = memory->read(currectDMAtransfer.from + i);
- memory->write(currectDMAtransfer.to + i, byte);
- }
- l.lock();
- state = FREE;
- return currectDMAtransfer;
- };
- private:
- Memory *memory;
- mutex m;
- condition_variable dma_cv;
- bool transfer_in_progress;
- DMAtransfer currectDMAtransfer;
- State state;
- };
- /*
- Konstruktori su napravljeni tako da omoguce jednostavno stvaranje naredbi.
- Citanje: 1 parametar = adresa lokacije sa koje se cita vrednost
- Pisanje: 2 parametra = adresa lokacije u koju se upisuje vrednost,
- vrednost koja se upisuje
- DMA: 3 parametra = adresa pocetka bloka memorije koji se kopira,
- broj lokacija ciji se sadrzaj kopira,
- adresa pocetka bloka memorije u koju se kopira
- (Vidi vektore I, II i III u funkciji main().)
- */
- struct MemoryTransfer {
- Bus::State transferType;
- int from;
- int count;
- int to;
- char value;
- MemoryTransfer(int address)
- : transferType(Bus::MEM_READ), from(address) {}
- MemoryTransfer(int address, char v)
- : transferType(Bus::MEM_WRITE), to(address), value(v) {}
- MemoryTransfer(int f, int c, int t)
- : transferType(Bus::DMA), from(f), count(c), to(t) {}
- };
- // Mutex je globalan jer ga koriste 2 funkcije ( processor() i dmaController() ).
- mutex term_m;
- void processor(Bus& bus, vector<MemoryTransfer>& program) {
- for(auto transfer = program.begin(); transfer!=program.end(); ++transfer) {
- if(transfer->transferType == Bus::MEM_READ) {
- transfer->value = bus.memRead(transfer->from);
- unique_lock<mutex> l(term_m);
- cout << "Processor " << this_thread::get_id()
- << " read from address " << transfer->from
- << " value=" << transfer->value << endl;
- } else if(transfer->transferType == Bus::MEM_WRITE) {
- bus.memWrite(transfer->to, transfer->value);
- unique_lock<mutex> l(term_m);
- cout << "Processor " << this_thread::get_id()
- << " wrote to address " << transfer->to
- << " value=" << transfer->value << endl;
- } else {
- Bus::DMAtransfer dmaTransfer = {transfer->from, transfer->count, transfer->to};
- bus.dma(dmaTransfer);
- unique_lock<mutex> l(term_m);
- cout << "Processor " << this_thread::get_id()
- << " DMA transfer requested " << endl;
- }
- }
- }
- void dmaController(Bus& bus) {
- for(;;) {
- Bus::DMAtransfer transfer = bus.dma_controller_hook();
- unique_lock<mutex> l(term_m);
- cout << " DMA transfer: from=" << transfer.from
- << " count=" << transfer.count
- << " to=" << transfer.to << endl;
- }
- }
- int main() {
- vector<MemoryTransfer> I = {
- {0, '0'},
- {4, '4'},
- {0},
- {8, '8'}
- };
- vector<MemoryTransfer> II = {
- {1, '1'},
- {3, '3'},
- {0, 5, 10},
- {10},
- {11}
- };
- vector<MemoryTransfer> III = {
- {8, '8'},
- {9, '9'},
- {2, '2'},
- {12},
- {13},
- {14}
- };
- Memory mem{16};
- Bus bus{mem};
- thread dmaCtrl(dmaController, ref(bus));
- dmaCtrl.detach();
- thread P1(processor, ref(bus), ref(I));
- thread P2(processor, ref(bus), ref(II));
- thread P3(processor, ref(bus), ref(III));
- P1.join();
- P2.join();
- P3.join();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement