int XXp1(char *arg) { int i, pid[10], result[10]; printf("XXp1(): creating children\n"); for (i = 0; i < 3; i++) pid[i] = fork1("XXp2", XXp2, "XXp2", USLOSS_MIN_STACK, 3); printf("XXp1(): creating zapper child\n"); pid[i] = fork1("XXp3", XXp3, "XXp3", USLOSS_MIN_STACK, 4); printf("XXp1(): unblocking children\n"); for (i = 0; i < 3; i++) result[i] = unblockProc(pid[i]); for (i = 0; i < 3; i++) printf("XXp1(): after unblocking %d, result = %d\n", pid[i], result[i]); quit(0); return 0; } /* XXp1 */
// returns 0 if nothing unblocked // returns 1 if something was unblocked int unblock(int mboxID, int block, int size, char message[], int *realSize) { // multiple processes may be blocked on the same mailbox, we only want to unblock one of them // this keeps track of it. Start at -1 incase no one is blocked on that mailbox int unblockID = -1; // go through the entire proc list and find the process to be unblocked for (int i = 0; i < MAXPROC; i++) { // find a process blocked on this mailbox and make sure they are the same type of block if (processTable[i].mboxID == mboxID && processTable[i].blockStatus == block) { // if this is the first process to be found if (unblockID == -1) { // set the unblockid to this new processes index in the table unblockID = i; } // otherwise else { // compare the start times of the old process and this new found one if (processTable[unblockID].timeAdded > processTable[i].timeAdded) { // if the new found process was blocked before the last found process, swap unblockID = i; } } } } // check to see if anyone needs to be unblocked if (unblockID != -1) { // save their pid int pid = processTable[unblockID].pid; // check if a receiver wants to get a message thats too big int retVal = 1; if (block == RECEIVEBLOCK && size > processTable[unblockID].size) { retVal++; } // if a zero slot message box if (message != NULL && block == SENDBLOCK) { memcpy(message, processTable[unblockID].message, size); *realSize = processTable[unblockID].size; } else if (message != NULL && block == RECEIVEBLOCK) { memcpy(processTable[unblockID].message, message, size); processTable[unblockID].size = size; } if (block == SENDBLOCK) { // empty out this slot in the processTable processTable[unblockID].pid = -1; processTable[unblockID].blockStatus = -1; processTable[unblockID].message[0] = '\0'; processTable[unblockID].size = -1; processTable[unblockID].mboxID = -1; processTable[unblockID].timeAdded = -1; } // unblock the process unblockProc(pid); return retVal; } else { return 0; } }
int MboxRelease(int mailboxID) { check_kernel_mode("MboxRelease"); disableInterrupts(); // get the mailbox mailbox *mbox = &(MailBoxTable[mailboxID]); // check to make sure the mail box is in use if (mbox->mboxID == -1) { return -1; } // update that this mail box is about to be deleted MailBoxTable[mailboxID].mboxID = -1; // unblock all processes blocked on this mailbox int unblockID = -1; // the index of the proccess to unblock // go through the entire proc list and find the process to be unblocked for (int i = 0; i < MAXPROC; i++) { // find a process blocked on this mailbox if (processTable[i].mboxID == mailboxID) { // if this is the first process to be found if (unblockID == -1) { // set the unblockid to this new processes index in the table unblockID = i; } // otherwise else { // compare the start times of the old process and this new found one if (processTable[unblockID].timeAdded > processTable[i].timeAdded) { // if the new found process was blocked before the last found process, swap unblockID = i; } } } } // if a blocked person was found, release them if (unblockID != -1) { unblockProc(processTable[unblockID].pid); // remove their info from the procTable processTable[unblockID].pid = -1; processTable[unblockID].blockStatus = NOT_BLOCKED; processTable[unblockID].message[0] = '\0'; processTable[unblockID].size = -1; processTable[unblockID].mboxID = -1; processTable[unblockID].timeAdded = -1; } // if there are still more processes to be unblocked while (unblockID != -1) { // set unblockID back to -1; unblockID = -1; // go through the entire proc list and find the process to be unblocked for (int i = 0; i < MAXPROC; i++) { // find a process blocked on this mailbox if (processTable[i].mboxID == mailboxID) { // if this is the first process to be found if (unblockID == -1) { // set the unblockid to this new processes index in the table unblockID = i; } // otherwise else { // compare the start times of the old process and this new found one if (processTable[unblockID].timeAdded > processTable[i].timeAdded) { // if the new found process was blocked before the last found process, swap unblockID = i; } } } } // if a blocked person was found, release them if (unblockID != -1) { unblockProc(processTable[unblockID].pid); // remove their info from the procTable processTable[unblockID].pid = -1; processTable[unblockID].blockStatus = NOT_BLOCKED; processTable[unblockID].message[0] = '\0'; processTable[unblockID].size = -1; processTable[unblockID].mboxID = -1; processTable[unblockID].timeAdded = -1; } } // null out all slots used by the mailbox slotPtr pre = NULL; slotPtr slot = mbox->headPtr; while (slot != NULL) { slot->mboxID = -1; slot->status = -1; slot->message[0] = '\0'; slot->size = -1; if (pre != NULL) { pre->nextSlot = NULL; } pre = slot; slot = slot->nextSlot; } // null out the removed mailbox MailBoxTable[mailboxID].mboxID = -1; MailBoxTable[mailboxID].numSlots = -1; MailBoxTable[mailboxID].numSlotsUsed = -1; MailBoxTable[mailboxID].slotSize = -1; MailBoxTable[mailboxID].headPtr = NULL; MailBoxTable[mailboxID].endPtr = NULL; MailBoxTable[mailboxID].blockStatus = 1; // check if zapped if (isZapped()) { return -3; } enableInterrupts(); return 0; }