diff -urN kernelInit/include/linux/mailbox.h kernelSrc/include/linux/mailbox.h
--- kernelInit/include/linux/mailbox.h	1969-12-31 19:00:00.000000000 -0500
+++ kernelSrc/include/linux/mailbox.h	2008-10-02 16:32:01.000000000 -0400
@@ -0,0 +1,67 @@
+/* Edited by Chris Williams */
+
+
+/*
+Adapted from CS-502 Project #3, Fall 2006
+	originally submitted by Cliff Lindsay
+ Modified for CS-3013, A-term 2008
+
+*/
+
+#ifndef __MAILBOX__
+#define __MAILBOX__
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/semaphore.h>
+
+#define NO_BLOCK 0
+#define BLOCK   1
+#define MAX_MSG_SIZE 128
+
+
+struct cs3013_mailbox {
+
+	spinlock_t mr_lock;
+
+	int num_messages;
+	bool stop;
+
+	/* Sender */
+	int wait_count_s;
+	struct semaphore sem_s;
+
+	/* Reciever */
+	int wait_count_r;
+	struct semaphore sem_r;
+	
+	struct cs3013_message* head;
+	struct cs3013_message* tail;
+};
+
+struct cs3013_message {
+
+	pid_t sender_id;
+	
+	int len;
+	struct cs3013_message* next;
+
+	void* msg;
+};
+	
+
+void message_cache_init( void );
+
+/*
+ * error codes pertaining to mailboxes
+ * 
+ * */
+#define MAILBOX_FULL	1001
+#define MAILBOX_EMPTY	1002
+#define MAILBOX_STOPPED	1003
+#define MAILBOX_INVALID	1004
+#define MSG_TOO_LONG	1005
+#define MSG_ARG_ERROR	1006
+#define MAILBOX_ERROR	1007
+
+#endif
diff -urN kernelInit/include/linux/mailbox.h~ kernelSrc/include/linux/mailbox.h~
--- kernelInit/include/linux/mailbox.h~	1969-12-31 19:00:00.000000000 -0500
+++ kernelSrc/include/linux/mailbox.h~	2008-10-02 16:06:49.000000000 -0400
@@ -0,0 +1,69 @@
+/* Edited by Chris Williams */
+
+
+/*
+Adapted from CS-502 Project #3, Fall 2006
+	originally submitted by Cliff Lindsay
+ Modified for CS-3013, A-term 2008
+
+*/
+
+#ifndef __MAILBOX__
+#define __MAILBOX__
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <asm/semaphore.h>
+
+#define NO_BLOCK 0
+#define BLOCK   1
+#define MAX_MSG_SIZE 128
+
+
+struct cs3013_mailbox {
+
+	spinlock_t mr_lock;
+
+	int num_messages;
+	bool stop;
+
+	/* Sender */
+	int wait_count_s;
+	struct semaphore sem_s;
+
+	/* Reciever */
+	int wait_count_r;
+	struct semaphore sem_r;
+	
+	struct cs3013_message* head;
+	struct cs3013_message* tail;
+
+	int ID;
+};
+
+struct cs3013_message {
+
+	pid_t sender_id;
+	
+	int len;
+	struct cs3013_message* next;
+
+	void* msg;
+};
+	
+
+void message_cache_init( void );
+
+/*
+ * error codes pertaining to mailboxes
+ * 
+ * */
+#define MAILBOX_FULL	1001
+#define MAILBOX_EMPTY	1002
+#define MAILBOX_STOPPED	1003
+#define MAILBOX_INVALID	1004
+#define MSG_TOO_LONG	1005
+#define MSG_ARG_ERROR	1006
+#define MAILBOX_ERROR	1007
+
+#endif
diff -urN kernelInit/kernel/exit.c kernelSrc/kernel/exit.c
--- kernelInit/kernel/exit.c	2008-06-09 11:08:36.000000000 -0400
+++ kernelSrc/kernel/exit.c	2008-10-03 15:17:44.000000000 -0400
@@ -48,6 +48,8 @@
 #include <linux/blkdev.h>
 #include <linux/task_io_accounting_ops.h>
 
+#include <linux/mailbox.h>
+
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 #include <asm/pgtable.h>
@@ -934,6 +936,14 @@
 		hrtimer_cancel(&tsk->signal->real_timer);
 		exit_itimers(tsk->signal);
 	}
+
+	
+	if( group_dead && tsk->mailbox != NULL ) {
+		kfree(tsk->mailbox);
+		tsk->mailbox = NULL;
+	}
+
 	acct_collect(code, group_dead);
 	if (unlikely(tsk->robust_list))
 		exit_robust_list(tsk);
diff -urN kernelInit/kernel/fork.c kernelSrc/kernel/fork.c
--- kernelInit/kernel/fork.c	2007-07-08 19:32:17.000000000 -0400
+++ kernelSrc/kernel/fork.c	2008-10-03 16:19:23.000000000 -0400
@@ -50,6 +50,8 @@
 #include <linux/taskstats_kern.h>
 #include <linux/random.h>
 
+#include <linux/mailbox.h>
+
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
 #include <asm/uaccess.h>
@@ -57,6 +59,8 @@
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
 
+#include <asm/semaphore.h>
+
 /*
  * Protected counters by write_lock_irq(&tasklist_lock)
  */
@@ -137,6 +141,9 @@
 	task_struct_cachep =
 		kmem_cache_create("task_struct", sizeof(struct task_struct),
 			ARCH_MIN_TASKALIGN, SLAB_PANIC, NULL, NULL);
+
+	/* create a slab on which messages can be allocated */
+        message_cache_init();
 #endif
 
 	/*
@@ -1414,6 +1421,35 @@
 				ptrace_notify ((PTRACE_EVENT_VFORK_DONE << 8) | SIGTRAP);
 			}
 		}
+
+		if( p->mm == 0 ) {  // kernel thread
+			p->mailbox = NULL;
+		} else {
+
+			if( !(clone_flags & CLONE_THREAD) ) {// a process
+
+				p->mailbox = kmalloc( sizeof(struct cs3013_mailbox), GFP_ATOMIC ); 
+
+				p->mailbox->mr_lock = SPIN_LOCK_UNLOCKED;
+
+				p->mailbox->num_messages = 0;
+				p->mailbox->stop = 0;
+
+				p->mailbox->wait_count_s = p->mailbox->wait_count_r =  0;
+
+				sema_init( &(p->mailbox->sem_s), 0 );
+				sema_init( &(p->mailbox->sem_r), 0 );
+
+				p->mailbox->head = p->mailbox->tail = NULL;
+
+
+			} else {// thread of a process
+				p->mailbox = p->parent->mailbox;
+			}
+		}
+
+  
+
 	} else {
 		free_pid(pid);
 		nr = PTR_ERR(p);
diff -urN kernelInit/kernel/mailbox.c kernelSrc/kernel/mailbox.c
--- kernelInit/kernel/mailbox.c	1969-12-31 19:00:00.000000000 -0500
+++ kernelSrc/kernel/mailbox.c	2008-10-03 15:51:21.000000000 -0400
@@ -0,0 +1,353 @@
+/* Chris Williams */
+
+#include <asm/current.h>
+#include <linux/mailbox.h>
+#include <linux/sched.h>
+
+#include <asm/semaphore.h>
+
+//for copy_to_user and copy_from_user
+#include <asm-i386/uaccess.h>
+
+//for exit
+#include <asm/unistd.h>
+
+#define MAX_MESSAGES 30
+
+static struct kmem_cache* message_cachep;
+
+void message_cache_init() {
+	message_cachep =
+		kmem_cache_create("cs3013_message", sizeof( struct cs3013_message ) + MAX_MSG_SIZE, 0, 0 ,NULL, NULL );
+}
+
+
+int flush_messages( void );
+
+asmlinkage int sys_mailbox_send(pid_t dest, void *msg, int len, bool block) {
+
+	struct task_struct* p_struct;
+	struct cs3013_mailbox* p_mailbox;
+
+	struct cs3013_message* new;
+
+	p_struct = find_task_by_pid( dest );
+	
+
+	/* ERROR CHECKING */
+
+		if( p_struct == 0 ) {
+			printk("Bogus Destination pid_t!\n");
+			return MAILBOX_INVALID;
+		}
+	
+		p_mailbox = p_struct->mailbox;
+	
+		if( p_mailbox == 0 ) {
+			printk("Mailbox is NULL! (mailbox_send)\n");
+			return MAILBOX_ERROR;
+		}
+
+		if( msg == 0 ) {
+			printk("Bogus Pointer Supplied By User in SendMsg!\n");
+			return MSG_ARG_ERROR;
+		}
+
+		if( len > MAX_MSG_SIZE ) {
+			printk("Message is too long!\n");
+			return MSG_TOO_LONG;
+		}
+
+		if( message_cachep == 0 ) {
+			printk("Mailbox cache wasn't initialized!\n");
+			return MAILBOX_ERROR;
+		}
+
+
+	/* Create the new message */
+
+	new = (struct cs3013_message*) kmem_cache_alloc( message_cachep, GFP_KERNEL);
+
+	if( new == 0 ) {
+		printk("kmem_cache_alloc failed!\n");
+		return MAILBOX_ERROR;
+	}
+
+		new->sender_id = current->pid;
+		new->len = len;
+		new->next = NULL;
+		new->msg = &(new->msg) + 4;
+
+		if( copy_from_user( new->msg, msg, len ) ) {
+			printk("copy from user failed\n");
+			kmem_cache_free(message_cachep, new );
+			return MSG_ARG_ERROR;
+		}
+
+
+spin_lock( &(p_mailbox->mr_lock) );
+
+	/* Has a stop been issued? */
+	if( p_mailbox == NULL || p_mailbox->stop == 1 ) {
+		spin_unlock( &(p_mailbox->mr_lock) );
+		kmem_cache_free( message_cachep, new );
+		return MAILBOX_STOPPED;
+	}
+
+	/* Check if list is full */
+
+	if( p_mailbox->num_messages == MAX_MESSAGES ) {
+
+		if( block == NO_BLOCK ) {
+			spin_unlock( &(p_mailbox->mr_lock) );
+			kmem_cache_free( message_cachep, new );
+			return MAILBOX_FULL;
+		} else {
+
+			do {
+				p_mailbox->wait_count_s += 1;
+				spin_unlock( &(p_mailbox->mr_lock) );
+				down_interruptible( &(p_mailbox->sem_s) );
+				spin_lock( &(p_mailbox->mr_lock) );
+		
+				/*  Has a stop been issued? */
+				if( p_mailbox == NULL || p_mailbox->stop == 1 ) {
+
+					p_mailbox->wait_count_s -= 1;
+			
+					/* Wake others up */	
+					if ( p_mailbox->wait_count_s > 0)
+						up( &(p_mailbox->sem_s) );
+			
+					spin_unlock( &(p_mailbox->mr_lock) );
+			
+					kmem_cache_free( message_cachep, new ); 
+					return MAILBOX_STOPPED;
+				}
+
+			} while( p_mailbox->num_messages == MAX_MESSAGES );
+		}
+	}
+
+	/* Assertion */
+	if( p_mailbox->num_messages == MAX_MESSAGES ) {
+		printk("You are adding an item to a full list you fool.\n");
+		spin_unlock( &(p_mailbox->mr_lock) );
+		return -100000000;
+	}
+
+	p_mailbox->num_messages += 1; // increment message count, we are about to add something to the mailbox
+	
+	/* Link new message to end of mailbox linked list */
+		
+	if( p_mailbox->tail == 0 ) p_mailbox->head = new;
+	else p_mailbox->tail->next = new;
+
+	p_mailbox->tail = new;
+
+
+	/* Signal if any receiving threads are blocked */
+	
+	if ( p_mailbox->wait_count_r > 0) {
+		up( &(p_mailbox->sem_r) );
+		p_mailbox->wait_count_r -= 1;
+	}
+
+spin_unlock( &(p_mailbox->mr_lock) );
+
+	return 0;
+}
+
+
+asmlinkage int sys_mailbox_rcv(pid_t *sender, void *msg, int *len, bool block) {
+
+	struct cs3013_mailbox* p_mailbox;
+	struct cs3013_message* old;
+
+	p_mailbox = current->mailbox;
+	
+	/* Error checking */
+	if( p_mailbox == NULL ) {
+		printk("Mailbox is NULL! (mailbox_receive)\n");
+		return MAILBOX_ERROR;
+	}
+
+spin_lock( &(p_mailbox->mr_lock) );
+
+	/* Has a stop been issued? */
+	if( p_mailbox == NULL || p_mailbox->stop == 1 ) {
+		spin_unlock( &(p_mailbox->mr_lock) );
+		return MAILBOX_STOPPED;
+	}
+	
+	/* Check if list is empty */
+	
+	if( p_mailbox->num_messages == 0 ) {
+
+		if( block == NO_BLOCK ) {
+			spin_unlock( &(p_mailbox->mr_lock) );
+			return MAILBOX_EMPTY;
+		} else {
+			
+			do {	
+				p_mailbox->wait_count_r += 1;
+				spin_unlock( &(p_mailbox->mr_lock) );
+				down_interruptible( &(p_mailbox->sem_r) );
+				spin_lock( &(p_mailbox->mr_lock) );
+	
+				/*  Has a stop been issued? */
+				if( p_mailbox == NULL || p_mailbox->stop == 1 ) {
+	
+					p_mailbox->wait_count_r -= 1;
+
+					/* Wake others up */
+					if ( p_mailbox->wait_count_r > 0)
+						up( &(p_mailbox->sem_r) );
+						
+		
+					spin_unlock( &(p_mailbox->mr_lock) );
+	
+					return MAILBOX_STOPPED;
+				}
+
+			} while( p_mailbox->num_messages == 0 );
+		}
+	}
+	
+	/* Assertion */
+	if( p_mailbox->num_messages == 0 ) {
+		printk("You are removing an item from an empty list you fool.\n");
+		spin_unlock( &(p_mailbox->mr_lock) );
+		return -100000000;
+	}
+
+
+	p_mailbox->num_messages -= 1; // decrement message count, we are about to remove something from the mailbox
+	old = p_mailbox->head;
+	
+	/* Unlink first message on the linked list */
+	if( old->next == NULL )
+		p_mailbox->tail = NULL;
+
+	p_mailbox->head = old->next;
+
+	/* Signal if any sending threads are blocked */
+	
+	if ( p_mailbox->wait_count_s > 0) {
+		up( &(p_mailbox->sem_s) );
+		p_mailbox->wait_count_s -= 1;
+	}
+
+spin_unlock( &(p_mailbox->mr_lock) ); 
+
+	/* Copy Data To user */
+
+	if(
+	(copy_to_user( sender, &(old->sender_id), sizeof(pid_t) ) ||
+	copy_to_user( msg, old->msg, old->len ) ||
+	copy_to_user( len, &(old->len), sizeof(int) ) ) < 0 ) {
+	
+		printk("COPY_TO_USER FAILED!!!\n");	
+		spin_unlock( &(p_mailbox->mr_lock) );	
+		return MSG_ARG_ERROR;
+	}  
+
+	kmem_cache_free( message_cachep,old );
+
+	return 0;
+
+}
+
+asmlinkage int sys_mailbox_manage(bool stop, int *count) {
+
+	struct cs3013_mailbox* p_mailbox;
+	int queued_messages;
+
+	p_mailbox = current->mailbox;
+	
+	/* Error checking */
+	if( p_mailbox == 0 ) {
+		printk("Mailbox invalid! (mailbox_manage\n");
+		return MAILBOX_ERROR;
+	}
+
+
+spin_lock( &(p_mailbox->mr_lock) );
+
+	if( stop == 1 ) {
+
+		printk("in manage mailbox\n");
+
+		p_mailbox->stop = stop;
+		spin_unlock( &(p_mailbox->mr_lock) ); 
+
+		if ( p_mailbox->wait_count_s > 0) {
+
+			up( &(p_mailbox->sem_s) );
+
+			while( p_mailbox->wait_count_s > 0 ) {};
+		}
+		
+
+		printk("No more sending messages blocked!\n");		
+
+		if ( p_mailbox->wait_count_r > 0) {
+
+			up( &(p_mailbox->sem_r) );
+
+			while( p_mailbox->wait_count_r >  0 ) {};
+		}
+
+		printk("No more receiving messages blocked!\n");	
+
+		flush_messages();	
+	}
+
+
+spin_unlock( &(p_mailbox->mr_lock) ); 
+
+	queued_messages = p_mailbox->wait_count_s + p_mailbox->wait_count_r;
+
+	kfree( p_mailbox );
+
+	copy_to_user( count, &queued_messages, sizeof(int) );
+
+	return 0;	
+
+}
+
+int flush_messages() {
+
+	struct cs3013_mailbox* p_mailbox;
+	struct cs3013_message* p_message;
+	struct cs3013_message* next;
+
+	p_mailbox = current->mailbox;
+	
+	printk("in flush messages()\n");
+
+	/* Error checking */
+	if( p_mailbox == NULL ) {
+		printk("Mailbox invalid! (flush_messages()\n");
+		return MAILBOX_INVALID;
+	}
+
+	if( (p_message = p_mailbox->head) == NULL )
+		return 0;
+
+	do {
+		next = p_message->next;
+
+		kmem_cache_free( message_cachep, p_message );
+		
+	} while( (p_message = next) != NULL );
+
+	printk("out flush messages()\n");
+
+	return 0;
+
+}
+
+
diff -urN kernelInit/kernel/Makefile kernelSrc/kernel/Makefile
--- kernelInit/kernel/Makefile	2007-07-08 19:32:17.000000000 -0400
+++ kernelSrc/kernel/Makefile	2008-10-02 15:28:30.000000000 -0400
@@ -8,7 +8,7 @@
 	    signal.o sys.o kmod.o workqueue.o pid.o \
 	    rcupdate.o extable.o params.o posix-timers.o \
 	    kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
-	    hrtimer.o rwsem.o latency.o nsproxy.o srcu.o die_notifier.o
+	    hrtimer.o rwsem.o latency.o nsproxy.o srcu.o die_notifier.o mailbox.o
 
 obj-$(CONFIG_STACKTRACE) += stacktrace.o
 obj-y += time/
