<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="sr">
	<id>https://siwiki.rs/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Vuk+Davidovi%C4%87</id>
	<title>SI Wiki - Кориснички доприноси [sr]</title>
	<link rel="self" type="application/atom+xml" href="https://siwiki.rs/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Vuk+Davidovi%C4%87"/>
	<link rel="alternate" type="text/html" href="https://siwiki.rs/wiki/%D0%9F%D0%BE%D1%81%D0%B5%D0%B1%D0%BD%D0%BE:%D0%94%D0%BE%D0%BF%D1%80%D0%B8%D0%BD%D0%BE%D1%81%D0%B8/Vuk_Davidovi%C4%87"/>
	<updated>2026-06-04T09:06:00Z</updated>
	<subtitle>Кориснички доприноси</subtitle>
	<generator>MediaWiki 1.39.8</generator>
	<entry>
		<id>https://siwiki.rs/w/index.php?title=%D0%9E%D0%A11/%D0%9C%D0%BE%D0%B4%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%98%D0%B5_%D1%84%D0%B5%D0%B1%D1%80%D1%83%D0%B0%D1%80_2023&amp;diff=5818</id>
		<title>ОС1/Модификације фебруар 2023</title>
		<link rel="alternate" type="text/html" href="https://siwiki.rs/w/index.php?title=%D0%9E%D0%A11/%D0%9C%D0%BE%D0%B4%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%98%D0%B5_%D1%84%D0%B5%D0%B1%D1%80%D1%83%D0%B0%D1%80_2023&amp;diff=5818"/>
		<updated>2023-02-25T00:29:29Z</updated>

		<summary type="html">&lt;p&gt;Vuk Davidović: Dodate modifikacije za Februar 2023. i rešena prva modifikacija&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Sledeće modifikacije su se pojavile na odbrani projekta u februarskom roku 2023.&lt;br /&gt;
&lt;br /&gt;
Mogli ste da izabere da radite ili 1. modifikaciju ili 2. modifikaciju.&lt;br /&gt;
&lt;br /&gt;
== Modifikacija bez asinhrone promene konteksta ==&lt;br /&gt;
* Dodati sistemski poziv čija je deklaracija &amp;lt;code&amp;gt;void thread_join(thread_t* handle)&amp;lt;/code&amp;gt; koji tekuću nit zaustavlja dok se ne završi izvršavanje niti označene ručkom &amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt;. U okviru C++ API dodati nestatičku metodu klasi &amp;lt;code&amp;gt;Thread&amp;lt;/code&amp;gt; sa deklaracijom &amp;lt;code&amp;gt;void join()&amp;lt;/code&amp;gt;. Napisati test program koristeći C++ API sa tri niti, gde će jedna nit čekati da se završe druge dve. Svaka nit na početku ispisuje poruku koja je to nit, zatim radi neku obradu(implementirati ugnježdenim petljama) i na kraju ispisuje poruku da se završila.&lt;br /&gt;
&lt;br /&gt;
=== Rešenje ===&lt;br /&gt;
&lt;br /&gt;
syscall_c.hpp&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
class TCB;&lt;br /&gt;
typedef TCB* thread_t;&lt;br /&gt;
&lt;br /&gt;
void thread_join(thread_t* handle);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
syscall_c.cpp&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void thread_join(thread_t* handle)&lt;br /&gt;
{&lt;br /&gt;
    uint64 number = 0x03; // Mogao je bilokoji, slobodan, ulaz&lt;br /&gt;
&lt;br /&gt;
    __asm__ volatile(&amp;quot;mv a1, %0&amp;quot; : : &amp;quot;r&amp;quot; (handle));&lt;br /&gt;
    __asm__ volatile(&amp;quot;mv a0, %0&amp;quot; : : &amp;quot;r&amp;quot; (number));&lt;br /&gt;
&lt;br /&gt;
    __asm__ volatile(&amp;quot;ecall&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TCB.hpp&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
typedef TCB* thread_t;&lt;br /&gt;
&lt;br /&gt;
class TCB&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	// ...&lt;br /&gt;
private:&lt;br /&gt;
	// ...&lt;br /&gt;
    static void join (thread_t* handle);&lt;br /&gt;
    // ...&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TCB.cpp&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
/* Glavni deo resenja */&lt;br /&gt;
void TCB::join(thread_t* handle)&lt;br /&gt;
{&lt;br /&gt;
	while(!(*handle)-&amp;gt;isFinished())&lt;br /&gt;
		TCB::dispatch();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
riscv.cpp&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
case 0x03: // Mogao je bilokoji, slobodan, ulaz&lt;br /&gt;
{&lt;br /&gt;
	thread_t *handle;&lt;br /&gt;
	__asm__ volatile (&amp;quot;mv %0, a1&amp;quot; : &amp;quot;=r&amp;quot; (handle));&lt;br /&gt;
&lt;br /&gt;
	TCB::join(handle);&lt;br /&gt;
&lt;br /&gt;
    break;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
syscall_cpp.hpp&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
class Thread&lt;br /&gt;
{&lt;br /&gt;
public:&lt;br /&gt;
	// ...&lt;br /&gt;
    void join(); // Obavezno nestaticka metoda&lt;br /&gt;
protected:&lt;br /&gt;
    // ...&lt;br /&gt;
private:&lt;br /&gt;
    thread_t myHandle; // Ovo je vec postojalo&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
syscall_cpp.cpp&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
void Thread::join()&lt;br /&gt;
{&lt;br /&gt;
	if (myHandle)&lt;br /&gt;
		thread_join(&amp;amp;myHandle);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
main.cpp&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;quot;../h/syscall_cpp.hpp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
bool finishedA = false;&lt;br /&gt;
bool finishedB = false;&lt;br /&gt;
&lt;br /&gt;
class WorkerA: public Thread&lt;br /&gt;
{&lt;br /&gt;
    void mod_fun_A(void* arg);&lt;br /&gt;
public:&lt;br /&gt;
    WorkerA():Thread() {}&lt;br /&gt;
&lt;br /&gt;
    void run() override&lt;br /&gt;
    {&lt;br /&gt;
        mod_fun_A(nullptr);&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class WorkerB: public Thread&lt;br /&gt;
{&lt;br /&gt;
    void mod_fun_B(void* arg);&lt;br /&gt;
public:&lt;br /&gt;
    WorkerB():Thread() {}&lt;br /&gt;
&lt;br /&gt;
    void run() override&lt;br /&gt;
    {&lt;br /&gt;
        mod_fun_B(nullptr);&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
void WorkerA::mod_fun_A(void *arg)&lt;br /&gt;
{&lt;br /&gt;
    for (uint64 i = 0; i &amp;lt; 10; i++)&lt;br /&gt;
    {&lt;br /&gt;
        printString(&amp;quot;A: i=&amp;quot;);&lt;br /&gt;
        printInt(i);&lt;br /&gt;
        printString(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        for (uint64 j = 0; j &amp;lt; 10000; j++)&lt;br /&gt;
        {&lt;br /&gt;
            for (uint64 k = 0; k &amp;lt; 30000; k++)&lt;br /&gt;
            {&lt;br /&gt;
                /* busy wait */&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            thread_dispatch();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    printString(&amp;quot;A finished!\n&amp;quot;);&lt;br /&gt;
    finishedA = true;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void WorkerB::mod_fun_B(void *arg)&lt;br /&gt;
{&lt;br /&gt;
    for (uint64 i = 0; i &amp;lt; 16; i++)&lt;br /&gt;
    {&lt;br /&gt;
        printString(&amp;quot;B: i=&amp;quot;);&lt;br /&gt;
        printInt(i);&lt;br /&gt;
        printString(&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
        for (uint64 j = 0; j &amp;lt; 10000; j++)&lt;br /&gt;
        {&lt;br /&gt;
            for (uint64 k = 0; k &amp;lt; 30000; k++)&lt;br /&gt;
            {&lt;br /&gt;
                /* busy wait */&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            thread_dispatch();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    printString(&amp;quot;B finished!\n&amp;quot;);&lt;br /&gt;
    finishedB = true;&lt;br /&gt;
    thread_dispatch();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    Riscv::w_stvec((uint64) &amp;amp;Riscv::supervisorTrap);&lt;br /&gt;
&lt;br /&gt;
    Thread* main = new Thread(nullptr, nullptr);&lt;br /&gt;
    printString(&amp;quot;Main Created\n&amp;quot;);&lt;br /&gt;
    TCB::running = main-&amp;gt;getMyHandle();&lt;br /&gt;
&lt;br /&gt;
    /* Modifikacija */&lt;br /&gt;
    Thread* threads[2];&lt;br /&gt;
&lt;br /&gt;
    threads[0] = new WorkerA();&lt;br /&gt;
    printString(&amp;quot;ThreadA created\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    threads[1] = new WorkerB();&lt;br /&gt;
    printString(&amp;quot;ThreadB created\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    for(int i = 0; i &amp;lt; 2; i++)&lt;br /&gt;
        threads[i]-&amp;gt;start();&lt;br /&gt;
&lt;br /&gt;
    threads[0]-&amp;gt;join(); // Blokiraj main nit(u ovom slucaju) dok se nit 0 ne zavrsi&lt;br /&gt;
    threads[1]-&amp;gt;join(); // Blokiraj main nit(u ovom slucaju) dok se nit 1 ne zavrsi&lt;br /&gt;
&lt;br /&gt;
    for (auto thread: threads)&lt;br /&gt;
        delete thread;&lt;br /&gt;
&lt;br /&gt;
    printString(&amp;quot;Main Stopped\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Dodatno ===&lt;br /&gt;
Dodatno, prilikom ispitivanja, tražili su da nit A čeka da se završi nit B. U tom slučaju morali smo ovo:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
threads[0] = new WorkerA();&lt;br /&gt;
printString(&amp;quot;ThreadA created\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
threads[1] = new WorkerB();&lt;br /&gt;
printString(&amp;quot;ThreadB created\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
for(int i = 0; i &amp;lt; 2; i++)&lt;br /&gt;
    threads[i]-&amp;gt;start();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
da definisemo globalno u fajlu &amp;quot;main.cpp&amp;quot; i da&lt;br /&gt;
nakon kreiranja main-a, odmah uradimo dispatch.&lt;br /&gt;
&lt;br /&gt;
A onda da unutar funkcije &amp;quot;mod_fun_A&amp;quot;, stavimo:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
threads[1]-&amp;gt;join();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
threads[1] je nit B.&lt;br /&gt;
&lt;br /&gt;
== Modifikacija sa asinhronom promenom konteksta ==&lt;br /&gt;
* Dodati sitemski poziv čija je deklaracija &amp;lt;code&amp;gt;void thread_join(thread_t* handle, time_t t)&amp;lt;/code&amp;gt; koji tekuću nit zaustavlja dok se ne završi izvršavanje niti označenom ručkom &amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; ukoliko je &amp;lt;code&amp;gt;t&amp;lt;/code&amp;gt; jednako nuli, a ukoliko je &amp;lt;code&amp;gt;t&amp;lt;/code&amp;gt; veće od nule onda se tekuća nit zaustavlja maksimalno &amp;lt;code&amp;gt;t&amp;lt;/code&amp;gt; vremena ili kraće ukoliko se nit označena sa &amp;lt;code&amp;gt;handle&amp;lt;/code&amp;gt; završi. U okviru C++ API dodati metodu klasi &amp;lt;code&amp;gt;Thread&amp;lt;/code&amp;gt; sa deklaracijom &amp;lt;code&amp;gt;void join(time_t)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Napisati test program koristeći C++ API sa tri niti, gde će dve niti čekati da se završi treća nit, ali jedna treba da čeka maksimalno neko vreme &amp;lt;code&amp;gt;t&amp;lt;/code&amp;gt;, a druga dok se zaista ne završi treća nit. Treća nit treba da traje dovoljno dugo kako bi se ispoljilo opisano ponašanje. Svaka nit na početku ispisuje poruku koja je to nit, zatim radi neku obradu(implementirati ugnježdenim petljama) i na kraju ispisuje poruku da se završila. Dodatno, nit koja čeka maksimalno &amp;lt;code&amp;gt;t&amp;lt;/code&amp;gt; vremena treba nakon što istekne to vreme da ispiše poruku da je nastavila izvršavanje.&lt;/div&gt;</summary>
		<author><name>Vuk Davidović</name></author>
	</entry>
</feed>