OS1/Modifikacije jun 2021

Izvor: SI Wiki
Pređi na navigaciju Pređi na pretragu

Sledeće modifikacije su se pojavile na odbrani projekta u junskom roku 2021.

20 poena

  • Sledeća stavka ista je kao 1. zadatak sa drugog kolokvijuma u junskom roku 2017. godine: Školsko jezgro treba proširiti konceptom barijere ("ograda", "rampa", engl. barrier) čiji je interfejs dat dole. Semantika ovog koncepta i operacija nad njim je sledeća:
    • Barijera može biti u jednom od dva stanja: otvorena ili zatvorena. Barijera se inicijalizuje zadatim stanjem (argument konstruktora). Nit u čijem kontekstu se kreira barijera (tj. izvršava konstruktor) je njen vlasnik.
    • void Barrier::pass(): ukoliko pozivajuća nit nije vlasnik ove barijere, ova operacija nema efekta - nit nastavlja svoje izvršavanje; ukoliko je pozivajuća nit vlasnik barijere, a barijera zatvorena, nit se suspenduje (blokira) sve dok se barijera ne otvori; ako je barijera otvorena, nit nastavlja izvršavanje bez blokade;
    • void Barrier::close(): zatvara barijeru;
    • void Barrier::open(): otvara barijeru i eventualno deblokira nit koja je na barijeri blokirana.
  • Napisati javni test sa dve niti A i B. Nit B pravi globalni semafor sa vrednošću 0 i globalnu barijeru sa vrednošću 1, a nit A uposleno čeka dok se oni ne naprave. Nit A treba ciklično da poziva Barrier::open(), Barrier::pass() i Semaphore::wait(0), dok nit B treba ciklično da poziva Barrier::pass(), Barrier::close() i Semaphore::signal().
class Barrier {
public:
    Barrier (int open=1);
    void open();
    void close();
    void pass();
};

Rešenje

Okvirno rešenje može se naći kao rešenje pomenutog kolokvijuma. Test opisan tekstom zadatka.

#include "thread.h"
#include "semaphor.h"
#include "barrier.h"
#include "intLock.h"

Semaphore *s = 0;
Barrier *b = 0;
Semaphore waiter(0);

class MyA : public Thread {
public:
	MyA() : Thread() {}
	~MyA() { waitToComplete(); }
protected:
	void run() {
		while (s == 0 || b == 0) {}

		while (1) {
			b->open();
			intLock
			cout << "A opened the barrier" << endl;
			intUnlock
			b->pass();
			intLock
			cout << "A passed the barrier" << endl;
			intUnlock
			s->wait(0);
		}
	}
};


class MyB : public Thread {
public:
	MyB() : Thread() {}
	~MyB() { waitToComplete(); }
protected:
	void run() {
		s = new Semaphore(0);
		b = new Barrier(1);
		while (1) {

			b->pass();
			intLock
			cout << "B passed the barrier" << endl;
			intUnlock
			b->close();
			intLock
			cout << "B closed the barrier" << endl;
			intUnlock
			s->signal();
			waiter.wait(30);
		}
	}
};

void tick() {}

int userMain(int argc, char *argv[]) {
	MyA a;
	MyB b;
	a.start();
	b.start();
	a.waitToComplete();
	b.waitToComplete();
}

30 poena

  • Napraviti da se nakon poziva fork() kao sledeća nit za izvršavanje izabere dete (pre izlaska iz fork() u roditeljskoj niti). Takođe, forsirati da se prvo biraju niti bez dece.
  • Napisati test primer koji testira zadatu funkcionalnost. Na primer, može da izgleda poput:
int result = Thread::fork();
if (result != -1) {
    if (result == 0) {
        intLock
        cout << "Child!" << endl;
        intUnlock
        Thread::exit();
    } else {
        intLock
        cout << "Parent!" << endl;
        intUnlock
        Thread::waitForForkChildren();
    }
}

Rešenje

  • Rešenje za biranje deteta jeste da se u PCB doda pokazivač na dete koje je izabrano koji se postavlja na novonapravljeno dete u fork(), proverava da li je nullptr u tajmeru (u koji se ušlo pozivom funkcije dispatch() unutar funkcije fork()), ako nije onda se nit koja je sledeća za izvršavanje postavlja na to dete i pokazivač se vraća na nullptr.
  • Jedno rešenje za forsiranje niti koje nemaju decu jeste da se, ukoliko se ne dešava biranje deteta, iz Scheduler vade niti dok se ne pronađe nit bez dece (koja se odmah postavi kao nit za izvršavanje) ili dok se ne izbace sve niti, ako su izvađene niti sa decom one se ubacuju u drugu listu i na kraju se vraćaju nazad u Scheduler. Ukoliko nit bez dece nije pronađena, između vađenja i vraćanja niti proverava se da li je izvučena ijedna nit bez dece i vadi se jedna nit sa decom ukoliko nije.