Index: /trunk/Basic.java
===================================================================
--- /trunk/Basic.java	(revision 2)
+++ /trunk/Basic.java	(revision 2)
@@ -0,0 +1,34 @@
+class ClasseAttiva extends Thread{
+    public void run(){
+        while (true) {
+            try {
+                Thread.sleep(100);
+            }
+            catch(InterruptedException e){
+                System.err.println(e);
+            }
+            System.out.println(this.getName());
+        }
+    }
+}
+
+public class Basic {
+    public static final void main(final String[] args) {
+        ClasseAttiva o1 = new ClasseAttiva();
+        ClasseAttiva o2 = new ClasseAttiva();
+        o1.start();
+        o2.start();
+        while (true){
+            try {
+                Thread.sleep(100);
+            }
+            catch(InterruptedException e){
+                System.err.println(e);
+            }
+
+            System.out.println("Main thread");
+        }
+        
+    }
+}
+
Index: /trunk/Boot.s
===================================================================
--- /trunk/Boot.s	(revision 2)
+++ /trunk/Boot.s	(revision 2)
@@ -0,0 +1,109 @@
+/*	set to 16 bit mode (80x86 begin in real mode) text section to 0 */
+.code16
+.text
+.org 0x00
+
+.global _start
+_start:
+	mov $0x07C0,%ax		
+	mov %ax,%ds		
+
+	call booting
+	xor %dx,%dx		/* test if dx == 0 */
+	call working
+	call idleloop
+	ret
+
+booting:
+	mov $boot,%si
+	call message
+	call nl
+	ret
+
+message:
+	cld			/* set direction to increment */
+	lodsb
+	or %al,%al
+	jz done
+	mov $0xE,%ah 
+	mov $7,%bx
+	int $0x10
+	jmp message
+	
+done:
+	ret
+
+nl:	
+	mov $newline,%si 
+	call message
+	ret
+
+working:
+	call nl
+	call nl
+	mov $device,%si
+	call message
+	call waitenter
+	inc %dx
+	cmp $3,%dx
+	je keyboard
+	jmp working
+
+waitenter:
+	call nl
+	movw $cont,%si 
+	call message
+	xor %ax,%ax 	/* Sets AH=0 and AL=0 */
+	int $0x16 	/* Wait for keypress */
+	cmp 'T',%al 
+	jz taz
+	cmp 't',%al 
+	jz taz
+	cmp $13,%al 
+	jnz waitenter
+	ret
+
+keyboard:
+	call nl
+	call nl
+	movw $kbd,%si 
+	call message
+	call nl
+	movw cont,%si
+	call message
+	ret
+
+taz:
+	call nl
+	call nl
+	movw tazq,%si 
+	call message
+	jmp waitenter
+
+idleloop:
+	hlt
+	jmp idleloop
+
+boot: 	
+	.ascii "Loading UniOS 1.1 Beta..."
+newline: 
+	.byte 10, 13, 0
+device: 
+	.ascii "Device not responding to SCSI command." 
+cont: 
+	.ascii "Hit ENTER to continue..."
+kbd: 
+	.ascii "Keyboard not responding to SCSI command."
+tazq: 
+	.ascii "Yes, TazQ is an Internet crack monkey on wheels."
+
+/* Fill with zero until boottag */
+padlen: 
+	.byte boottag - .
+
+.fill 10,1,0	
+/*	times 510-($-$$) db 0 */
+
+.org 510
+boottag:
+	.word 0xAA55
Index: /trunk/Makefile
===================================================================
--- /trunk/Makefile	(revision 2)
+++ /trunk/Makefile	(revision 2)
@@ -0,0 +1,36 @@
+CFLAGS=-m32
+LDFLAGS=-m32
+
+mioboot: mioboot.asm
+	nasm -l $@.lst -o $@ $<
+
+mioboot-nobios: mioboot-nobios.asm
+	nasm -l $@.lst -o $@ $<
+
+mioboot-nobios-simple: mioboot-nobios-simple.asm
+	nasm -l $@.lst -o $@ $<
+
+
+esercizio: esercizio.asm
+	nasm -f elf $<
+	gcc -o $@ esercizio.o
+
+pthreads-pc: pthreads-pc.c
+	cc -pthread pthreads-pc.c -o pthreads-pc
+
+fork-pc: fork-pc.c
+	cc fork-pc.c -o fork-pc
+
+tsl: tsl.asm
+	nasm -felf tsl.asm
+	gcc tsl.o -o tsl
+
+enter.o: enter.asm
+	nasm -felf enter.asm
+
+threads-tsl: threads-tsl.o enter.o
+
+
+.PHONY: clean
+clean:
+	rm -f mioboot mioboot-nobios mioboot-nobios-simple *.lst *~ semantic.cache esegui forca
Index: /trunk/PC.java
===================================================================
--- /trunk/PC.java	(revision 2)
+++ /trunk/PC.java	(revision 2)
@@ -0,0 +1,124 @@
+/**
+ * Describe class PC here.
+ *
+ *
+ * Created: Fri Jun  8 14:32:29 2007
+ *
+ * @author <a href="mailto:mattia.monga@unimi.it">Mattia Monga</a>
+ * @version 1.0
+ */
+
+class Actor extends Thread 
+{
+    public Actor(String nome){
+        super(nome);
+    }
+    
+    private Magazzino shared;
+    public final Magazzino getShared() {
+        return shared;
+    }
+    public final void setShared(final Magazzino newShared) {
+        this.shared = newShared;
+    }
+
+}
+
+
+class Produttore extends Actor {
+    public Produttore(String nome, Magazzino b) {
+        super(nome);
+        setShared(b);
+    }
+    
+    public void run(){
+        int i = 0;
+        while(true){
+            System.out.println(getName() + ": Inserisco " + i + " nel buffer");
+            getShared().put(i);
+            i += 1;
+        }
+    }
+}
+
+class Consumatore extends Actor{
+    public Consumatore(String nome, Magazzino b) {
+        super(nome);
+        setShared(b);
+    }
+    public void run(){
+        while(true){
+            int i = getShared().get();
+            System.out.println(getName() + ": Estraggo " + i + " dal buffer");
+
+        }
+    }
+}
+
+class Magazzino{
+    public final static int SIZE = 10;
+    private int[] memory = new int[SIZE];
+    private int quanti = 0;
+
+    public final int get() {
+        String n = Thread.currentThread().getName();
+        synchronized(syncPC){
+            while(isVuoto()){
+                System.out.println(n + " ha tentato di leggere");
+                try {
+                    syncPC.wait();
+                } catch (InterruptedException e) {
+                    System.err.println(e);
+                }
+            }
+            int ris = memory[--quanti];
+            if (quanti == SIZE - 1) syncPC.notifyAll();
+            System.out.println(n + " ha letto");
+            return ris;
+        }
+    }
+
+    public final void put(final int newMemory) {
+        String n = Thread.currentThread().getName();
+        synchronized(syncPC){
+            while (isPieno()){
+                System.out.println(n + " ha tentato di scrivere");
+                try {
+                    syncPC.wait();
+                } catch (InterruptedException e) {
+                    e.printStackTrace(System.err);
+                }
+            }
+            memory[quanti++] = newMemory;
+            if (quanti == 1) syncPC.notifyAll();
+            System.out.println(n + " ha scritto");
+        }
+    }
+
+    public final boolean isVuoto() {
+        return quanti == 0;
+    }
+
+    public final boolean isPieno() {
+        return quanti == SIZE;
+    }
+
+    private Object syncPC = new Object();
+}
+
+
+public class PC {
+
+    public static final void main(final String[] args) {
+        Magazzino x = new Magazzino();
+        Produttore a1 = new Produttore("Aldo", x);
+        Produttore a2 = new Produttore("Alberto", x);
+        Consumatore b = new Consumatore("Barbara", x);
+        a1.start();
+        b.start();
+        a2.start();
+    }
+
+}
+
+
Index: /trunk/PCMon.java
===================================================================
--- /trunk/PCMon.java	(revision 2)
+++ /trunk/PCMon.java	(revision 2)
@@ -0,0 +1,133 @@
+/**
+ * Describe class PC here.
+ *
+ *
+ * Created: Fri Jun  8 14:32:29 2007
+ *
+ * @author <a href="mailto:mattia.monga@unimi.it">Mattia Monga</a>
+ * @version 1.0
+ */
+import java.util.concurrent.locks.*;
+
+class Actor extends Thread 
+{
+    public Actor(String nome){
+        super(nome);
+    }
+    
+    private Magazzino shared;
+    public final Magazzino getShared() {
+        return shared;
+    }
+    public final void setShared(final Magazzino newShared) {
+        this.shared = newShared;
+    }
+
+}
+
+
+class Produttore extends Actor {
+    public Produttore(String nome, Magazzino b) {
+        super(nome);
+        setShared(b);
+    }
+    
+    public void run(){
+        int i = 0;
+        while(true){
+            System.out.println(getName() + ": Inserisco " + i + " nel buffer");
+            getShared().put(i);
+            i += 1;
+        }
+    }
+}
+
+class Consumatore extends Actor{
+    public Consumatore(String nome, Magazzino b) {
+        super(nome);
+        setShared(b);
+    }
+    public void run(){
+        while(true){
+            int i = getShared().get();
+            System.out.println(getName() + ": Estraggo " + i + " dal buffer");
+
+        }
+    }
+}
+
+class Magazzino{
+    public final static int SIZE = 10;
+    private int[] memory = new int[SIZE];
+    private int quanti = 0;
+    
+    public final int get() {
+        monitor.lock();
+        int ris = -1;
+        try{
+            String n = Thread.currentThread().getName();
+            while (isVuoto()){
+                System.out.println(n + " ha tentato di leggere");
+                empty.await();
+            }
+            ris = memory[--quanti];
+            if (quanti == SIZE - 1) full.signal();
+            System.out.println(n + " ha letto");
+        } catch (InterruptedException e){
+            System.err.println(e);
+        } finally {
+            monitor.unlock();
+            return ris;
+        }
+    }
+
+    public final void put(final int newMemory) {
+        monitor.lock();
+        try{
+            String n = Thread.currentThread().getName();
+            while (isPieno()){
+                System.out.println(n + " ha tentato di scrivere");
+                full.await();
+            }
+            memory[quanti++] = newMemory;
+            if (quanti == 1) empty.signal();
+            System.out.println(n + " ha scritto");
+        } catch (InterruptedException e){
+            System.err.println(e);
+        } finally {
+            monitor.unlock();
+        }
+    }
+
+    public final boolean isVuoto() {
+        return quanti == 0;
+    }
+
+    public final boolean isPieno() {
+        return quanti == SIZE;
+    }
+
+
+    private static final Lock monitor = new ReentrantLock();
+    private static final Condition empty = monitor.newCondition();
+    private static final Condition full = monitor.newCondition();
+
+
+}
+
+
+public class PCMon {
+
+    public static final void main(final String[] args) {
+        Magazzino x = new Magazzino();
+        Produttore a1 = new Produttore("Aldo", x);
+        Produttore a2 = new Produttore("Alberto", x);
+        Consumatore b = new Consumatore("Barbara", x);
+        a1.start();
+        b.start();
+        a2.start();
+    }
+
+}
+
+
Index: /trunk/PCSem.java
===================================================================
--- /trunk/PCSem.java	(revision 2)
+++ /trunk/PCSem.java	(revision 2)
@@ -0,0 +1,117 @@
+/**
+ * Describe class PC here.
+ *
+ *
+ * Created: Fri Jun  8 14:32:29 2007
+ *
+ * @author <a href="mailto:mattia.monga@unimi.it">Mattia Monga</a>
+ * @version 1.0
+ */
+
+import java.util.concurrent.Semaphore;
+
+class Actor extends Thread 
+{
+    public Actor(String nome){
+        super(nome);
+    }
+    
+    private Magazzino shared;
+    public final Magazzino getShared() {
+        return shared;
+    }
+    public final void setShared(final Magazzino newShared) {
+        this.shared = newShared;
+    }
+
+}
+
+
+class Produttore extends Actor {
+    public Produttore(String nome, Magazzino b) {
+        super(nome);
+        setShared(b);
+    }
+    
+    public void run(){
+        int i = 0;
+        while(true){
+            System.out.println(getName() + ": Inserisco " + i + " nel buffer");
+            getShared().put(i);
+            i += 1;
+        }
+    }
+}
+
+class Consumatore extends Actor{
+    public Consumatore(String nome, Magazzino b) {
+        super(nome);
+        setShared(b);
+    }
+    public void run(){
+        while(true){
+            int i = getShared().get();
+            System.out.println(getName() + ": Estraggo " + i + " dal buffer");
+
+        }
+    }
+}
+
+class Magazzino{
+    public final static int SIZE = 10;
+    private int[] memory = new int[SIZE];
+    private int quanti = 0;
+    
+    public final int get() {
+        try{
+            String n = Thread.currentThread().getName();
+            pieno.acquire();
+            mutex.acquire();
+            int ris = memory[--quanti];
+            mutex.release();
+            vuoto.release();
+        
+            System.out.println(n + " ha letto");
+            return ris;
+        }
+        catch(InterruptedException e){
+            System.err.println(e);
+            return -1;
+        }
+    }
+
+    public final void put(final int newMemory) {
+        try{
+            String n = Thread.currentThread().getName();
+            vuoto.acquire();
+            mutex.acquire();
+            memory[quanti++] = newMemory;
+            mutex.release();
+            pieno.release();
+            System.out.println(n + " ha scritto");
+        }
+        catch(InterruptedException e){
+            System.err.println(e);
+        }
+    }
+
+    private static final Semaphore mutex = new Semaphore(1);
+    private static final Semaphore pieno = new Semaphore(0);
+    private static final Semaphore vuoto = new Semaphore(SIZE);
+
+}
+
+
+public class PCSem {
+
+    public static final void main(final String[] args) {
+        Magazzino x = new Magazzino();
+        Produttore a1 = new Produttore("Aldo", x);
+        Produttore a2 = new Produttore("Alberto", x);
+        Consumatore b = new Consumatore("Barbara", x);
+        a1.start();
+        b.start();
+        a2.start();
+    }
+
+}
Index: /trunk/SemPC.java
===================================================================
--- /trunk/SemPC.java	(revision 2)
+++ /trunk/SemPC.java	(revision 2)
@@ -0,0 +1,73 @@
+import java.util.Vector;
+import java.util.concurrent.Semaphore;
+
+public class SemPC{
+    public static final int N = 10;
+    public static final void main(final String[] args) {
+        Vector<Object> shared = new Vector<Object>(N);
+        Semaphore mutex = new Semaphore(1);
+        Semaphore empty = new Semaphore(N);
+        Semaphore full = new Semaphore(0);
+        Producer p = new Producer(shared, mutex, empty, full);
+        Consumer c = new Consumer(shared, mutex, empty, full);
+        p.start(); c.start();
+    }
+}
+
+class Agent extends Thread{
+    protected Vector<Object> buf;
+    protected Semaphore mutex;
+    protected Semaphore empty;
+    protected Semaphore full;
+    public Agent(String name, Vector<Object> b, 
+                 Semaphore _mutex, Semaphore _empty, Semaphore _full){
+        super(name);
+        this.buf = b;
+        this.mutex = _mutex;
+        this.full = _full;
+        this.empty = _empty;
+    }
+}
+
+class Producer extends Agent{
+    public Producer(Vector<Object> b, 
+                    Semaphore _mutex, Semaphore _empty, Semaphore _full) { 
+        super("Producer", b, _mutex, _empty, _full); 
+    }
+    public void run(){
+        while (true){
+            Object o = new Object();
+            System.out.println("Ho prodotto " + o);
+            try {
+                this.empty.acquire();
+                this.mutex.acquire();
+                this.buf.add(o);
+                this.mutex.release();
+                this.full.release();
+            } catch (InterruptedException e) {
+                System.err.println(e);
+            }
+        }
+    }
+}
+
+class Consumer extends Agent{
+    public Consumer(Vector<Object> b,
+                    Semaphore _mutex, Semaphore _empty, Semaphore _full) { 
+        super("Consumer", b, _mutex, _empty, _full); }
+    public void run(){
+        while (true){
+            try {
+                this.full.acquire();
+                this.mutex.acquire();
+                Object o = this.buf.remove(0);
+                System.out.println("Ho consumato " + o);
+                this.mutex.release();
+                this.empty.release();
+            } catch (InterruptedException e) {
+                System.out.println(e);
+            }
+        }
+    }
+}
+   
Index: /trunk/Shared.java
===================================================================
--- /trunk/Shared.java	(revision 2)
+++ /trunk/Shared.java	(revision 2)
@@ -0,0 +1,46 @@
+class ClasseAttiva extends Thread{
+    protected static int shared = 0;
+    public void run() {
+        while (true) {
+            if (shared >= 10) break;
+            try {
+                Thread.sleep(1000);
+            }
+            catch(InterruptedException e){
+                System.err.println(e);
+            }
+            if (shared >= 10){
+                throw new Error("Corsa critica!!!");
+            }
+            System.out.print(this.getName());
+            System.out.print(" s = ");
+            System.out.println(this.shared);
+            shared += 1;
+        }
+    }
+}
+
+
+
+public class Shared {
+    public static final void main(final String[] args) {
+        ClasseAttiva o1 = new ClasseAttiva();
+        ClasseAttiva o2 = new ClasseAttiva();
+        o1.start();
+        o2.start();
+        while (true){
+            try {
+                Thread.sleep(1000);
+            }
+            catch(InterruptedException e){
+                System.err.println(e);
+            }
+
+            System.out.println("Main thread");
+        }
+        
+    }
+}
+
+
+
Index: /trunk/Shared2.java
===================================================================
--- /trunk/Shared2.java	(revision 2)
+++ /trunk/Shared2.java	(revision 2)
@@ -0,0 +1,50 @@
+class ClasseAttiva extends Thread{
+    protected static int shared = 0;
+    protected static Object lock = new Object();
+    public void run() {
+        while (true) {
+            synchronized(lock){
+                if (shared >= 10) break;
+                try {
+                    Thread.sleep(1000);
+                }
+                catch(InterruptedException e){
+                    System.err.println(e);
+                }
+                if (shared >= 10){
+                    throw new Error("Corsa critica!!!");
+                }
+                System.out.print(this.getName());
+                System.out.print(" s = ");
+                System.out.println(this.shared);
+                shared += 1;
+            }
+            Thread.yield(); // non necessaria, ma favorisce lo scheduling di entrambi
+        }
+    }
+}
+
+
+
+public class Shared2 {
+    public static final void main(final String[] args) {
+        ClasseAttiva o1 = new ClasseAttiva();
+        ClasseAttiva o2 = new ClasseAttiva();
+        o1.start();
+        o2.start();
+        while (true){
+            try {
+                Thread.sleep(1000);
+            }
+            catch(InterruptedException e){
+                System.err.println(e);
+            }
+
+            System.out.println("Main thread");
+        }
+        
+    }
+}
+
+
+
Index: /trunk/alea.sh
===================================================================
--- /trunk/alea.sh	(revision 2)
+++ /trunk/alea.sh	(revision 2)
@@ -0,0 +1,26 @@
+SHARED_MEM=lock
+echo 0 > $SHARED_MEM
+
+processo(){ # name
+ for i in $(seq 1000); do
+     while grep 1 $SHARED_MEM >/dev/null ; do true; done
+     echo 1 > $SHARED_MEM
+     critical_session $1
+     echo 0 > $SHARED_MEM
+     io
+ done
+}
+critical_session(){ 
+  for i in 1 2 3; do
+      echo -n $1
+      io
+  done
+  echo .
+}
+
+io(){
+ dd if=/dev/zero of=/dev/null count=1000 2>/dev/null
+}
+
+processo pippo & processo pluto &
+wait
Index: /trunk/alternanza.sh
===================================================================
--- /trunk/alternanza.sh	(revision 2)
+++ /trunk/alternanza.sh	(revision 2)
@@ -0,0 +1,29 @@
+SHARED_MEM=turn
+echo pippo > $SHARED_MEM
+
+processo(){ # name
+ for i in $(seq 100); do
+     while grep -v $1 $SHARED_MEM >/dev/null ; do true; done
+     critical_session $1
+     if test "$1" = "pippo"; then  
+	 echo "pluto" > $SHARED_MEM;
+     else
+	 echo "pippo" > $SHARED_MEM;
+     fi
+     io
+ done
+}
+critical_session(){ 
+  for i in 1 2 3; do
+      echo -n $1
+      io
+  done
+  echo .
+}
+
+io(){
+ dd if=/dev/zero of=/dev/null count=1000 2>/dev/null
+}
+
+processo pippo & processo pluto &
+wait
Index: /trunk/dekker1.sh
===================================================================
--- /trunk/dekker1.sh	(revision 2)
+++ /trunk/dekker1.sh	(revision 2)
@@ -0,0 +1,32 @@
+#! /bin/bash
+
+turno=1
+
+function p1(){
+    for i in $(seq 1 10); do
+	local ddone=$(false)
+	while ! [ $ddone ]; do
+	   while [ $turno -eq 2 ]; do
+	       echo $i
+	       ddone=$(true)
+	       turno=2
+	   done
+       done
+    done
+}
+
+function p2(){
+    for i in $(seq 11 20); do
+	local ddone=$(false)
+	while ! [ $ddone ]; do
+	   while [ $turno -eq 1 ]; do
+	       echo $i
+	       ddone=$(true)
+	       turno=1
+	   done
+       done
+    done
+}
+
+p1 & p2 &
+wait %1 %2
Index: /trunk/enter.asm
===================================================================
--- /trunk/enter.asm	(revision 2)
+++ /trunk/enter.asm	(revision 2)
@@ -0,0 +1,13 @@
+section .text
+global enter_section
+
+enter_section:
+        enter 0, 0         ; 0 bytes of local stack space
+        mov   ebx,[ebp+8]     ; first parameter to function
+
+spin:   lock bts dword [ebx], 0
+        jc spin
+
+        leave                   ; mov esp,ebp / pop ebp
+        ret     
+
Index: /trunk/enter2.asm
===================================================================
--- /trunk/enter2.asm	(revision 2)
+++ /trunk/enter2.asm	(revision 2)
@@ -0,0 +1,26 @@
+section .text
+global enter_section
+extern printf	
+
+enter_section:
+        enter 0, 0         ; 0 bytes of local stack space
+        mov   ebx,[ebp+8]     ; first parameter to function
+	
+	
+spin:   mov ecx, 0
+	lock bts dword [ebx], 0
+	jc save
+print:  push busy
+	call printf
+
+	cmp ecx, 1
+        je spin
+
+save:	mov ecx, 1
+	jmp print
+	
+        leave                   ; mov esp,ebp / pop ebp
+        ret     
+
+section .rodata
+busy:	db "Busy waiting!",10,0
Index: /trunk/esegui.c
===================================================================
--- /trunk/esegui.c	(revision 2)
+++ /trunk/esegui.c	(revision 2)
@@ -0,0 +1,24 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(){
+  int x = fork();
+  if (x < 0){
+      perror("Errore nella fork:");
+      exit(1);
+  } else {
+    if (x != 0){
+      printf("Processo padre\n");
+    } else {
+      char* argv[] = {"/bin/ls", "/usr", 0};
+      execv("/bin/ls",argv );
+      perror("Errore nella exec:");
+    }
+  }
+  return 0;
+}
+
+    
+        
+  
Index: /trunk/esercizio.asm
===================================================================
--- /trunk/esercizio.asm	(revision 2)
+++ /trunk/esercizio.asm	(revision 2)
@@ -0,0 +1,27 @@
+	;;  uguale all'esame.....
+	
+segment .text
+	global main
+	extern printf,exit
+
+main:	push dword 3
+	push dword 5
+	mov ebp,esp
+	mov eax,[esp]
+	mov ebx,[ebp]
+	add eax, ebx
+	add esp, 4
+	mov ebx,[esp]
+	push ebx
+	push eax
+	push dword format
+	call printf
+	add esp, 4*3
+	push dword 0
+	call exit
+	hlt
+	
+segment .rodata
+format:	db "EAX %d, EBX %d",0x0a,0 ; 0x0a -> a capo
+
+
Index: /trunk/forca.c
===================================================================
--- /trunk/forca.c	(revision 2)
+++ /trunk/forca.c	(revision 2)
@@ -0,0 +1,22 @@
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(void){
+  int x = fork();
+  if (x < 0){
+      perror("Errore nella fork:");
+      exit(1);
+  } else {
+    if (x != 0){
+      while(1) printf("Processo padre (Figlio: %d)\n", x);
+    } else {
+      while(1) printf("Processo figlio (%d)\n", x);
+    }
+  }
+  return 0;
+}
+
+    
+        
+  
Index: /trunk/fork-pc.c
===================================================================
--- /trunk/fork-pc.c	(revision 2)
+++ /trunk/fork-pc.c	(revision 2)
@@ -0,0 +1,81 @@
+/* Copyright (C) 2008 by Mattia Monga <mattia.monga@unimi.it> */
+/* $Id$ */
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/wait.h>
+
+void b_insert(char*);
+void b_remove(char**);
+
+
+void producer(void)
+{ 
+  while (1){
+    char* o = (char*)malloc(sizeof(char));
+    printf("Ho prodotto %x\n", o);
+    b_insert(o);
+  }
+}
+
+void consumer(void)
+{ 
+  while (1){
+    char* o;
+    b_remove(&o);
+    free(o);
+    printf("Ho consumato %x\n", o);
+  }
+}
+
+int main(void){
+
+  int p, c;
+  
+  p = fork();
+  if (p == 0) producer();
+  c = fork();
+  if (c == 0) consumer();
+  
+  waitpid(-1, NULL, 0);
+
+  return 0;
+}
+
+#define N 10
+char* buffer[N];
+int count = 0;
+
+pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t full = PTHREAD_COND_INITIALIZER;
+pthread_cond_t empty = PTHREAD_COND_INITIALIZER;
+
+void b_insert(char* o)
+{
+  pthread_mutex_lock(&lock);
+
+  if (count == N) pthread_cond_wait(&full, &lock);
+  buffer[count++] = o;
+  if (count == 1) pthread_cond_signal(&empty);
+
+  pthread_mutex_unlock(&lock);
+}
+
+/* passaggio per indirizzo per evitare di fare la return fuori dai lock */
+void b_remove(char** result)
+{
+  pthread_mutex_lock(&lock);
+
+  if (count == 0) pthread_cond_wait(&empty, &lock);
+  *result = buffer[--count];
+  if (count == N-1) pthread_cond_signal(&full);
+
+  pthread_mutex_unlock(&lock);
+}
+
+
+/* Local Variables: */
+/* compile-command: "make -k " */
+/* End: */
+
+
Index: /trunk/globale.sh
===================================================================
--- /trunk/globale.sh	(revision 2)
+++ /trunk/globale.sh	(revision 2)
@@ -0,0 +1,20 @@
+
+
+globale=0
+
+function primo(){
+  globale=1;
+  echo "Primo ha finito"
+}
+
+function secondo(){
+  echo "Secondo ha iniziato"  
+  sleep 10
+  echo $globale;
+  echo "Secondo ha finito"
+}
+
+
+primo ;  secondo ;
+primo &  secondo &
+wait %1 %2
Index: /trunk/lamport.sh
===================================================================
--- /trunk/lamport.sh	(revision 2)
+++ /trunk/lamport.sh	(revision 2)
@@ -0,0 +1,67 @@
+#! /bin/bash
+
+N=2
+
+function assegna(){
+    echo $2 >> $1
+}
+
+function leggi(){
+    tail -1 $1
+}
+
+
+for j in $(seq 1 $N); do
+    echo "0">choosing$j
+    echo "0">number$j
+done
+echo "1">alternanza
+
+function max(){
+    local m=$(leggi number1)
+    for j in $(seq 1 $N); do
+	m=$(( $m > $(leggi number$j) ? $m : $(leggi number$j) ))
+    done
+    echo $m
+}
+
+
+function p(){
+    local p
+    for p in $(seq $(( $1 * 10 )) $(( $1 * 10 + 9 )) ); do
+	while true; do
+	    # doorway
+	    assegna choosing$1 "1"
+	    assegna number$1 "$(( 1 + max ))"
+	    # bakery
+	    assegna choosing$1 "0"
+	    local j
+	    for j in $(seq 1 $N); do
+		while [ $(leggi choosing$j) -ne 0  ]; do
+		    sleep 0.01
+		done
+		while [ \( $(leggi number$j) -ne 0 \) -a  \
+		    \( \( $(leggi number$j) -lt $(leggi number$1) \) -o \
+		       \( $(leggi number$j) -eq $(leggi number$1)  \) -a \
+		         \( $j -lt $1 \) \) ]; do
+		    sleep 0.01
+		done
+	    done
+            # critical section
+	    if [ $(leggi alternanza) -eq $1 ]; then
+		echo $p
+		assegna alternanza "$(( ( $(leggi alternanza) % 2 )  + 1))"
+		assegna number$1 "0"
+		break
+	    else
+		assegna number$1 "0"
+	    fi
+	    # non critical section
+	done
+    done
+}
+
+p 1 & 
+p 2 & 
+
+wait %1 %2
Index: /trunk/mioboot-nobios-simple.asm
===================================================================
--- /trunk/mioboot-nobios-simple.asm	(revision 2)
+++ /trunk/mioboot-nobios-simple.asm	(revision 2)
@@ -0,0 +1,20 @@
+;Copyright (C) 2008, 2009 by Mattia Monga <mattia.monga@unimi.it>
+bits 16                         ; 16 bit real mode
+org 0x7C00                      ; origine indirizzo 0000:7C00
+
+start:	
+ mov ax, 0xb800	; text video memory
+ mov ds, ax	; ds non accessibile direttamente 
+ mov bx, 10
+write:
+ cmp bx, 0
+ jz end
+ mov byte [ds:bx], 'm'    ; indirizzamento relativo a ds
+ mov byte [ds:bx+1], 0x0F ; attrib = white on black
+ sub bx, 2
+ jmp write
+end:
+ hlt
+
+times 510-($-$$) db 0 ; 0-padding 
+dw 0xAA55
Index: /trunk/mioboot-nobios.asm
===================================================================
--- /trunk/mioboot-nobios.asm	(revision 2)
+++ /trunk/mioboot-nobios.asm	(revision 2)
@@ -0,0 +1,28 @@
+;Copyright (C) 2007 by Mattia Monga <mattia.monga@unimi.it>
+bits 16                         ; 16 bit real mode
+org 0x7C00                      ; origine indirizzo 0000:7C00
+
+start:
+	mov ax, 0xb800   ; text video memory dest array index [ES:DI]
+        mov es, ax
+        mov di, 0        ; start of video memory
+
+        cld             ; clears direction flag (index regs incremented)
+        mov ah, 0x0F    ; attrib = white on black
+        mov si, msg
+        call message
+        hlt
+        
+message:
+        lodsb                   ; carica un byte da [DS:SI] in AL e inc SI
+        cmp al, 0
+        jz done
+        stosw                   ; memorizza una word da [ES:DI] in AL e inc SI 
+        jmp message
+done:   ret
+
+
+msg   db "Hello world from the bare machine!!!", 0      
+        
+        times 510-($-$$) db 0
+        dw 0xAA55
Index: /trunk/mioboot.asm
===================================================================
--- /trunk/mioboot.asm	(revision 2)
+++ /trunk/mioboot.asm	(revision 2)
@@ -0,0 +1,49 @@
+;Copyright (C) 2008 by Mattia Monga <mattia.monga@unimi.it>
+bits 16                         ; 16 bit real mode
+org 0x7C00                      ; origine indirizzo 0000:7C00
+        
+start:
+        cld                     ; clears direction flag (index regs incremented)
+        mov si, boot
+        call message
+working:
+        mov si, work
+        call message
+
+        call waitenter
+        jmp working
+
+message:
+        lodsb                   ; carica un byte da [DS:SI] in AL e inc SI
+        cmp al, 0
+        jz done
+        mov ah, 0x0E            ; write char to screen in text mode
+        mov bx, 0               ; BH page number BL foreground color
+        int 0x10                ; write AL to screen (BIOS)
+        jmp message
+done:   ret
+
+boot: db "Loading unuseful system...." , 10, 13, 0
+work: db "I've done my unuseful stuff!" , 10, 13, 0 
+cont: db "Hit ENTER to continue...", 10, 13, 0
+wow: db "Great! Hello world!" , 10, 13, 0
+        
+waitenter: mov si, cont
+           call message
+           mov ah, 0
+           int 0x16                ; Wait for keypress (BIOS)
+           cmp al, 'm'
+           jz egg
+           cmp al, 'b'
+           jz basic
+           cmp al, 13
+           jnz waitenter
+           ret
+egg:       mov si, wow
+           call message
+           jmp waitenter
+basic:     int 0x18		; basic (BIOS)
+           hlt
+
+        times 510-($-$$) db 0
+        dw 0xAA55
Index: /trunk/peterson.sh
===================================================================
--- /trunk/peterson.sh	(revision 2)
+++ /trunk/peterson.sh	(revision 2)
@@ -0,0 +1,38 @@
+SHARED_MEM=turno
+echo pippo > $SHARED_MEM
+
+processo(){ # name other
+ for i in $(seq 100); do
+     enter_region $1 $2
+     critical_session $1
+     leave_region $1
+     io
+ done
+}
+critical_session(){ 
+  for i in 1 2 3; do
+      echo -n $1
+      io
+  done
+  echo .
+}
+
+io(){ 
+    dd if=/dev/zero of=/dev/null count=1000 2>/dev/null 
+}
+
+enter_region() { # process other
+ echo "true" > interested_$1
+ echo $1 > $SHARED_MEM
+ while grep $1 $SHARED_MEM >/dev/null && 
+       grep true interested_$2 >/dev/null ; 
+ do 
+     true; 
+ done
+}
+leave_region() { # process
+ echo "false" > interested_$1
+}
+
+processo pippo pluto & processo pluto pippo &
+wait
Index: /trunk/processi.sh
===================================================================
--- /trunk/processi.sh	(revision 2)
+++ /trunk/processi.sh	(revision 2)
@@ -0,0 +1,16 @@
+#! /bin/bash
+
+function p1(){
+    for i in $(seq 1 10); do
+	echo $i
+    done
+}
+
+function p2(){
+    for i in $(seq 11 20); do
+	echo $i
+    done
+}
+
+p1 & p2 &
+wait %1 %2 
Index: /trunk/pthreads-pc.c
===================================================================
--- /trunk/pthreads-pc.c	(revision 2)
+++ /trunk/pthreads-pc.c	(revision 2)
@@ -0,0 +1,81 @@
+/* Copyright (C) 2008 by Mattia Monga <mattia.monga@unimi.it> */
+/* $Id$ */
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+void b_insert(char*);
+void b_remove(char**);
+
+
+void* producer(void* args)
+{ 
+  while (1){
+    char* o = (char*)malloc(sizeof(char));
+    printf("Ho prodotto %x\n", o);
+    b_insert(o);
+  }
+  return NULL;
+}
+
+void* consumer(void* args)
+{ 
+  while (1){
+    char* o;
+    b_remove(&o);
+    free(o);
+    printf("Ho consumato %x\n", o);
+  }
+  return NULL;
+}
+
+int main(void){
+  
+  pthread_t p, c;
+  
+  
+  pthread_create(&p, NULL, &producer, NULL);
+  pthread_create(&c, NULL, &consumer, NULL);
+  
+  pthread_join(p, NULL);
+  pthread_join(c, NULL);
+  return 0;
+}
+
+#define N 10
+char* buffer[N];
+int count = 0;
+
+pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t full = PTHREAD_COND_INITIALIZER;
+pthread_cond_t empty = PTHREAD_COND_INITIALIZER;
+
+void b_insert(char* o)
+{
+  pthread_mutex_lock(&lock);
+
+  if (count == N) pthread_cond_wait(&full, &lock);
+  buffer[count++] = o;
+  if (count == 1) pthread_cond_signal(&empty);
+
+  pthread_mutex_unlock(&lock);
+}
+
+/* passaggio per indirizzo per evitare di fare la return fuori dai lock */
+void b_remove(char** result)
+{
+  pthread_mutex_lock(&lock);
+
+  if (count == 0) pthread_cond_wait(&empty, &lock);
+  *result = buffer[--count];
+  if (count == N-1) pthread_cond_signal(&full);
+
+  pthread_mutex_unlock(&lock);
+}
+
+
+/* Local Variables: */
+/* compile-command: "make -k " */
+/* End: */
+
+
Index: /trunk/semafori.sh
===================================================================
--- /trunk/semafori.sh	(revision 2)
+++ /trunk/semafori.sh	(revision 2)
@@ -0,0 +1,39 @@
+N=2
+
+function assegna(){
+    echo $2 >> $1
+}
+
+function leggi(){
+    tail -1 $1
+}
+
+
+echo "1">alternanza
+
+TMP=$(mktemp semafori.sh.XXXXXX)
+trap "rm -f $TMP* 2>/dev/null" 0
+rm $TMP
+
+function p(){
+    local p
+    for p in $(seq $(( $1 * 10 )) $(( $1 * 10 + 9 )) ); do
+	while true; do
+	    lockfile $TMP
+	    if [ $(leggi alternanza) -eq $1 ]; then
+		echo $p
+		assegna alternanza "$(( ( $(leggi alternanza) % 2 )  + 1))"
+		rm -f $TMP
+		break
+	    else
+		rm -f $TMP
+	    fi
+	    sleep 0.01
+        done
+    done
+}
+
+p 1 & 
+p 2 &
+
+wait %1 %2
Index: /trunk/threads-isolated.c
===================================================================
--- /trunk/threads-isolated.c	(revision 2)
+++ /trunk/threads-isolated.c	(revision 2)
@@ -0,0 +1,71 @@
+/* Copyright (C) 2009 by Mattia Monga <mattia.monga@unimi.it> */
+/* $Id$ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sched.h>
+
+int run(void* s)
+{
+        int* shared = (int*)s; /* alias per comodita` */
+        while (shared[0] < 10) {
+                sleep(1);
+                printf("Processo figlio (%d). s = %d\n", 
+                       getpid(), shared[0]);
+                if (!(shared[0] < 10)){
+                        printf("Corsa critica!!!!\n");
+                        abort();
+                }
+                shared[0] += 1;
+        }
+        return 0;
+}
+
+
+int main(void){
+ 
+        int shared[2] = {0 , 0};
+
+        /* int clone(int (*fn)(void *), 
+         *           void *child_stack, 
+         *           int flags,
+         *           void *arg); 
+         * crea una copia del chiamante (con le caratteristiche 
+         * specificate da flags) e lo esegue partendo da fn */
+        if (clone(run, /* il nuovo
+                        * processo esegue run(shared), vedi quarto
+                        * parametro */
+                  malloc(4096)+4096,  /* lo stack del nuovo processo 
+                                       *  (cresce verso il basso!) */
+                  SIGCHLD, /* in questo caso la clone e` analoga alla fork */
+                  shared) < 0){
+                perror("Errore nella creazione");
+                exit(1);
+        } 
+
+        if (clone(run, malloc(4096)+4096,  SIGCHLD, shared) < 0){
+                perror("Errore nella creazione");
+                exit(1);
+        } 
+
+        /* Isolati: ciascuno dei figli esegue 10 volte. Per il padre
+         * shared[0] e` sempre 0 */
+
+        while(1) {
+                sleep(1);
+                printf("Processo padre. s = %d\n", shared[0]);
+        }
+        return 0;
+}
+
+    
+        
+  
+
+
+
+/* Local Variables: */
+/* compile-command: "make -k " */
+/* End: */
Index: /trunk/threads-peterson.c
===================================================================
--- /trunk/threads-peterson.c	(revision 2)
+++ /trunk/threads-peterson.c	(revision 2)
@@ -0,0 +1,97 @@
+/* Copyright (C) 2009 by Mattia Monga <mattia.monga@unimi.it> */
+/* $Id$ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sched.h>
+
+
+void enter_section(int process, int* turn, int* interested)
+{
+        int other = 1 - process;
+        interested[process] = 1;
+        *turn = process;
+        while  (*turn == process && interested[other]){ 
+                printf("Busy waiting di %d\n", process);
+        }
+}
+
+void leave_section(int process, int* interested)
+{
+        interested[process] = 0;
+}
+
+int run(const int p, void* s)
+{
+        int* shared = (int*)s; /* alias per comodita` */
+        while (enter_section(p, &shared[1], &shared[2]), 
+               shared[0] < 10) {
+                sleep(1);
+                printf("Processo figlio (%d). s = %d\n", 
+                       getpid(), shared[0]);
+                if (!(shared[0] < 10)){
+                        printf("Corsa critica!!!!\n");
+                        abort();
+                }
+                shared[0] += 1;
+                leave_section(p, &shared[2]);
+        }
+        return 0;
+}
+
+int run0(void*s){ return run(0, s); }
+int run1(void*s){ return run(1, s); }
+        
+
+int main(void){
+ 
+        int shared[4] = {0 , 0, 0, 0};
+
+        /* int clone(int (*fn)(void *), 
+         *           void *child_stack, 
+         *           int flags,
+         *           void *arg); 
+         * crea una copia del chiamante (con le caratteristiche 
+         * specificate da flags) e lo esegue partendo da fn */
+        if (clone(run0, /* il nuovo
+                         * processo esegue run(shared), vedi quarto
+                         * parametro */
+                  malloc(4096)+4096,  /* lo stack del nuovo processo 
+                                       *  (cresce verso il basso!) */
+                  CLONE_VM | SIGCHLD, /* la (virtual) memory e` condivisa */
+                  shared) < 0){
+                perror("Errore nella creazione");
+                exit(1);
+        } 
+
+        if (clone(run1, malloc(4096)+4096,  CLONE_VM | SIGCHLD, shared) < 0){
+                perror("Errore nella creazione");
+                exit(1);
+        } 
+
+        /* Memoria condivisa: i due figli nell'insieme eseguono 10 o
+         * 11 volte: e` possibile una corsa critica. Il padre
+         * condivide shared[0] con i figli */
+
+        while(shared[0] < 10) {
+                sleep(1);
+                printf("Processo padre. s = %d %d %d %d\n", 
+                       shared[0],
+                       shared[1],
+                       shared[2],
+                       shared[3]);
+        }
+        return 0;
+}
+
+    
+        
+  
+
+
+
+/* Local Variables: */
+/* compile-command: "make -k " */
+/* End: */
Index: /trunk/threads-sem.c
===================================================================
--- /trunk/threads-sem.c	(revision 2)
+++ /trunk/threads-sem.c	(revision 2)
@@ -0,0 +1,111 @@
+/* Copyright (C) 2009 by Mattia Monga <mattia.monga@unimi.it> */
+/* $Id$ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sched.h>
+#include <semaphore.h>
+
+void enter_section(sem_t *s){ 
+        if (sem_wait(s) < 0){
+                perror("Errore semaforo (down)");
+                exit(1);
+        }
+}
+
+        
+
+void leave_section(sem_t *s)
+{
+        if (sem_post(s) < 0){
+                perror("Errore semaforo (up)");
+                exit(1);
+        }
+}
+
+int run(const int p, void* s)
+{
+        int* shared = (int*)s; /* alias per comodita` */
+        while (enter_section((sem_t*)shared[1]), 
+               shared[0] < 10) {
+                sleep(1);
+                printf("Processo figlio (%d). s = %d\n", 
+                       getpid(), shared[0]);
+                if (!(shared[0] < 10)){
+                        printf("Corsa critica!!!!\n");
+                        abort();
+                }
+                shared[0] += 1;
+                leave_section((sem_t*)shared[1]);
+                sched_yield();
+        }
+        return 0;
+}
+
+int run0(void*s){ return run(0, s); }
+int run1(void*s){ return run(1, s); }
+        
+
+int main(void){
+ 
+        int shared[4] = {0 , 0, 0, 0};
+
+        sem_t *ss;
+        if (sem_init(ss, 
+                     0 /* thread local semaphore */,
+                     0 /* init value */
+                    ) < 0){
+                perror("Errore semaforo");
+                exit(1);
+        }
+        shared[1] = (int)ss;
+
+        /* int clone(int (*fn)(void *), 
+         *           void *child_stack, 
+         *           int flags,
+         *           void *arg); 
+         * crea una copia del chiamante (con le caratteristiche 
+         * specificate da flags) e lo esegue partendo da fn */
+        if (clone(run0, /* il nuovo
+                         * processo esegue run(shared), vedi quarto
+                         * parametro */
+                  malloc(4096)+4096,  /* lo stack del nuovo processo 
+                                       *  (cresce verso il basso!) */
+                  CLONE_VM | SIGCHLD, /* la (virtual) memory e` condivisa */
+                  shared) < 0){
+                perror("Errore nella creazione");
+                exit(1);
+        } 
+
+        if (clone(run1, malloc(4096)+4096,  CLONE_VM | SIGCHLD, shared) < 0){
+                perror("Errore nella creazione");
+                exit(1);
+        } 
+
+        /* Memoria condivisa: i due figli nell'insieme eseguono 10 o
+         * 11 volte: e` possibile una corsa critica. Il padre
+         * condivide shared[0] con i figli */
+
+        while(shared[0] < 10) {
+                sleep(1);
+                printf("Processo padre. s = %d %d %d %d\n", 
+                       shared[0],
+                       shared[1],
+                       shared[2],
+                       shared[3]);
+        }
+        sem_destroy(ss);
+        return 0;
+}
+
+    
+        
+  
+
+
+
+/* Local Variables: */
+/* compile-command: "make -k " */
+/* End: */
Index: /trunk/threads-shared.c
===================================================================
--- /trunk/threads-shared.c	(revision 2)
+++ /trunk/threads-shared.c	(revision 2)
@@ -0,0 +1,72 @@
+/* Copyright (C) 2009 by Mattia Monga <mattia.monga@unimi.it> */
+/* $Id$ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sched.h>
+
+int run(void* s)
+{
+        int* shared = (int*)s; /* alias per comodita` */
+        while (shared[0] < 10) {
+                sleep(1);
+                printf("Processo figlio (%d). s = %d\n", 
+                       getpid(), shared[0]);
+                if (!(shared[0] < 10)){
+                        printf("Corsa critica!!!!\n");
+                        abort();
+                }
+                shared[0] += 1;
+        }
+        return 0;
+}
+
+
+int main(void){
+ 
+        int shared[2] = {0 , 0};
+
+        /* int clone(int (*fn)(void *), 
+         *           void *child_stack, 
+         *           int flags,
+         *           void *arg); 
+         * crea una copia del chiamante (con le caratteristiche 
+         * specificate da flags) e lo esegue partendo da fn */
+        if (clone(run, /* il nuovo
+                        * processo esegue run(shared), vedi quarto
+                        * parametro */
+                  malloc(4096)+4096,  /* lo stack del nuovo processo 
+                                       *  (cresce verso il basso!) */
+                  CLONE_VM | SIGCHLD, /* la (virtual) memory e` condivisa */
+                  shared) < 0){
+                perror("Errore nella creazione");
+                exit(1);
+        } 
+
+        if (clone(run, malloc(4096)+4096,  CLONE_VM | SIGCHLD, shared) < 0){
+                perror("Errore nella creazione");
+                exit(1);
+        } 
+
+        /* Memoria condivisa: i due figli nell'insieme eseguono 10 o
+         * 11 volte: e` possibile una corsa critica. Il padre
+         * condivide shared[0] con i figli */
+
+        while(1) {
+                sleep(1);
+                printf("Processo padre. s = %d\n", shared[0]);
+        }
+        return 0;
+}
+
+    
+        
+  
+
+
+
+/* Local Variables: */
+/* compile-command: "make -k " */
+/* End: */
Index: /trunk/threads-tsl.c
===================================================================
--- /trunk/threads-tsl.c	(revision 2)
+++ /trunk/threads-tsl.c	(revision 2)
@@ -0,0 +1,89 @@
+/* Copyright (C) 2009 by Mattia Monga <mattia.monga@unimi.it> */
+/* $Id$ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sched.h>
+
+
+void enter_section(int *s); /* in enter.asm */
+
+void leave_section(int *s){
+        *s = 0;
+}
+
+int run(const int p, void* s)
+{
+        int* shared = (int*)s; /* alias per comodita` */
+        while (enter_section(&shared[1]), 
+               shared[0] < 10) {
+                sleep(100);
+                printf("Processo figlio (%d). s = %d\n", 
+                       getpid(), shared[0]);
+                if (!(shared[0] < 10)){
+                        printf("Corsa critica!!!!\n");
+                        abort();
+                }
+                shared[0] += 1;
+                leave_section(&shared[1]);
+                sched_yield();
+        }
+        return 0;
+}
+
+int run0(void*s){ return run(0, s); }
+int run1(void*s){ return run(1, s); }
+        
+
+int main(void){
+ 
+        int shared[4] = {0 , 0, 0, 0};
+
+        /* int clone(int (*fn)(void *), 
+         *           void *child_stack, 
+         *           int flags,
+         *           void *arg); 
+         * crea una copia del chiamante (con le caratteristiche 
+         * specificate da flags) e lo esegue partendo da fn */
+        if (clone(run0, /* il nuovo
+                         * processo esegue run(shared), vedi quarto
+                         * parametro */
+                  malloc(4096)+4096,  /* lo stack del nuovo processo 
+                                       *  (cresce verso il basso!) */
+                  CLONE_VM | SIGCHLD, /* la (virtual) memory e` condivisa */
+                  shared) < 0){
+                perror("Errore nella creazione");
+                exit(1);
+        } 
+
+        if (clone(run1, malloc(4096)+4096,  CLONE_VM | SIGCHLD, shared) < 0){
+                perror("Errore nella creazione");
+                exit(1);
+        } 
+
+        /* Memoria condivisa: i due figli nell'insieme eseguono 10 o
+         * 11 volte: e` possibile una corsa critica. Il padre
+         * condivide shared[0] con i figli */
+
+        while(shared[0] < 10) {
+                sleep(1);
+                printf("Processo padre. s = %d %d %d %d\n", 
+                       shared[0],
+                       shared[1],
+                       shared[2],
+                       shared[3]);
+        }
+        return 0;
+}
+
+    
+        
+  
+
+
+
+/* Local Variables: */
+/* compile-command: "make -k " */
+/* End: */
Index: /trunk/threads.c
===================================================================
--- /trunk/threads.c	(revision 2)
+++ /trunk/threads.c	(revision 2)
@@ -0,0 +1,56 @@
+/* Copyright (C) 2009 by Mattia Monga <mattia.monga@unimi.it> */
+/* $Id$ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <sched.h>
+#include <assert.h>
+
+int run(void* s)
+{
+        int* shared = (int*)s; /* alias per comodita` */
+        while (shared[0] < 10) {
+                sleep(1);
+                printf("Processo figlio (%d). s = %d\n", 
+                       getpid(), shared[0]);
+                if (!(shared[0] < 10)){
+                        printf("Corsa critica!!!!\n");
+                        abort();
+                }
+                shared[0] += 1;
+        }
+        return 0;
+}
+
+
+int main(void){
+ 
+        int shared[2] = {0 , 0};
+        if (clone(run, malloc(4096)+4096,  SIGCHLD, shared) < 0){
+                perror("Errore nella creazione");
+                exit(1);
+        } 
+
+        if (clone(run, malloc(4096)+4096,  SIGCHLD, shared) < 0){
+                perror("Errore nella creazione");
+                exit(1);
+        } 
+
+        while(1) {
+                sleep(1);
+                printf("Processo padre. s = %d\n", shared[0]);
+        }
+        return 0;
+}
+
+    
+        
+  
+
+
+
+/* Local Variables: */
+/* compile-command: "make -k " */
+/* End: */
Index: /trunk/trap.sh
===================================================================
--- /trunk/trap.sh	(revision 2)
+++ /trunk/trap.sh	(revision 2)
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+trap "echo Ho ricevuto il segnale USR1" 10
+trap "echo Ho ricevuto il segnale USR2" 12
+trap "echo Ho ricevuto il segnale INT" 2
+
+while true ; do
+    sleep 1
+    echo "ciao: sono $(id)"
+done
+
+
Index: /trunk/tsl.asm
===================================================================
--- /trunk/tsl.asm	(revision 2)
+++ /trunk/tsl.asm	(revision 2)
@@ -0,0 +1,32 @@
+	
+segment .text
+	global main
+extern printf
+
+main:	mov eax, 0
+	call stampa
+	lock bts dword [x], 0
+	jc salta  		; gia` settato
+	call stampa
+salta:	lock bts dword [x], 0
+	jnc _end
+	call stampa
+	jmp _end
+
+stampa:	push dword [x]	
+	push dword fmt	
+	call printf
+	add esp, 8
+	ret
+	
+
+_end:	mov eax, 1 		; call syscall exit
+	xor ebx, ebx		; exit status 0
+	int 0x80
+	hlt
+
+segment .data	
+x:	dd 0
+
+segment .rodata
+fmt:	db "Il valore di x e` %x",0x0a,0 ; 0x0a -> a capo
Index: /trunk/unios.asm
===================================================================
--- /trunk/unios.asm	(revision 2)
+++ /trunk/unios.asm	(revision 2)
@@ -0,0 +1,113 @@
+; Redistribution and use in source and binary forms, with or without modification, are
+; permitted provided that the following conditions are met:
+;
+; Redistributions of source code must retain the above copyright notice, this list of
+; conditions and the following disclaimer.
+;
+; Redistributions in binary form must reproduce the above copyright notice, this list of
+; conditions and the following disclaimer in the documentation and/or other materials
+; provided with the distribution.
+;
+; The name of the author may not be used to endorse or promote products derived from this
+; software without specific prior written permission.
+;
+; THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+; INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+; INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+;
+; Version: 1.1.1 Beta
+
+bits 16
+org 0h
+
+	mov ax, 0x7C0
+	mov ds, ax
+
+	call booting
+	xor dx,dx
+	call working
+	call idleloop
+
+nl:
+	mov si, newline
+	call message
+	ret
+	
+booting:
+	mov si, boot
+	call message
+	call nl
+	ret
+	
+working:
+	call nl
+	call nl
+	mov si, device
+	call message
+	call waitenter;
+	inc dx
+	cmp dx, 3
+	je keyboard
+	jmp working
+
+keyboard:
+	call nl
+	call nl
+	mov si, kbd
+	call message
+	call nl
+	mov si, cont
+	call message
+	ret
+
+waitenter:
+	call nl
+	mov si, cont
+	call message
+	xor ax,ax ; Sets AH=0 and AL=0
+	int 16h ; Wait for keypress
+	cmp al, 'T'
+	jz taz
+	cmp al, 't'
+	jz taz
+	cmp al, 13
+	jnz waitenter
+	ret
+
+taz:
+	call nl
+	call nl
+	mov si, tazq
+	call message
+	jmp waitenter
+
+idleloop:
+	hlt
+	jmp idleloop
+
+message:
+	lodsb
+	or al, al
+	jz done
+	mov ah, 0Eh
+	mov bx, 7
+	int 10h
+	jmp message
+	
+done:
+	ret
+ 
+boot: db 'Loading UniOS 1.1 Beta...' , 0
+newline: db 10, 13, 0
+device: db 'Device not responding to SCSI command.' , 0 
+cont: db 'Hit ENTER to continue...', 0
+kbd: db 'Keyboard not responding to SCSI command.' , 0
+tazq: db 'Yes, TazQ is an Internet crack monkey on wheels.' , 0
+
+	times 510-($-$$) db 0
+	dw 0xAA55
