DPRINTF(("semexit:  back from wakeup\n"));
semexit(struct proc *p){	struct sem_undo *suptr;	struct sem_undo **supptr;	/*	 * Go through the chain of undo vectors looking for one associated with	 * this process.	 */	for (supptr = &semu_list; (suptr = *supptr) != NULL;	    supptr = &suptr->un_next) {		if (suptr->un_proc == p)			break;	}	/*	 * No (i.e. we are in case 1 or 2).	 *	 * If there is no undo vector, skip to the end and unlock the	 * semaphore facility if necessary.	 */	if (suptr == NULL)		return;	/*	 * We are now in case 1 or 2, and we have an undo vector for this	 * process.	 */#ifdef SEM_DEBUG	printf("proc @%p has undo structure with %d entries\n", p,	    suptr->un_cnt);#endif	/*	 * If there are any active undo elements then process them.	 */	if (suptr->un_cnt > 0) {		int ix;		for (ix = 0; ix < suptr->un_cnt; ix++) {			int semid = suptr->un_ent[ix].un_id;			int semnum = suptr->un_ent[ix].un_num;			int adjval = suptr->un_ent[ix].un_adjval;			struct semid_ds *semaptr;			if ((semaptr = sema[semid]) == NULL)				panic("semexit - semid not allocated");			if (semnum >= semaptr->sem_nsems)				panic("semexit - semnum out of range");#ifdef SEM_DEBUG			printf("semexit:  %p id=%d num=%d(adj=%d) ; sem=%d\n",			    suptr->un_proc, suptr->un_ent[ix].un_id,			    suptr->un_ent[ix].un_num,			    suptr->un_ent[ix].un_adjval,			    semaptr->sem_base[semnum].semval);#endif			if (adjval < 0 &&			    semaptr->sem_base[semnum].semval < -adjval)				semaptr->sem_base[semnum].semval = 0;			else				semaptr->sem_base[semnum].semval += adjval;			wakeup((caddr_t)&sema[semid]);#ifdef SEM_DEBUG			printf("semexit:  back from wakeup\n");#endif		}	}	/*	 * Deallocate the undo vector.	 */#ifdef SEM_DEBUG	printf("removing vector\n");#endif	*supptr = suptr->un_next;	pool_put(&semu_pool, suptr);}