Advertisement
canezzy

5.zad

Jun 3rd, 2018
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.91 KB | None | 0 0
  1. #include <iostream>
  2. #include <mutex>
  3. #include <condition_variable>
  4. #include <vector>
  5. #include <thread>
  6. #include <map>
  7. #include <algorithm>
  8.  
  9. #include "math.h"
  10.  
  11. using namespace std;
  12. using namespace chrono;
  13. mutex m;
  14. mutex term_m;
  15. class Kompir {
  16. public:
  17.     int id;
  18.     int velicina;
  19.     Kompir(int _id, bool _velicina) : id(_id), velicina(_velicina) {}
  20. };
  21. bool wayToSort(Kompir i, Kompir j) { return i.velicina > j.velicina; }
  22.  
  23. int odrediStepen(int i)
  24. {
  25.     int brojac = 0;
  26.     while (true) {
  27.         if (pow(2, brojac) >= i)
  28.             return brojac;
  29.         brojac++;
  30.  
  31.     }
  32. }
  33.  
  34.  
  35. class cv_tag {
  36. private:
  37.     struct cv_data {
  38.         condition_variable c;
  39.         bool fulfilled;
  40.         cv_data() : fulfilled(false) {}
  41.     };
  42.     map<size_t, cv_data*> waiting;
  43. public:
  44.     cv_tag() {}
  45.     ~cv_tag();
  46.     void wait(unique_lock<mutex>&, size_t);
  47.     void notify(size_t tag);
  48.     void notify_all();
  49. };
  50.  
  51. cv_tag::~cv_tag() {
  52.     for (auto i = waiting.begin(); i != waiting.end(); ++i)
  53.         delete (*i).second;
  54. }
  55.  
  56. void cv_tag::wait(unique_lock<mutex>& l, size_t tag) {
  57.     waiting.insert(pair<size_t, cv_data*>{tag, new cv_data});
  58.     while (!waiting[tag]->fulfilled)
  59.         waiting[tag]->c.wait(l);
  60.     delete waiting[tag];
  61.     waiting.erase(tag);
  62. }
  63.  
  64. void cv_tag::notify(size_t tag) {
  65.     if (waiting.find(tag) != waiting.end()) {
  66.         waiting[tag]->fulfilled = true;
  67.         waiting[tag]->c.notify_one();
  68.     }
  69. }
  70.  
  71. void cv_tag::notify_all() {
  72.     for (auto i = waiting.begin(); i != waiting.end(); ++i) {
  73.         (*i).second->fulfilled = true;
  74.         (*i).second->c.notify_one();
  75.     }
  76. }
  77.  
  78. class Komat {
  79. public:
  80.     int velicina;
  81.     bool zauzeto;
  82.     int kuj;
  83.     Komat(int _velicina, bool _zauzeto, int _kuj) : velicina(_velicina), zauzeto(_zauzeto), kuj(_kuj) {}
  84. };
  85.  
  86.  
  87. inline bool operator==(const Komat& lhs, const Komat& rhs) { return lhs.velicina == rhs.velicina; }
  88. class RadnaMemorija {
  89. private:
  90.     vector<Komat> komati;
  91.     int U;
  92.  
  93.     vector<Kompir> kompiri;
  94.     cv_tag red;
  95.  
  96.     void printaj() {
  97.         unique_lock<mutex> l(term_m);
  98.  
  99.         cout << "--------------------------------------------------------------------" << endl;
  100.         for (Komat k : komati)
  101.         {
  102.             cout << "Komat: " << pow(2,k.velicina) << "KB, zauz: " << k.zauzeto << ", kuj: " << k.kuj << endl;
  103.         }
  104.         cout << "--------------------------------------------------------------------" << endl;
  105.     }
  106.  
  107.     void namakni(int i, int kolikoGodina) // 22, '90 godiste
  108.     {
  109.         vector<Komat> noviKomati;
  110.         for (int k = 0; k < kolikoGodina; ++k) {
  111.             noviKomati = vector<Komat>();
  112.  
  113.             for (int j = 0; j < komati.size(); ++j)
  114.             {
  115.                 if (j != i)
  116.                     noviKomati.push_back(komati[j]);
  117.                 else
  118.                 {
  119.                     noviKomati.push_back(Komat(komati[j].velicina - 1, false, komati[j].kuj));
  120.                     noviKomati.push_back(Komat(komati[j].velicina - 1, false, komati[j].kuj));
  121.                 }
  122.             }
  123.  
  124.             komati = noviKomati;
  125.         }
  126.     }
  127.  
  128.     void razapni(bool& fnd, int& ind, int& step)
  129.     {
  130.         while (step <= U && !fnd) {
  131.             for (int i = 0; i < komati.size(); i++)
  132.             {
  133.                 if (komati[i].velicina == step && !komati[i].zauzeto)
  134.                 {
  135.  
  136.                     fnd = true;
  137.                     ind = i;
  138.                     break;
  139.                 }
  140.             }
  141.             step++;
  142.         }
  143.     }
  144.  
  145.     void razjebi()
  146.     {
  147.         vector<Komat> novi = komati;
  148.  
  149.         do
  150.         {
  151.             komati = novi;
  152.             novi = vector<Komat>();
  153.             bool flag = false;
  154.             for (int i = 0; i < komati.size(); ++i)
  155.             {
  156.                 if ((i != komati.size() - 1) && (komati[i].velicina == komati[i + 1].velicina) && (!komati[i].zauzeto) && (!komati[i + 1].zauzeto) && !flag)
  157.                 {
  158.                     novi.push_back(Komat(komati[i].velicina + 1, false, komati[i].kuj));
  159.                     i++;
  160.                     flag = true;
  161.                 }
  162.                 else {
  163.                     novi.push_back(komati[i]);
  164.                 }
  165.             }
  166.  
  167.         } while (novi != komati);
  168.     }
  169. public:
  170.     RadnaMemorija(int _U) : U(_U)
  171.     {
  172.         komati.push_back(Komat(_U, false, 0));
  173.     }
  174.  
  175.     //Zauzimanje memorije
  176.     //Parametar id_procesa - identifikator procesa koji se smesta u memoriju
  177.     //Parametar potrebno - koja kolicina memorije je potrebna da se proces smesti (broj potrebnih kilobajta, a ne stepen broja 2)
  178.     void zauzmi(int id_procesa, int potrebno)
  179.     {
  180.         printaj();
  181.         int stepen = odrediStepen(potrebno);
  182.         int step = stepen;
  183.         bool found = false;
  184.         int indeks = -1;
  185.         unique_lock<mutex> l(m);
  186.         razapni(found, indeks, step);
  187.         while (!found)
  188.         {
  189.             kompiri.push_back(Kompir(id_procesa, stepen));
  190.             red.wait(l, id_procesa);
  191.             razapni(found, indeks, step);
  192.         }
  193.  
  194.         if (step != stepen)
  195.             namakni(indeks, (step - stepen) - 1);
  196.  
  197.         komati[indeks].zauzeto = true;
  198.         komati[indeks].kuj = id_procesa;
  199.         printaj();
  200.     }
  201.     void oslobodi(int id_procesa)
  202.     {
  203.         printaj();
  204.         unique_lock<mutex> l(m);
  205.         for (Komat& k : komati)
  206.         {
  207.             if (k.kuj == id_procesa)
  208.                 k.zauzeto = false;
  209.         }
  210.  
  211.         razjebi();
  212.  
  213.         sort(kompiri.begin(), kompiri.end(), wayToSort);
  214.         for (Kompir krkr : kompiri) {
  215.             red.notify(krkr.id);
  216.         }
  217.         printaj();
  218.     }
  219. };
  220.  
  221.  
  222. void proces(RadnaMemorija& rm, int id_procesa, int potrebno, int kasnjenje, int trajanje) {
  223.     this_thread::sleep_for(chrono::seconds(kasnjenje));
  224.     {
  225.         unique_lock<mutex> l(term_m);
  226.         cout << "Proces " << id_procesa << " zeli da zauzme " << potrebno << " KB memorije." << endl;
  227.        
  228.     }
  229.     rm.zauzmi(id_procesa, potrebno);
  230.     {
  231.         unique_lock<mutex> l(term_m);
  232.         cout << "Proces " << id_procesa << " zauzeo " << potrebno << " KB memorije." << endl;
  233.     }
  234.     this_thread::sleep_for(chrono::seconds(trajanje));
  235.     {
  236.         unique_lock<mutex> l(term_m);
  237.         cout << "Proces " << id_procesa << " oslobadja memoriju." << endl;
  238.     }
  239.     rm.oslobodi(id_procesa);
  240.     {
  241.         unique_lock<mutex> l(term_m);
  242.         cout << "Proces " << id_procesa << " zavrsio." << endl;
  243.     }
  244. }
  245.  
  246. const int BROJ_PROCESA = 5;
  247.  
  248. int main() {
  249.     RadnaMemorija rm(10);
  250.     vector<int> velicine = { 100, 240, 64, 256, 75 };
  251.     vector<int> kasnjenje = { 0, 1, 2, 3, 6 };
  252.     vector<int> trajanje = { 5, 3, 5, 6, 2 };
  253.     thread procesi[BROJ_PROCESA];
  254.  
  255.     for (int i = 0; i < BROJ_PROCESA; ++i)
  256.         procesi[i] = thread(proces, ref(rm), i + 1, velicine[i], kasnjenje[i], trajanje[i]);
  257.  
  258.     for (int i = 0; i < BROJ_PROCESA; ++i)
  259.         procesi[i].join();
  260.  
  261.     cout << "Press enter to continujes: ";
  262.     cin.get();
  263. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement