rem: static void smp_finish_message_processing(int curr_cpu, struct smp_msg *msg, int source_mailbox)
add: smp_finish_message_processing(int curr_cpu, struct smp_msg *msg, int source_mailbox)
context: static void smp_finish_message_processing(int curr_cpu, struct smp_msg *msg, int source_mailbox){	int old_refcount;	old_refcount = atomic_add(&msg->ref_count, -1);	if(old_refcount == 1) {		// we were the last one to decrement the ref_count		// it's our job to remove it from the list & possibly clean it up		struct smp_msg **mbox = NULL;		spinlock_t *spinlock = NULL;		// clean up the message from one of the mailboxes		switch(source_mailbox) {			case MAILBOX_BCAST:				mbox = &smp_broadcast_msgs;				spinlock = &broadcast_msg_spinlock;				break;			case MAILBOX_LOCAL:				mbox = &smp_msgs[curr_cpu];				spinlock = &cpu_msg_spinlock[curr_cpu];				break;		}		acquire_spinlock_nocheck(spinlock);//		dprintf("cleaning up message 0x%x\n", msg);		if(msg == *mbox) {			(*mbox) = msg->next;		} else {			// we need to walk to find the message in the list.			// we can't use any data found when previously walking through			// the list, since the list may have changed. But, we are guaranteed			// to at least have msg in it.			struct smp_msg *last = NULL;			struct smp_msg *msg1;			msg1 = *mbox;			while(msg1 != NULL && msg1 != msg) {				last = msg1;				msg1 = msg1->next;			}			// by definition, last must be something			if(msg1 == msg && last != NULL) {				last->next = msg->next;			} else {				dprintf("last == NULL or msg != msg1!!!\n");			}		}		release_spinlock(spinlock);		if(msg->data_ptr != NULL)			kfree(msg->data_ptr);		if(msg->flags == SMP_MSG_FLAG_SYNC) {			msg->done = true;			// the caller cpu should now free the message		} else {			// in the !SYNC case, we get to free the message			return_free_message(msg);		}	}}