Zibaldone

From Sistemi Operativi
Revision as of 18:04, 10 November 2016 by Renzo (talk | contribs) (Created page with "Codice '''ERRATO''' dei lettori scrittori che dovrebbe non soffrire di problemi di starvation... Esercizio: trovare gli errori. <syntaxhighlight lang=C> #include<stdio.h> #in...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Codice ERRATO dei lettori scrittori che dovrebbe non soffrire di problemi di starvation... Esercizio: trovare gli errori.

#include<stdio.h>
#include<stdint.h>
#include<pthread.h>
#include<semaphore.h>

#define NREADER 3
#define NWRITER 3
semaphore mutex;
semaphore ok2read;
semaphore ok2write;

int nr=0;
int nw=0;
int wr=0;
int ww=0;
int w_last;

// (nw == 0 && nr == 0) || (nr > 0 && nw == 0) || nw == 1
// (nw == 0 && nr >= 0) || nw == 1

// this "baton" function has been left for reference only.
// code to implement "passing the baton" has been copied at the end of
// each ({start}|{end})({read}|{write}) function and reduced.
void baton(void) {
        if (nw == 0 && nr == 0 && ww > 0)
                semaphore_V(ok2write);
        else if (nw == 0 && wr > 0 )
                semaphore_V(ok2read);
        else
                semaphore_V(mutex);
}

void startread(void) {
// <await nw == 0 -> nr++>
        semaphore_P(mutex);
        if (nw > 0 && ww == 0) {
                wr++;
                semaphore_V(mutex);
                semaphore_P(ok2read);
                wr--;
        }
        nr++;
        w_last=0;
        printf("NR %d - NW %d - WR %d - WW %d \n", nr, nw, wr, ww);
        if (wr > 0 )
                semaphore_V(ok2read);
        else
                semaphore_V(mutex);
}

void endread(void) {
// <nr-->
        semaphore_P(mutex);
        nr--;
        printf("NR %d - NW %d - WR %d - WW %d \n", nr, nw, wr, ww);
        if (nr == 0 && ww > 0)
                semaphore_V(ok2write);
        else
                semaphore_V(mutex);
}

void startwrite(void) {
// <await nw == 0 && nr == 0 -> nw++>
        semaphore_P(mutex);
        if (nw > 0 || nr > 0) {
                ww++;
                semaphore_V(mutex);
                semaphore_P(ok2write);
                ww--;
        }
        nw++;
        w_last=1;
        printf("NR %d - NW %d - WR %d - WW %d \n", nr, nw, wr, ww);
        semaphore_V(mutex);
}

void endwrite(void) {
// <nw-->
        semaphore_P(mutex);
        nw--;
        printf("NR %d - NW %d - WR %d - WW %d \n", nr, nw, wr, ww);
        if (wr > 0 && (ww == 0 || w_last))
                semaphore_V(ok2read);
        else if (ww > 0 && (wr == 0 || !w_last))
                semaphore_V(ok2write);
        else
                semaphore_V(mutex);
}

void *reader(void *arg) {
        int i = (uintptr_t)arg;
        while (1) {
                //other code
                usleep(random() % 200000);
                startread();
                //read
                usleep(random() % 200000);
                endread();
        }
}

void *writer(void *arg) {
        int i = (uintptr_t)arg;
        while (1) {
                //other code
                usleep(random() % 200000);
                startwrite();
                //write
                usleep(random() % 200000);
                endwrite();
        }
}


//printf("philo thinking: %d\n",i);
/*while*/

int main(int argc, char *argv[]) {
        int i;
        pthread_t t;
        srandom(time(NULL));
        mutex=semaphore_create(1);
        ok2read=semaphore_create(0);
        ok2write=semaphore_create(0);
        for (i=0; i<NREADER; i++)
                pthread_create(&t, NULL, reader, (void *)(uintptr_t) i);
        for (i=0; i<NWRITER; i++)
                pthread_create(&t, NULL, writer, (void *)(uintptr_t) i);
        while(1)
                pause();
}