#include "jos.h" void process_zb(void *arg) { ZB_call *zb, *other; JRB tmp; int nbytes; zb = (ZB_call *) arg; tmp = jrb_find_str(JG.zb_waiters, zb->name); /* If there's no matching call in the tree, insert the ZB_call and return */ if (tmp == NULL) { jrb_insert_str(JG.zb_waiters, zb->name, new_jval_v((void *) zb)); return; /* Note, this will have the scheduler run. */ } /* If the other call in the tree is of the same type, insert the ZB_call and return */ other = (ZB_call *) tmp->val.v; if (other->send_or_receive == zb->send_or_receive) { jrb_insert_str(JG.zb_waiters, zb->name, new_jval_v((void *) zb)); return; } /* Otherwise, we have a match. First remove it from the tree: */ jrb_delete_node(tmp); /* Next, copy the message. */ nbytes = zb->size; if (other->size < nbytes) nbytes = other->size; if (zb->send_or_receive == 'S') { memcpy(other->physical->ptr, zb->physical->ptr, nbytes); } else { memcpy(zb->physical->ptr, other->physical->ptr, nbytes); } /* Set the return value (it goes is Register 2, but any one would do for this exam). */ zb->caller->regs[Reg2] = nbytes; other->caller->regs[Reg2] = nbytes; /* Put the two PCB's onto the ready queue */ dll_append(JG.readyq, new_jval_v((void *) zb->caller)); dll_append(JG.readyq, new_jval_v((void *) other->caller)); /* Finally, free up the memory */ free(zb); free(other); return; }