Index: tags/minix3.1.2a-orig/minix/include/minix/com.h
===================================================================
--- tags/minix3.1.2a-orig/minix/include/minix/com.h	(revision 12)
+++ tags/minix3.1.2a-orig/minix/include/minix/com.h	(revision 13)
@@ -42,5 +42,6 @@
 #define TTY_PROC_NR	  5	/* terminal (TTY) driver */
 #define DS_PROC_NR	  6    	/* data store server */
-#define INIT_PROC_NR	  7    	/* init -- goes multiuser */
+#define SS_PROC_NR	  7    	/* semaphore server */
+#define INIT_PROC_NR	  8    	/* init -- goes multiuser */
 
 /* Number of processes contained in the system image. */
@@ -487,4 +488,13 @@
 
 /*===========================================================================*
+ *                Messages for the Semaphore Server			     *
+ *===========================================================================*/
+#define SS_RQ_BASE 0xA00  /* qualsiasi numero inutilizzato e` ok */
+#define SS_DOWN	(SS_RQ_BASE + 0)	/* semaphore down */
+#define SS_UP	(SS_RQ_BASE + 1)	/* semaphore up */
+
+
+
+/*===========================================================================*
  *                Miscellaneous messages used by TTY			     *
  *===========================================================================*/
Index: tags/minix3.1.2a-orig/minix/kernel/table.c
===================================================================
--- tags/minix3.1.2a-orig/minix/kernel/table.c	(revision 12)
+++ tags/minix3.1.2a-orig/minix/kernel/table.c	(revision 13)
@@ -69,5 +69,5 @@
 #define SRV_M	(~0)
 #define SYS_M	(~0)
-#define USR_M (s(PM_PROC_NR) | s(FS_PROC_NR) | s(RS_PROC_NR) | s(SYSTEM))
+#define USR_M (s(PM_PROC_NR) | s(FS_PROC_NR) | s(RS_PROC_NR) | s(SS_PROC_NR) | s(SYSTEM))
 #define DRV_M (USR_M | s(SYSTEM) | s(CLOCK) | s(DS_PROC_NR) | s(LOG_PROC_NR) | s(TTY_PROC_NR))
 
@@ -80,4 +80,5 @@
 #define RS_C	~0	
 #define DS_C	~0	
+#define SS_C	~0	
 #define PM_C	~(c(SYS_DEVIO) | c(SYS_SDEVIO) | c(SYS_VDEVIO) | c(SYS_IRQCTL) | c(SYS_INT86))
 #define FS_C	(c(SYS_KILL) | c(SYS_VIRCOPY) | c(SYS_VIRVCOPY) | c(SYS_UMAP) | c(SYS_GETINFO) | c(SYS_EXIT) | c(SYS_TIMES) | c(SYS_SETALARM))
@@ -97,4 +98,12 @@
  * Note: the quantum size must be positive in all cases! 
  */
+/* Attenzione! Minix bug! L'ordine nella bootimage deve coincidere con quello 
+ * della tabella (vedi commento precedente). Ne deriva che tre file devono
+ * essere coerenti:
+ * 1. include/minix/com.h (l'ordine delle macro *_NR)
+ * 2. kernel/table.c      (l'ordine in boot_image)
+ * 3. tools/Makefile      (l'ordine di concatenamento nella boot image) 
+ * altrimenti la ipc_to mask non corrisponde
+ */
 PUBLIC struct boot_image image[] = {
 /* process nr,   pc, flags, qs,  queue, stack, traps, ipcto, call,  name */ 
@@ -106,6 +115,7 @@
  { FS_PROC_NR,    0, SRV_F, 32,      4, 0,     SRV_T, SRV_M,  FS_C, "fs"    },
  { RS_PROC_NR,    0, SRV_F,  4,      3, 0,     SRV_T, SYS_M,  RS_C, "rs"    },
+ { TTY_PROC_NR,   0, SRV_F,  4,      1, 0,     SRV_T, SYS_M, TTY_C, "tty"   },
  { DS_PROC_NR,    0, SRV_F,  4,      3, 0,     SRV_T, SYS_M,  DS_C, "ds"    },
- { TTY_PROC_NR,   0, SRV_F,  4,      1, 0,     SRV_T, SYS_M, TTY_C, "tty"   },
+ { SS_PROC_NR,    0, SRV_F,  4,      3, 0,     SRV_T, SYS_M,  SS_C, "ss"    },
  { MEM_PROC_NR,   0, SRV_F,  4,      2, 0,     SRV_T, SYS_M, MEM_C, "mem"   },
  { LOG_PROC_NR,   0, SRV_F,  4,      2, 0,     SRV_T, SYS_M, DRV_C, "log"   },
Index: tags/minix3.1.2a-orig/minix/servers/Makefile
===================================================================
--- tags/minix3.1.2a-orig/minix/servers/Makefile	(revision 12)
+++ tags/minix3.1.2a-orig/minix/servers/Makefile	(revision 13)
@@ -20,4 +20,5 @@
 	cd ./rs && $(MAKE) $@
 	cd ./ds && $(MAKE) $@
+	cd ./ss && $(MAKE) $@
 	cd ./is && $(MAKE) $@
 	cd ./init && $(MAKE) $@
@@ -29,4 +30,5 @@
 	cd ./rs && $(MAKE) EXTRA_OPTS=$(EXTRA_OPTS) build
 	cd ./ds && $(MAKE) EXTRA_OPTS=$(EXTRA_OPTS) build
+	cd ./ss && $(MAKE) EXTRA_OPTS=$(EXTRA_OPTS) build
 	cd ./init && $(MAKE) EXTRA_OPTS=$(EXTRA_OPTS) build
 
Index: tags/minix3.1.2a-orig/minix/servers/ss/Makefile
===================================================================
--- tags/minix3.1.2a-orig/minix/servers/ss/Makefile	(revision 13)
+++ tags/minix3.1.2a-orig/minix/servers/ss/Makefile	(revision 13)
@@ -0,0 +1,31 @@
+# Semaphore Server
+SERVER = ss
+
+# programs, flags, etc.
+CC =	exec cc
+CFLAGS = -I/usr/include
+LDFLAGS = -i
+LIBS = -lsys -lsysutil 
+
+OBJ = main.o semaforo.o 
+
+# build local binary
+all build:	$(SERVER)
+$(SERVER):	$(OBJ)
+	$(CC) -o $@ $(LDFLAGS) $(OBJ) $(LIBS)
+	install -S 16k $@
+
+# install with other servers
+install: $(SERVER)
+	install -o root -c $? /sbin/$(SERVER)
+
+# clean up local files
+clean:
+	rm -f $(SERVER) *.o *.bak 
+
+depend: 
+	/usr/bin/mkdep "$(CC) -E $(CPPFLAGS)" *.c > .depend
+
+# Include generated dependencies.
+include .depend
+
Index: tags/minix3.1.2a-orig/minix/servers/ss/main.c
===================================================================
--- tags/minix3.1.2a-orig/minix/servers/ss/main.c	(revision 13)
+++ tags/minix3.1.2a-orig/minix/servers/ss/main.c	(revision 13)
@@ -0,0 +1,81 @@
+#include "semaforo.h"
+
+/* Declare some local functions. */
+FORWARD _PROTOTYPE(void init_server, (void)		);
+FORWARD _PROTOTYPE(void get_work, (message *m_ptr)			);
+FORWARD _PROTOTYPE(int do_up, (message *m_ptr)			);
+FORWARD _PROTOTYPE(int do_down, (message *m_ptr)			);
+
+/* semaforo globale al server */
+semaforo sema;
+
+/*===========================================================================*
+ *				main                                         *
+ *===========================================================================*/
+PUBLIC int main(void){
+        message m;
+        int result;
+        /* Initialize the semaphore server. */
+        init_server();
+        /* Main loop of server. Get work and process it. */
+        while(TRUE) {
+                /* Block and wait until a request message arrives. */
+                get_work(&m);
+                /* Caller is now blocked. Dispatch based on message type. */
+                switch(m.m_type) {
+                case SS_UP:      result = do_up(&m);   break;
+                case SS_DOWN:    result = do_down(&m); break;
+                default:          result = EINVAL;
+                }
+                /* Send the reply, unless the caller must be blocked. */
+                if (result != EDONTREPLY) {
+                        m.m_type = result;
+                        send(m.m_source, &m);
+                }
+        }
+        return(OK);
+}
+
+/*===========================================================================*
+ *				 init_server                                 *
+ *===========================================================================*/
+PRIVATE void init_server(void){
+        sema.s = 0;
+        sema.quanti = 0;
+}
+
+
+/*===========================================================================*
+ *				get_work                                     *
+ *===========================================================================*/
+PRIVATE void get_work(message *m_ptr){
+    int status = 0;
+    status = receive(ANY, m_ptr);   /* this blocks until message arrives */
+    if (OK != status)
+        panic("SS","failed to receive message!", status);
+}
+
+PRIVATE int do_down(message *m_ptr){
+        if (sema.s > 0){
+                sema.s -= 1;
+                return(OK);
+        }
+        if (accoda(&sema, m_ptr->m_source) < 0) return(EFAULT);
+        printf("Accodato %d (semaforo %d [%d])\n", 
+               m_ptr->m_source, sema.s, sema.quanti);
+        return(EDONTREPLY); /* non risponde: il chiamante rimane bloccato */
+}
+
+PRIVATE int do_up(message *m_ptr){
+        sema.s += 1;
+        if (sema.quanti > 0){
+                int waiting = scoda(&sema);
+                if (waiting < 0) return(EFAULT);
+                sema.s -= 1;
+                printf("Scodato %d (semaforo %d [%d])\n", 
+                       waiting, sema.s, sema.quanti);
+                m_ptr->m_type = OK;
+                send(waiting, m_ptr);
+        }
+        return(OK);
+}
Index: tags/minix3.1.2a-orig/minix/servers/ss/semaforo.c
===================================================================
--- tags/minix3.1.2a-orig/minix/servers/ss/semaforo.c	(revision 13)
+++ tags/minix3.1.2a-orig/minix/servers/ss/semaforo.c	(revision 13)
@@ -0,0 +1,19 @@
+#include "semaforo.h"
+
+PUBLIC int accoda(semaforo *ss, int who){
+        if (ss->quanti < MAX_CODA){
+                ss->coda[ss->quanti++] = who;
+                return ss->quanti;
+        }
+        return -1;
+}
+
+PUBLIC int scoda(semaforo *ss){
+        if (ss->quanti > 0){
+                return ss->coda[--ss->quanti];
+        }
+        return -1;
+}
+
+
+
Index: tags/minix3.1.2a-orig/minix/servers/ss/semaforo.h
===================================================================
--- tags/minix3.1.2a-orig/minix/servers/ss/semaforo.h	(revision 13)
+++ tags/minix3.1.2a-orig/minix/servers/ss/semaforo.h	(revision 13)
@@ -0,0 +1,24 @@
+#ifndef SEMA_H
+#define SEMA_H
+
+#define _SYSTEM            1    /* get OK and negative error codes */
+#define _MINIX             1	/* tell headers to include MINIX stuff */
+
+#include <lib.h>
+#include <minix/syslib.h>
+#include <minix/sysutil.h>
+
+#define MAX_CODA 100
+
+typedef struct{
+        int s;
+        int coda[MAX_CODA];
+        int quanti;
+} semaforo;
+
+
+_PROTOTYPE(int accoda, (semaforo *ss, int who)			);
+_PROTOTYPE(int scoda,  (semaforo *ss)			);
+
+
+#endif
Index: tags/minix3.1.2a-orig/minix/test/testsema.c
===================================================================
--- tags/minix3.1.2a-orig/minix/test/testsema.c	(revision 13)
+++ tags/minix3.1.2a-orig/minix/test/testsema.c	(revision 13)
@@ -0,0 +1,40 @@
+#include <lib.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int up(void)
+{
+  message m;
+ 
+  if (_syscall(SS_PROC_NR, SS_UP, &m) < 0) return(-1);
+  return 0;
+}
+ 
+int down(void)
+{
+  message m;
+ 
+  if (_syscall(SS_PROC_NR, SS_DOWN, &m) < 0) return(-1);
+  return 0;
+}
+
+int main(void)
+{
+        /* grazie al semaforo, il padre stampa sempre prima del figlio */
+	int r=0;
+        if (fork() > 0){
+                /* padre */
+                sleep(10);
+                printf("Sono il padre\n");
+		r = up();
+		if (r<0) printf("Errore p:%d\n", r);
+                return 0;
+        } else {
+                /* figlio */
+		r = down();
+		if (r<0) printf("Errore f:%d\n", r);
+                printf("Sono il figlio\n");
+                return 0;
+        }
+}
Index: tags/minix3.1.2a-orig/minix/tools/Makefile
===================================================================
--- tags/minix3.1.2a-orig/minix/tools/Makefile	(revision 12)
+++ tags/minix3.1.2a-orig/minix/tools/Makefile	(revision 13)
@@ -11,6 +11,7 @@
 	../servers/fs/fs \
 	../servers/rs/rs \
+	../drivers/tty/tty \
 	../servers/ds/ds \
-	../drivers/tty/tty \
+	../servers/ss/ss \
 	../drivers/memory/memory \
 	../drivers/log/log \
