In-memory cacher
Chivereanu Radu-Gabriel, Dinu Dumitru-Razvan 335CA


-- LINUX --
Pentru rezolvarea acestei probleme am mapat fisiere in memorie si in momentul in care se apeleaza flush
sincronizam cu msync.

-> Functionalitatile de baza au toate implementare -> Trec toate testele.
-> BONUS: Fisierul nu contine null suplimentar atunci cand se apeleaza flush, intrucat avem 
grija sa il retrunchiem la dimensiunile necesare.
-> BONUS: Snapshot -> La un interval de x secunde (in cod, 15 pentru debug) se arunca un semnal (folisind un timer) care cand este prins creaza un proces copie care se opreste cu o functie blocanta (in cazul de fata getchar()). In cazul in care procesul principal crapa, putem debloca si inspecta unul din procesele copie care inca ruleaza.
-> BONUS: Folosim select pentru a detecta daca un client doreste sa se conecteze. Nu am apucat sa extindem si pentru celelalte apeluri.



Cool stuff!
Partea cea mai interesanta este paralelizarea:

In loc sa avem cate un thread pentru fiecare client (Ineficient in momentul in care sunt multi clienti din cauza multiplelor context switchuri), avem o abordarea de tipul thread pool.

Folosim o lista inlantuita cu care simulam o coada. Ideea este urmatoarea:

-> Acesul coada este protejat cu un mutex
-> Avem metoda add care ia lock ul cozii, adauga un client si notifica cu variabila conditionala a cozii
threadurile care asteapta
-> Un thread care asteapta, in momentul in care este notificat, extrage primul client din coada. Aceasta extragere se face sincronizat. Dupa extragere, elibereaza locul si proceseaza o comanda a clientului. Daca clientul nu a dat disconnect, la sfarsitul executarii comenzii, il readauga in coada pentru a fi din nou preluat.
-> Startul este dat de threadul main, care atunci cand prinde conexiuni cu clienti ii adauga in coada, de unde sunt preluati de threadurile worker.

-- WINDOWS --

Pentru windows este acelasi rationament cu maparea fisierelor.
Am folosit api-ul linux pentru a utiliza thread pool, mergand pe aceeasi idee ca la Linux (aici, functia care executa o comanda pentru client este callback).

Din pacate, din cauza multelor argumente necesare pentru apelul functiilor din win32, nu am reusit sa facem codul sa treaca testele.