Skip to content

Commit

Permalink
extract tar now that non-kebab-case filenames are supported
Browse files Browse the repository at this point in the history
  • Loading branch information
lucat1 committed Jul 26, 2023
1 parent 4e46683 commit 451e192
Show file tree
Hide file tree
Showing 9 changed files with 495 additions and 0 deletions.
Binary file not shown.
18 changes: 18 additions & 0 deletions prove/scritto/scritto-2022-07-20-soluzione-c1libera/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
CFLAGS=-I.
LDLIBS=-lpthread
ALL= esercizio

all: $(ALL)

esercizio: esercizio.o monitor.o suspend.o tlist.o

monitor.o: monitor.c suspend.h tlist.h

semaphore.o: semaphore.c suspend.h tlist.h

suspend.o: suspend.c

tlist.o: tlist.c

clean:
rm -f *.o $(ALL)
183 changes: 183 additions & 0 deletions prove/scritto/scritto-2022-07-20-soluzione-c1libera/esercizio.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
//https://github.com/csunibo/sistemi-operativi/blob/main/prove/scritto/scritto-2022-07-20-testo.pdf
//esercizio c1:
/*In un porto con una sola banchina utilizzabile occorre caricare cereali sulle navi. I camion portano i cereali al porto. Una sola nave alla volta può essere attraccata al molo, un solo camion alla volta scarica i cereali nella nave.
Il codice eseguito da ogni nave è:
nave[i] process:
porto.attracca(capacità)
porto.salpa()
...naviga verso la destinazione
il codice di ogni camion è:
camion[j] process:
while(true):
quantità = carica_cereali()
porto.scarica(quantità)
I camion fanno la spola dai depositi alla nave. La nave arriva vuota e può salpare solo se è stata completamente riempita (la somma delle quantità scaricate dai camion raggiunge la capacità indicata come parametro della funzione attracca). Se un camion può scaricare solo parzialmente il suo carico rimane in porto e aspetta di completare l'operazione con la prossima nave che attraccherà al molo.
Scrivere il monitor porto.
*/


//soluzione es c.1 del prof Davoli

/*
monitor porto(){
boolean is_molo_free = true //per la nave
boolean is_park_free = true //per il camion
int dariempire=0 //per la nave, quanto è ancora da riempire?
condition ok2attracca;
condition ok2salpa;
condition ok2scarica;
condition ok2ancora;
porto attracca(capacita){
if (is_molo_free == false)
ok2attracca.wait() //se il molo è occupato fermati ad aspettare
is_molo_free = False //attracca.
dariempire = capacita
ok2ancora.signal()
porto.salpa(){
if (dariempire > 0)
ok2salpa.wait() //posso salpare solo se ho saturato la capacità della nave
is_molo_free = True //salpa.
ok2attracca.signal() //sblocchiamo le navi in attesa del molo libero
porto scarica(quantita){
if (is_park_free == false)
ok2scarica.wait() //se il parcheggio è occupato fermati ad aspettare
is_park_free = False //parcheggia.
while (quantita > dariempire){ //la quantità non può essere versata completamente
quantita -= dariempire //metti quello che ci sta sulla nave
dariempire = 0 //satura la nave
ok2salpa.signal() //lascia andare la nave
ok2ancora . wait() //il camion deve aspettare la prossima nave
}
dariempire -= quantita //metti tutta la capacità del camion sulla nave
if (dariempire == 0) //ora la nave è riempita?
ok2salpa.signal()
is_park_free = True //il camion se ne va
ok2scarica.signal;
}
*/


//riscritta in linguaggio C per l'esecuzione da Longo Libera

#include<stdio.h>
#include<pthread.h>
#include<stdbool.h>
#include<monitor.h>
#include<stdint.h>

#define HUMAN_READABLE_ATTESA 10000
#define RANDOM_ATTESA 2000000
#define DORMITINA_RANDOM() (usleep( HUMAN_READABLE_ATTESA + (random() % RANDOM_ATTESA) ))

volatile bool is_molo_free = true; //per la nave
volatile bool is_park_free = true; //per il camion
volatile int dariempire = 0; //per la nave, quanto è ancora da riempire?

monitor porto;
condition ok2attracca;
condition ok2salpa;
condition ok2scarica;
condition ok2ancora;

void porto_create(void) {
porto = monitor_create();
ok2attracca = condition_create(porto);
ok2salpa = condition_create(porto);
ok2scarica = condition_create(porto);
ok2ancora = condition_create(porto);
}

void porto_attracca(int capacita) {
monitor_enter(porto);
if (is_molo_free == false)
condition_wait(ok2attracca);//se il molo è occupato fermati ad aspettare
is_molo_free = false;//attracca.
dariempire = capacita;
condition_signal(ok2ancora);
monitor_exit(porto);
}

void porto_salpa() {
monitor_enter(porto);
if(dariempire > 0)
condition_wait(ok2salpa); //posso salpare solo se ho saturato la capacità della nave
is_molo_free = true; //salpa.
condition_signal(ok2attracca); //sblocchiamo le navi in attesa del molo libero
monitor_exit(porto);
}

void porto_scarica(int quantita) {
monitor_enter(porto);
if(is_park_free == false)
condition_wait(ok2scarica); //se il parcheggio è occupato fermati ad aspettare
is_park_free = false; //parcheggia
while (quantita > dariempire){ //la quantità non può essere versata completamente
quantita -= dariempire; //metti quello che ci sta sulla nave
dariempire = 0; //satura la nave
condition_signal(ok2salpa); //lascia andare la nave
condition_wait(ok2ancora); //il camion deve aspettare la prossima nave
}
dariempire -= quantita; //metti tutta la capacità del camion sulla nave
if (dariempire == 0) //ora la nave è riempita?
condition_signal(ok2salpa);
is_park_free = true; //il camion se ne va
condition_signal(ok2scarica);
monitor_exit(porto);
}


void *nave(void *arg) {
int i = (uintptr_t)arg;
while (1) {
printf("\t\t\tnave %d ready\n", i);
int nave_capienza = random() % 300;
printf("\t\t\tcapienza_nave %d = %d\n", i, nave_capienza);
DORMITINA_RANDOM();
porto_attracca(nave_capienza);
printf("\t\t\tattracca %d\n", i);
DORMITINA_RANDOM();
porto_salpa();
printf("\t\t\tsalpa %d\n", i);
printf("\t\t\t...%d naviga verso la destinazione...\n", i);
DORMITINA_RANDOM();
}
}

void *camion(void *arg) {
int i = (uintptr_t)arg;
while (1) {
printf("camion %d ready\n", i);
DORMITINA_RANDOM();
int cereali_sul_camion = random() % 300;
printf("sul_camion %d = %d\n", i, cereali_sul_camion);
DORMITINA_RANDOM();
porto_scarica(cereali_sul_camion);
printf("scarica %d\n", i);
DORMITINA_RANDOM();
}
}


int main(int argc, char *argv[]) {

const int NAVI = 3; //quante navi ci sono? puoi cambiare questo numero purchè sia >= 1
const int CAMION = 5; //quanti camion ci sono? puoi cambiare questo numero purchè sia >= 1

int i;
pthread_t nave_t[NAVI];
pthread_t camion_t[CAMION];
porto_create();
srandom(time(NULL));
for (i=0; i<NAVI; i++)
pthread_create(&nave_t[i], NULL, nave, (void *)(uintptr_t) i);
for (i=0; i<CAMION; i++)
pthread_create(&camion_t[i], NULL, camion, (void *)(uintptr_t) i);
for (i=0; i<NAVI; i++)
pthread_join(nave_t[i], NULL);
for (i=0; i<CAMION; i++)
pthread_join(camion_t[i], NULL);
}

106 changes: 106 additions & 0 deletions prove/scritto/scritto-2022-07-20-soluzione-c1libera/monitor.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* sm: educational resources to teach concurrent programming
* Copyright (C) 2016 Renzo Davoli, University of Bologna
*
* implementation of monitors
*
* sm is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; If not, see <http://www.gnu.org/licenses/>.
*
*/

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<suspend.h>
#include<monitor.h>
#include<tlist.h>

#define mutex_in(X) pthread_mutex_lock(X)
#define mutex_out(X) pthread_mutex_unlock(X)

struct monitor {
pthread_mutex_t lock;
struct tlist *urgent;
};

typedef struct monitor *monitor;

struct condition {
monitor m;
struct tlist *q;
};

typedef struct condition *condition;

monitor monitor_create(void) {
monitor m = malloc(sizeof(*m));
if (m) {
pthread_mutex_init(&m->lock, NULL);
m->urgent = NULL;
}
return m;
}

void monitor_destroy(monitor m) {
pthread_mutex_destroy(&m->lock);
free(m);
}

void monitor_enter(monitor m) {
//printf("enter %p\n",m);
mutex_in(&m->lock);
}

void monitor_exit(monitor m) {
//printf("exit %p\n",m);
if (!tlist_empty(m->urgent)) {
pthread_t t = tlist_pop(&m->urgent);
wakeup(t);
} else
mutex_out(&m->lock);
}

condition condition_create(monitor m) {
condition c = malloc(sizeof(*c));
if (c) {
c->m = m;
c->q = NULL;
}
return c;
}

void condition_destroy(condition c) {
free(c);
}

void condition_wait(condition c) {
//printf("wait %p\n",c);
tlist_enqueue(&c->q, pthread_self());
monitor_exit(c->m);
suspend();
}

void condition_signal(condition c) {
//printf("signal %p\n",c);
if (!tlist_empty(c->q)) {
monitor m = c->m;
pthread_t t = tlist_dequeue(&c->q);
tlist_push(&m->urgent, pthread_self());
wakeup(t);
suspend();
}
}


32 changes: 32 additions & 0 deletions prove/scritto/scritto-2022-07-20-soluzione-c1libera/monitor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef MONITOR_H
#define MONITOR_H
#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<suspend.h>
#include<semaphore.h>

struct monitor;
typedef struct monitor *monitor;
struct condition;
typedef struct condition *condition;

monitor monitor_create(void);

void monitor_destroy(monitor m);

void monitor_enter(monitor m);

void monitor_exit(monitor m);

condition condition_create(monitor m);

void condition_destroy(condition c);

void condition_wait(condition c);

void condition_signal(condition c);

#endif

43 changes: 43 additions & 0 deletions prove/scritto/scritto-2022-07-20-soluzione-c1libera/suspend.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* sm: educational resources to teach concurrent programming
* Copyright (C) 2016 Renzo Davoli, University of Bologna
*
* thread suspend and wakeup
*
* sm is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; If not, see <http://www.gnu.org/licenses/>.
*
*/

#include<pthread.h>
#include<signal.h>
#include<suspend.h>

void suspend(void) {
int sig;
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
sigwait(&set, &sig);
}

void wakeup(pthread_t thread) {
pthread_kill(thread, SIGUSR1);
}

__attribute__((constructor)) void _suspend_init() {
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
pthread_sigmask(SIG_BLOCK, &set, NULL);
}
11 changes: 11 additions & 0 deletions prove/scritto/scritto-2022-07-20-soluzione-c1libera/suspend.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef SUSPEND_H
#define SUSPEND_H
#include<pthread.h>

void suspend(void);

void wakeup(pthread_t thread);

__attribute__((constructor)) void _suspend_init();

#endif // SUSPEND_H
Loading

0 comments on commit 451e192

Please sign in to comment.