#include jos.h void process_zb(void *arg) { ZB_call *zb, *other; JRB tmp; Dllist l; 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) { l = new_dllist(); dll_append(l, new_jval_v((void *) zb)); jrb_insert_str(JG.zb_waiters, zb->name, new_jval_v((void *) l)); return; } l = (dllist) tmp->val.v; other = (ZB_call *) l->flink; /* If the other calls in the tree are of the same type, append the ZB_call and return */ if (other->send_or_receive == zb->send_or_receive) { dll_append(l, new_jval_v((void *) zb)); return; } /* Otherwise, we have a match. First remove it from the list/tree: */ dll_delete_node(l->flink); if (dll_empty(l)) { dll_free_tree(l); jrb_delete_node(tmp); } /* The rest of the code is the same as before. */ 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; }