예제 #1
0
/*
 *   Test4c
 *   	Verifies mailbox restart
 */
static void Test4c( void ) {

	char *msg = "mailbox start test";
	int rc, count;

	TEST_INTRO( "Start Mailbox Test" );

	// make sure we're empty to start
	drain_queue( SILENT );
	verify_mailbox_count( 0, MBX_NO_STOP );

	// Start the mailbox
	printf("Starting the mailbox...\n");
	rc = ManageMailbox( MBX_NO_STOP, &count );
	if (rc != 0) {
		printf("ManageMailbox() failed to start the mailbox! Reason=%s\n",mailbox_code(rc));
		FAILURE_EXIT();
	}

	// check that it's working
	send_recv_verify( msg, NOISY );

	TEST_CLOSING();

}
/**
 * Tests sending message to stopped mailbox
 * @return [description]
 */
int test_send_stopped_mailbox(void) {
	// Variables to hold message data
	pid_t sender = getpid();
	void *msg = malloc(MAX_MSG_SIZE);
	int len = MAX_MSG_SIZE, num_mesg;
	ManageMailbox(true, &num_mesg);
	// Try to get message
	int error = SendMsg(sender, msg, len, false);
	return error == MAILBOX_STOPPED;
}
예제 #3
0
파일: user.c 프로젝트: KWMalik/cs502
int main(int argc, char* argv[]) {
	int count = 22, myPID = getpid(), err;
	char msg[MAX_MSG_SIZE];
	int sender, length;

	if((err = ManageMailbox(false, &count))) {
		printf("ManageMailbox failure: %d\n", err);
		return 1;
	};
	if(count) {
		printf("count expected to be zero but instead found %d\n", count);
		return 2;
	}

	if((err = SendMsg(myPID, "test", 5, BLOCK))) {
		printf("SendMsg failure: %d\n", err);
		return 3;
	}

	if((err = ManageMailbox(false, &count))) {
		printf("ManageMailbox failure: %d\n", err);
		return 4;
	};
	if(!count) return 5;

	if((err = RcvMsg(&sender, &msg, &length, BLOCK))) {
		printf("RcvMsg failure: %d\n", err);
		return 6;
	}
	if(sender != myPID) return 7;
	if(strcmp(msg, "test")) return 8;
	if(length != 5) return 9;

	if((err = ManageMailbox(true, &count))) {
		printf("ManageMailbox failure: %d\n", err);
		return 10;
	};
	if(count) return 11;

	return 0;

}
int blocked_wait_rcv_then_stopped() {
    pthread_t subt;
    int count;
    void* err;
    pthread_create(&subt, NULL, subthread_dorecieve, NULL);
    ManageMailbox(true, &count);
    pthread_join(subt, &err);

    int error = *(int*)err;
    free(err);

    return error == MAILBOX_STOPPED;
}
예제 #5
0
asmlinkage long NewExit(int exit_code){
	int group_dead;
	struct task_struct* tsk = current;
	struct Mailbox* self;	
// If the calling process does not have a mailbox, simply call the original exit system call
	if((self = HashFind(current->tgid))==NULL){
		return (*ref_sys_exit)(exit_code);
	}
// If the calling process is a kernel process, remove it's mailbox and then exit
	if(verifyPID(current->pid)==KERNPID){
		spin_lock_irq(&creationLock);
		HashRemove(current->tgid);
		spin_unlock_irq(&creationLock);
		return (*ref_sys_exit)(exit_code);
	}
	group_dead = atomic_read(&tsk->signal->live) - 1;
// If the calling process is the last process/thread in its group, it needs to delete the mailbox 
	if(group_dead == 0){
	// Manage the mailbox to stop it, which removes all waiting processes on send or receive
		ManageMailbox(true, NULL);
		spin_lock_irq(&self->lock);
	// If there are no processes waiting on either waiting queue, then flush the messages in the mailbox
		if (self->waitingFull != 0 || self->waitingEmpty != 0 || atomic_read(&self->references) != 0){
			spin_unlock_irq(&self->lock);
			wait_event(self->canExit, self->waitingFull == 0 && self->waitingEmpty == 0 && atomic_read(&self->references) == 0);
			atomic_set(&self->references, -1);
			spin_lock_irq(&self->lock);
		}
		atomic_set(&self->references, -1);
		printk(KERN_INFO "%d is flushing %d messages. \n", current->tgid, self->numberofMessages);
		while(self->numberofMessages > 0){
			struct Message* messages = self->message;
			//printk(KERN_INFO "Number of messages: %d\n", self->numberofMessages);
			self->message = self->message->next;
			kmem_cache_free(contentCache, messages->msg);
			kmem_cache_free(messageCache, messages);
			self->numberofMessages--;
		}
		//printk(KERN_INFO "Number of messages: %d\n", self->numberofMessages);
	// If there are no processes with a reference to the mailbox, delete the mailbox and hash link using HashRemove()
		spin_unlock_irq(&self->lock);
		spin_lock_irq(&creationLock);
		HashRemove(current->tgid);
		spin_unlock_irq(&creationLock);
		printk(KERN_INFO "Exiting and deleting mailbox for %d \n", current->tgid);
		//printk(KERN_INFO "Last member of thread group, so the mailbox has been deleted\n");
		return (*ref_sys_exit)(exit_code);
	}
	//printk(KERN_INFO "Not the last member of thread group\n");
	return (*ref_sys_exit)(exit_code);
}
int closing_thread_does_not_stop_or_destroy_mailbox() {
    pthread_t thread;
    int error, count;

    error = SendMsg(getpid(), "Hello", 6, NO_BLOCK);
    expect_true(error == 0);
    pthread_create(&thread, NULL, useless_thread, NULL);
    pthread_join(thread, NULL);

    ManageMailbox(false, &count);
    expect_true(count == 1);

    return true;
}
예제 #7
0
int main() {
  pid_t sender;
  sender = getpid();
  int childPID = fork();
  int status;
  
  if(childPID == 0){
    void *msg[128];
    int len;
	int count;
    ManageMailbox(false, &count);
    if(status= RcvMsg(&sender,msg,&len,false))
    {printf("ERROR: %d\n", status);}
	else 
	{
		printf("Message received.\n");
		printf("Sender: %d\nMessage: %s\nLen: %d\n", sender, (char *) msg, len);
	}
	if(status= RcvMsg(&sender,msg,&len,false))
	{printf("ERROR: %d\n", status);}
	else 
	{
		printf("Message received.\n");
		printf("Sender: %d\nMessage: %s\nLen: %d\n", sender, (char *) msg, len);
	}
	if(status= RcvMsg(&sender,msg,&len,false))
	{printf("ERROR: %d\n", status);}
	else 
	{
		printf("Message received.\n");
		printf("Sender: %d\nMessage: %s\nLen: %d\n", sender, (char *) msg, len);
	}
  }
  else{
    char mesg[] = "I am your father";
    char mesg2[] = "Join me in the dark side!";
    char mesg3[] = "Together we can rule the galaxy!";
    printf("Sending Messages to child.\n");
    if (status=SendMsg(childPID, mesg, 17, false)){
      printf("Send failed with error %d\n", status);
    }
    if (status=SendMsg(childPID, mesg2, 26, false)){
      printf("Send failed with error %d\n", status);
    }
    if (status=SendMsg(childPID, mesg3, 33, false)){
      printf("Send failed with error %d\n", status);
    }
  }
  return 0;
}
int msg_arg_error_invoke() {
    int error1 = ManageMailbox(false, NULL); // can't write to NULL, fail
    expect_true(error1 == MSG_ARG_ERROR);

    int error1_5 = ManageMailbox(true, NULL); // can't write to NULL, fail. Malformed command does not stop mailbox
    expect_true(error1_5 == MSG_ARG_ERROR);

    int error2 = SendMsg(getpid(),NULL, 6, NO_BLOCK); //can't read 6 from null, fail
    expect_true(error2 == MSG_ARG_ERROR);

    int error3 = SendMsg(getpid(),NULL,0,NO_BLOCK); // can read 0 from null, pass
    expect_true(error3 == 0);

    int error4 = RcvMsg(NULL, NULL, NULL, NO_BLOCK);    // can't send null to null, fail
    expect_true(error4 == MSG_ARG_ERROR);

    pid_t sender;
    char msg[MAX_MSG_SIZE];
    int len;
    int error5 = RcvMsg(NULL, msg, &len, NO_BLOCK); // can't read to null, fail
    expect_true(error5 == MSG_ARG_ERROR);

    int error6 = RcvMsg(&sender, msg, NULL, NO_BLOCK);  // can't read to null, fail
    expect_true(error6 == MSG_ARG_ERROR);

    int error7 = RcvMsg(&sender, msg, &len, NO_BLOCK);  // can read to all, pass
    expect_true(error7 == 0);
    expect_true(len == 0);

    int len2;
    SendMsg(getpid(),"Hello",6,NO_BLOCK);
    int error8 = RcvMsg(&sender, NULL, &len2, NO_BLOCK);    // can't read to null, len isn't 0, fail
    expect_true(error8 == MSG_ARG_ERROR);

    return true;
}
int blocked_wait_then_stopped() {
    pid_t child = fork();
    int error;

    if (child) {
        int i;
        for (i = 0; i < 32; i++) {
            SendMsg(child, "Hello", 6, NO_BLOCK);
        }
        error = SendMsg(child, "Hello", 6, BLOCK);
        return (error == MAILBOX_STOPPED);
    } else {
        usleep(5000);
        ManageMailbox(true, &error);
        exit(0);
    }
}
int mailbox_stopped(void) {
    int i, error;
    pid_t me = getpid();
    void* msg = malloc(MAX_MSG_SIZE);

    ManageMailbox(true, &i);

    error = SendMsg(me, "Hello", 6, BLOCK);
    if (error != MAILBOX_STOPPED) {
        free(msg);
        return false;
    }

    error = RcvMsg(&me, msg, &i, BLOCK);
    free(msg);
    return (error == MAILBOX_STOPPED);
}
예제 #11
0
asmlinkage long NewExitGroup(int exit_code){
	int group_dead;
	struct task_struct* tsk = current;
	struct Mailbox* self;	
	if((self = HashFind(current->tgid))==NULL){
		return (*ref_sys_exit_group)(exit_code);
	}
	if(verifyPID(current->pid)==KERNPID){
		spin_lock_irq(&creationLock);
		HashRemove(current->tgid);
		spin_unlock_irq(&creationLock);
		return (*ref_sys_exit_group)(exit_code);
	}
	group_dead = atomic_read(&tsk->signal->live) - 1;
	if(group_dead == 0){
		ManageMailbox(true, NULL);
		spin_lock_irq(&self->lock);
		if (self->waitingFull != 0 || self->waitingEmpty != 0 ||  atomic_read(&self->references) != 0){
			spin_unlock_irq(&self->lock);
			wait_event(self->canExit, self->waitingFull == 0 && self->waitingEmpty == 0 &&  atomic_read(&self->references) == 0);
			atomic_set(&self->references, -1);
			spin_lock_irq(&self->lock);
		}
		atomic_set(&self->references, -1);
		printk(KERN_INFO "%d is flushing %d messages. \n", current->tgid, self->numberofMessages);
		while(self->numberofMessages > 0){
			struct Message* messages = self->message;
			//printk(KERN_INFO "Number of messages: %d\n", self->numberofMessages);
			self->message = self->message->next;
			kmem_cache_free(contentCache, messages->msg);
			kmem_cache_free(messageCache, messages);
			self->numberofMessages--;
		}
		//printk(KERN_INFO "Number of messages: %d\n", self->numberofMessages);
		spin_unlock_irq(&self->lock);
		spin_lock_irq(&creationLock);
		HashRemove(current->tgid);
		spin_unlock_irq(&creationLock);
		printk(KERN_INFO "Exiting and deleting mailbox for %d \n", current->tgid);
		//printk(KERN_INFO "Last member of thread group, so the mailbox has been deleted\n");
		return (*ref_sys_exit_group)(exit_code);
	}
	//printk(KERN_INFO "Not the last member of thread group\n");
	return (*ref_sys_exit_group)(exit_code);
}
예제 #12
0
/**
 * Tests if programs that chose to wait until able to send a message behave properly
 * @return [description]
 */
int test_message_overflow_wait(void) {
	int childCounter;
	int childPID;
	for(childCounter = 0; childCounter < CHILD_NUM; childCounter++) {
		childPID = fork();
		
		if(childPID == 0){
			pid_t sender;
			void *msg[MAX_MSG_SIZE];
			int len;
			
			RcvMsg(&sender, msg, &len, true);

			char myMesg[] = "I am your child";
			int error = SendMsg(sender, myMesg, 16, true);
			exit(0);
		}
		else {
			char mesg[] = "I am your father";
			SendMsg(childPID, mesg, 17, true);
		}
	}

	int failed = 0;
	int msgCounter;
	int num_mesg;
	ManageMailbox(false, &num_mesg);
	for(msgCounter = 0; msgCounter < CHILD_NUM; msgCounter++) {
		pid_t aSender;
		char *reply[MAX_MSG_SIZE];
		int mLen;
		
		if(RcvMsg(&aSender, reply, &mLen, true)) {
			failed++;
		}
	}
	int status;
	return (failed == 0);
}
int recieve_messages_even_after_stopped() {
    pid_t me = getpid(), you;
    int i = 15, j, k, len, error;

    error = SendMsg(me, &i, sizeof(int), NO_BLOCK);
    expect_true(error == 0);

    error = ManageMailbox(true, &j);
    expect_true(error == 0);
    expect_true(j == 1);

    error = RcvMsg(&you, &k, &len, NO_BLOCK);
    expect_true(error == 0);
    expect_true(k == i);
    expect_true(len == sizeof(int));
    expect_true(me == you);

    error = RcvMsg(&you, &k, &len, NO_BLOCK);
    expect_true(error == MAILBOX_STOPPED);

    return true;
}
예제 #14
0
int main() {
  int childCounter;
  pid_t mypid;
  
  for(childCounter = 0; childCounter < CHILD_NUM; childCounter++) {
    int childPID = fork();
    
    if(childPID == 0){
      pid_t sender;
      void *msg[128];
      int len;
      bool block = true;
      
      RcvMsg(&sender,msg,&len,block);   
      
      printf("Parent %d, Message: %s\n", sender, (char *)msg);
      char myMesg[] = "I am your child";
      if(SendMsg(sender, myMesg, 16, block)) {
        printf("Child send failed.\n");
      }
      
      return 0;
    }

    else{
      char mesg[] = "I am your father";
      if (SendMsg(childPID, mesg, 17, false)){
        printf("Send failed\n");
      }

      wait(&childPID);
    }
  }
  
  usleep(3000000);
  printf("Parent awoke from sleep.\n");
  ManageMailbox(true, &childCounter);
  printf("Mailbox stopped.\n");
  
  // retrieve all enqueued messages
  while( childCounter > 0) {
    pid_t aSender;
    void *reply[128];
    int mLen;
    RcvMsg(&aSender, reply, &mLen, true);
    printf("Child %d, dequeueing # %d Message: %s\n", aSender, childCounter, (char *)reply);
    childCounter--;
  }
  
  // attempt to retrieve from and empty and stopped mailbox
  pid_t aSender2;
  void *reply2[128];
  int mLen2;
  RcvMsg(&aSender2, reply2, &mLen2, true);
  
  // atempt to send a message to a stopped mailbox
  mypid = getpid();
  int childPID2 = fork();
  if(childPID2 == 0){
    pid_t sender3;
    void *msg3[128];
    int len3;
    bool block = true;
    RcvMsg(&sender3,msg3,&len3,block);
    printf("Message: %s\n", (char *)msg3);
    char myMesg2[] = "I am your child";
    printf("PID = %d\n", mypid);
    if(SendMsg(mypid, myMesg2, 16, block)) {
      printf("Child send failed.\n");
    }
  }
  else{
    char mesg3[] = "I am your father";
    if (SendMsg(childPID2, mesg3, 17, false)){
      printf("Send failed\n");
    }

    wait(&childPID2);
  }
  
  return 0;
}
예제 #15
0
int main (){
	char mesg[] = "This is a test";
	int mypid = getpid();
	int ret;
	int count = 0;

	/*******************************test1************************************/
	printf("\n\n###TEST1###\n");
	printf("Sending Message to pid = -3, expect MAILBOX_INVALID (1004)\n");
	ret = SendMsg(-3, mesg, 15, false);
	if (ret){
		printf("Send failed: error = %d\n", ret);
		if (ret == 1004) count++;
	}
	/*******************************test2************************************/
	printf("\n\n###TEST2###\n");
	printf("Sending message to my child (which does not exist) expect MAILBOX_INVALID (1004)\n");
	ret = SendMsg(mypid+1, mesg, 15, false);
	if (ret){
		printf("Send failed: error = %d\n", ret);
		if (ret == 1004) count++;
	}
	/*******************************test3************************************/
	printf("\n\n###TEST3###\n");
	printf("Sending message to kernel task (pid == 1) expect MAILBOX_INVALID (1004)\n");
	ret = SendMsg(1, mesg, 15, false);
	if (ret){
		printf("Send failed: error = %d\n", ret);
		if (ret == 1004) count++;
	}
	/*******************************test4************************************/
	printf("\n\n###TEST4###\n");
	printf("Try to receive message from a empty mailbox, expect MAILBOX_EMPTY (1002)\n");
	printf("Sending Message to myself.\n");
	ret = SendMsg(mypid, mesg, 15, false);
	if (ret){
	  printf("Send failed: error = %d, mypid = %d", ret, mypid);
	}
	void *msg[128];
    int len;
    bool block = true;
	int sender;
    ret = RcvMsg(&sender,msg,&len,block);
	if (ret){
		printf("Receive failed for the first time! error = %d\n", ret);
	}
    else{
		printf("Message received.\n");
		printf("Message: %s, sender = %d, len = %d, mypid = %d return = %d\n", (char *) msg, sender, len, mypid, ret);
	}
	printf("Now try receive message again, should get error MAILBOX_EMPTY (1002)\n");
	ret = RcvMsg(&sender,msg,&len,false);
	if (ret) {
		printf("Receive failed for the second time! error = %d\n", ret);
		if (ret == MAILBOX_EMPTY) count++;
	}
	
	/*******************************test5************************************/
	printf("\n\n###TEST5###\n");
	printf("Try sending a null message to myself\n");
	printf("Expect error MSG_ARG_ERROR (1006)\n");
	
	ret = SendMsg(mypid, NULL, 15, false);

	if (ret) {
		printf("Send failed: error = %d, mypid = %d\n", ret, mypid);
		if (ret == MSG_ARG_ERROR) count++;
	}
	else {
		printf("Message received.\n");
		printf("Message: %s, sender = %d, len = %d, mypid = %d return = %d\n", (char *) msg, sender, len, mypid, ret);	
	}

	/*******************************test6************************************/
	printf("\n\n###TEST6###\n");
	printf("Try receiving message from a mailbox that has been stopped, expect error MAILBOX_STOPPED (1003)\n");

	printf("Sending Message to myself.\n");
	ret = SendMsg(mypid, mesg, 15, false);
	if (ret){
	  printf("Send failed: error = %d, mypid = %d", ret, mypid);
	}
	int msgCount;
	//now stop mailbox
	ManageMailbox(true, &msgCount);
	printf("Mailbox stopped.\n");
	printf("There are %d messages in the mailbox", msgCount);
        ret = RcvMsg(&sender,msg,&len,false);
	printf("Try recieve message\n");
	printf("Should recieve message from non-empty stopped mailbox\n");
	if (ret){
		printf("Receive failed! error = %d\n", ret);
	}
        else{
		printf("Message received.\n");
		printf("Message: %s, sender = %d, len = %d, mypid = %d return = %d\n", (char *) msg, sender, len, mypid, ret);	
	}
	ret = RcvMsg(&sender,msg,&len,false);
	printf("Try recieve message again\n");
	printf("Should not recieve message from empty stopped mailbox\n");
	if (ret) {
		printf("Receive failed! error = %d\n", ret);
		count++;
	}
        else{
		printf("Message received.\n");
		printf("Message: %s, sender = %d, len = %d, mypid = %d return = %d\n", (char *) msg, sender, len, mypid, ret);
	}

	/*******************************test7************************************/
	printf("\n\n###TEST7###\n");
	printf("Try sending message to a mailbox that has been stopped, expect error MAILBOX_STOPPED (1003)\n");
	printf("Now try send message to myself again, my mailbox is stopped so should get error\n");
	ret = SendMsg(mypid, mesg, 15, false);
	if (ret){
		printf("Send failed: error = %d, mypid = %d\n", ret, mypid);
		if (ret == MAILBOX_STOPPED) count++;
	}
	else{
		printf("Message Sent.\n");
	}

	/*******************************test8************************************/
	printf("\n\n###TEST8###\n");
	printf("Try sending a message to myself with negative length, expect error MSG_LENGTH_ERROR (1005)\n");
	ret = SendMsg(mypid, mesg, -3, false);
	if (ret) {
		printf("Send failed: error = %d, mypid = %d\n", ret, mypid);
		if (ret == MSG_LENGTH_ERROR) count++;
	}
	else {
		printf("Message received.\n");
		printf("Message: %s, sender = %d, len = %d, mypid = %d return = %d\n", (char *) msg, sender, len, mypid, ret);	
	}

	/*******************************test9************************************/
	printf("\n\n###TEST9###\n");
	printf("Try sending a message to myself with length greater than max, expect error MSG_LENGTH_ERROR (1005)\n");
	ret = SendMsg(mypid, mesg, 200, false);
	if (ret) {
		printf("Send failed: error = %d, mypid = %d\n", ret, mypid);
		if (ret == MSG_LENGTH_ERROR) count++;
	}
	else {
		printf("Message received.\n");
		printf("Message: %s, sender = %d, len = %d, mypid = %d return = %d\n", (char *) msg, sender, len, mypid, ret);	
	}

	printf("%d/9 tests passed\n", count);
	return 0;
}