Advertisement
lukicdarkoo

Rukovanje memorijom - Uvodni zadatak

May 22nd, 2015
225
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.25 KB | None | 0 0
  1. /*
  2. Napisati konkurentni program koji modeluje ponasanje racunarskog sistema.
  3. U sistemu se nalaze:
  4. - magistrala - sabirnica (bus)
  5. - n-procesora
  6. - memorija
  7. - dma kontroler
  8. Svi procesori, memorija i DMA kontroler su zakaceni na istu magistralu.
  9.  
  10. Memorija je predstavljena klasom Memory.
  11. Pri instanciranju objekta ovog tipa se zadaje velicina memorije.
  12. Meorija se moze citati (read()) i pisati (write()).
  13. Obe operacije treba da budu thread safe.
  14. I citanje iz memorije i pisanje u memoriju traje po 300 ms.
  15.  
  16. Magistrala je predstavljena klasom Bus.
  17. Magistrala ima 3 operacije koje pozivaju procesori (memRead(), memWrite(), dma())
  18. i jednu koju poziva DMA kontroler (dma_controller_hook()).
  19. Sve operacije treba da budu thread safe.
  20. Pre pristupa memoriji neophodno je zakljucati (ekskluzivno) magistralu.
  21. Zakljucavanje magistrale traje 700ms.
  22. Po zavrsetku pristupa magistrala se otkljucava (trenutno).
  23.  
  24.  
  25.  
  26. DMA transfer se obavlja tako sto se magistrala zakljuca jednom,
  27. obave se svi transferi i na kraju se magistrala otkljuca.
  28.  
  29. DMA kontroler je predstavljen funkcijom dmaController.
  30. Kontroler poziva operaciju Bus::dma_controller_hook() i u njoj ceka
  31. dok neki procesor ne zatrazi DMA prenos.
  32.  
  33.  
  34. Procesori pri stvaranju dobiju zadat program (u obliku vektora naredbi)
  35. koji treba da izvrse.
  36. Naredbe su predstavljene objektima klase MemoryTransfer.
  37. Moguce naredbe su:
  38. - pisanja u memoriju,
  39. - citanje iz memorije i
  40. - DMA transfer
  41.  
  42. Stvoriti nekoliko niti koje pokazuju da program radi ispravno.
  43.  
  44. Dato je nekoliko programa (u funkciji main()) za primer, zarad lakseg testiranja.
  45.  
  46.  
  47. */
  48.  
  49. #include <iostream>
  50. #include <thread>
  51. #include <vector>
  52.  
  53. using namespace std;
  54.  
  55. class Memory {
  56. public:
  57.     Memory(int bytes) {
  58.         memory_locations.resize(bytes, -1);
  59.     };
  60.  
  61.     char read(int address) {
  62.         unique_lock<mutex> l(m);
  63.         this_thread::sleep_for(chrono::milliseconds(300));
  64.         return memory_locations[address];
  65.     };
  66.  
  67.     void write(int address, char value) {
  68.         unique_lock<mutex> l(m);
  69.         this_thread::sleep_for(chrono::milliseconds(300));
  70.         memory_locations[address] = value;
  71.     };
  72.  
  73. private:
  74.     vector<char> memory_locations;
  75.     mutex m;
  76. };
  77.  
  78.  
  79. class Bus {
  80. public:
  81.     enum State { FREE, MEM_READ, MEM_WRITE, DMA };
  82.     struct DMAtransfer {
  83.         int from;
  84.         int count;
  85.         int to;
  86.     };
  87. public:
  88.     Bus(Memory& mem) : transfer_in_progress(false) {
  89.         memory = &mem;
  90.     };
  91.  
  92.     char memRead(int address) {
  93.         unique_lock<mutex> l(m);
  94.  
  95.         state = MEM_READ;
  96.  
  97.         this_thread::sleep_for(chrono::milliseconds(700));
  98.         char read_char = memory->read(address);
  99.         state = FREE;
  100.  
  101.         return read_char;
  102.     };
  103.  
  104.     void memWrite(int address, char value) {
  105.         unique_lock<mutex> l(m);
  106.  
  107.         state = MEM_WRITE;
  108.  
  109.         this_thread::sleep_for(chrono::milliseconds(700));
  110.         memory->write(address, value);
  111.  
  112.         state = FREE;
  113.     };
  114.  
  115.     /*
  116.     DMA transfer se obavlja tako sto se magistrala zakljuca jednom,
  117.     obave se svi transferi i na kraju se magistrala otkljuca.
  118.  
  119.     DMA kontroler je predstavljen funkcijom dmaController.
  120.     Kontroler poziva operaciju Bus::dma_controller_hook() i u njoj ceka
  121.     dok neki procesor ne zatrazi DMA prenos.
  122.     */
  123.  
  124.     void dma(DMAtransfer dmaTransfer) {
  125.         unique_lock<mutex> l(m);
  126.         currectDMAtransfer = dmaTransfer;
  127.         dma_cv.notify_one();
  128.     };
  129.  
  130.     DMAtransfer dma_controller_hook() {
  131.         unique_lock<mutex> l(m);
  132.  
  133.         while (state != FREE) {
  134.             dma_cv.wait(l);
  135.         }
  136.  
  137.         state = DMA;
  138.  
  139.         l.unlock();
  140.  
  141.         // Do a transfer
  142.         for (int i = 0; i < currectDMAtransfer.count; i++) {
  143.             char byte = memory->read(currectDMAtransfer.from + i);
  144.             memory->write(currectDMAtransfer.to + i, byte);
  145.         }
  146.  
  147.         l.lock();
  148.  
  149.         state = FREE;
  150.  
  151.         return currectDMAtransfer;
  152.     };
  153.  
  154. private:
  155.     Memory *memory;
  156.     mutex m;
  157.     condition_variable dma_cv;
  158.     bool transfer_in_progress;
  159.     DMAtransfer currectDMAtransfer;
  160.     State state;
  161. };
  162.  
  163.  
  164. /*
  165. Konstruktori su napravljeni tako da omoguce jednostavno stvaranje naredbi.
  166. Citanje: 1 parametar = adresa lokacije sa koje se cita vrednost
  167. Pisanje: 2 parametra = adresa lokacije u koju se upisuje vrednost,
  168.                        vrednost koja se upisuje
  169. DMA:     3 parametra = adresa pocetka bloka memorije koji se kopira,
  170.                        broj lokacija ciji se sadrzaj kopira,
  171.                        adresa pocetka bloka memorije u koju se kopira
  172.  
  173. (Vidi vektore I, II i III u funkciji main().)
  174. */
  175. struct MemoryTransfer {
  176.     Bus::State transferType;
  177.     int from;
  178.     int count;
  179.     int to;
  180.     char value;
  181.     MemoryTransfer(int address)
  182.         : transferType(Bus::MEM_READ), from(address) {}
  183.     MemoryTransfer(int address, char v)
  184.         : transferType(Bus::MEM_WRITE), to(address), value(v) {}
  185.     MemoryTransfer(int f, int c, int t)
  186.        : transferType(Bus::DMA), from(f), count(c), to(t) {}
  187. };
  188.  
  189. // Mutex je globalan jer ga koriste 2 funkcije ( processor() i dmaController() ).
  190. mutex term_m;
  191.  
  192. void processor(Bus& bus, vector<MemoryTransfer>& program) {
  193.     for(auto transfer = program.begin(); transfer!=program.end(); ++transfer) {
  194.         if(transfer->transferType == Bus::MEM_READ) {
  195.             transfer->value = bus.memRead(transfer->from);
  196.             unique_lock<mutex> l(term_m);
  197.             cout << "Processor " << this_thread::get_id()
  198.                  << " read from address " << transfer->from
  199.                  << " value=" << transfer->value << endl;
  200.         } else if(transfer->transferType == Bus::MEM_WRITE) {
  201.             bus.memWrite(transfer->to, transfer->value);
  202.             unique_lock<mutex> l(term_m);
  203.             cout << "Processor " << this_thread::get_id()
  204.                  << " wrote to address " << transfer->to
  205.                  << " value=" << transfer->value << endl;
  206.         } else {
  207.             Bus::DMAtransfer dmaTransfer = {transfer->from, transfer->count, transfer->to};
  208.             bus.dma(dmaTransfer);
  209.             unique_lock<mutex> l(term_m);
  210.             cout << "Processor " << this_thread::get_id()
  211.                  << " DMA transfer requested " << endl;
  212.         }
  213.     }
  214.  
  215. }
  216.  
  217. void dmaController(Bus& bus) {
  218.     for(;;) {
  219.         Bus::DMAtransfer transfer = bus.dma_controller_hook();
  220.         unique_lock<mutex> l(term_m);
  221.         cout << "                DMA transfer: from=" << transfer.from
  222.              << " count=" << transfer.count
  223.              << " to=" << transfer.to << endl;
  224.     }
  225. }
  226.  
  227. int main() {
  228.     vector<MemoryTransfer> I  = {
  229.         {0, '0'},
  230.         {4, '4'},
  231.         {0},
  232.         {8, '8'}
  233.     };
  234.     vector<MemoryTransfer> II = {
  235.         {1, '1'},
  236.         {3, '3'},
  237.         {0, 5, 10},
  238.         {10},
  239.         {11}
  240.     };
  241.     vector<MemoryTransfer> III = {
  242.         {8, '8'},
  243.         {9, '9'},
  244.         {2, '2'},
  245.         {12},
  246.         {13},
  247.         {14}
  248.     };
  249.  
  250.     Memory mem{16};
  251.     Bus bus{mem};
  252.  
  253.     thread dmaCtrl(dmaController, ref(bus));
  254.     dmaCtrl.detach();
  255.  
  256.     thread P1(processor, ref(bus), ref(I));
  257.     thread P2(processor, ref(bus), ref(II));
  258.     thread P3(processor, ref(bus), ref(III));
  259.     P1.join();
  260.     P2.join();
  261.     P3.join();
  262. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement