void
soput(struct socket *so)
{

	KASSERT(!cv_has_waiters(&so->so_cv));
	KASSERT(!cv_has_waiters(&so->so_rcv.sb_cv));
	KASSERT(!cv_has_waiters(&so->so_snd.sb_cv));
	seldestroy(&so->so_rcv.sb_sel);
	seldestroy(&so->so_snd.sb_sel);
	mutex_obj_free(so->so_lock);
	cv_destroy(&so->so_cv);
	cv_destroy(&so->so_rcv.sb_cv);
	cv_destroy(&so->so_snd.sb_cv);
	pool_cache_put(socket_cache, so);
}
示例#2
0
void
cprng_strong_destroy(struct cprng_strong *cprng)
{

	/*
	 * Destroy the rndsink first to prevent calls to the callback.
	 */
	rndsink_destroy(cprng->cs_rndsink);

	KASSERT(!cv_has_waiters(&cprng->cs_cv));
#if 0
	KASSERT(!select_has_waiters(&cprng->cs_selq)) /* XXX ? */
#endif

	nist_ctr_drbg_destroy(&cprng->cs_drbg);
	seldestroy(&cprng->cs_selq);
	cv_destroy(&cprng->cs_cv);
	mutex_destroy(&cprng->cs_lock);

	explicit_memset(cprng, 0, sizeof(*cprng)); /* paranoia */
	kmem_free(cprng, sizeof(*cprng));
}
示例#3
0
void
rumpuser_cv_has_waiters(struct rumpuser_cv *cv, int *rvp)
{

	cv_has_waiters(cv, rvp);
}
示例#4
0
static int
semrealloc(int newsemmni, int newsemmns, int newsemmnu)
{
	struct semid_ds *new_sema, *old_sema;
	struct __sem *new_sem;
	struct sem_undo *new_semu_list, *suptr, *nsuptr;
	int *new_semu;
	kcondvar_t *new_semcv;
	vaddr_t v;
	int i, j, lsemid, nmnus, sz;

	if (newsemmni < 1 || newsemmns < 1 || newsemmnu < 1)
		return EINVAL;

	/* Allocate the wired memory for our structures */
	sz = ALIGN(newsemmni * sizeof(struct semid_ds)) +
	    ALIGN(newsemmns * sizeof(struct __sem)) +
	    ALIGN(newsemmni * sizeof(kcondvar_t)) +
	    ALIGN(newsemmnu * seminfo.semusz);
	sz = round_page(sz);
	v = uvm_km_alloc(kernel_map, sz, 0, UVM_KMF_WIRED|UVM_KMF_ZERO);
	if (v == 0)
		return ENOMEM;

	mutex_enter(&semlock);
	if (sem_realloc_state) {
		mutex_exit(&semlock);
		uvm_km_free(kernel_map, v, sz, UVM_KMF_WIRED);
		return EBUSY;
	}
	sem_realloc_state = true;
	if (sem_waiters) {
		/*
		 * Mark reallocation state, wake-up all waiters,
		 * and wait while they will all exit.
		 */
		for (i = 0; i < seminfo.semmni; i++)
			cv_broadcast(&semcv[i]);
		while (sem_waiters)
			cv_wait(&sem_realloc_cv, &semlock);
	}
	old_sema = sema;

	/* Get the number of last slot */
	lsemid = 0;
	for (i = 0; i < seminfo.semmni; i++)
		if (sema[i].sem_perm.mode & SEM_ALLOC)
			lsemid = i;

	/* Get the number of currently used undo structures */
	nmnus = 0;
	for (i = 0; i < seminfo.semmnu; i++) {
		suptr = SEMU(semu, i);
		if (suptr->un_proc == NULL)
			continue;
		nmnus++;
	}

	/* We cannot reallocate less memory than we use */
	if (lsemid >= newsemmni || semtot > newsemmns || nmnus > newsemmnu) {
		mutex_exit(&semlock);
		uvm_km_free(kernel_map, v, sz, UVM_KMF_WIRED);
		return EBUSY;
	}

	new_sema = (void *)v;
	new_sem = (void *)((uintptr_t)new_sema +
	    ALIGN(newsemmni * sizeof(struct semid_ds)));
	new_semcv = (void *)((uintptr_t)new_sem +
	    ALIGN(newsemmns * sizeof(struct __sem)));
	new_semu = (void *)((uintptr_t)new_semcv +
	    ALIGN(newsemmni * sizeof(kcondvar_t)));

	/* Initialize all semaphore identifiers and condvars */
	for (i = 0; i < newsemmni; i++) {
		new_sema[i]._sem_base = 0;
		new_sema[i].sem_perm.mode = 0;
		cv_init(&new_semcv[i], "semwait");
	}
	for (i = 0; i < newsemmnu; i++) {
		nsuptr = SEMU(new_semu, i);
		nsuptr->un_proc = NULL;
	}

	/*
	 * Copy all identifiers, semaphores and list of the
	 * undo structures to the new memory allocation.
	 */
	j = 0;
	for (i = 0; i <= lsemid; i++) {
		if ((sema[i].sem_perm.mode & SEM_ALLOC) == 0)
			continue;
		memcpy(&new_sema[i], &sema[i], sizeof(struct semid_ds));
		new_sema[i]._sem_base = &new_sem[j];
		memcpy(new_sema[i]._sem_base, sema[i]._sem_base,
		    (sizeof(struct __sem) * sema[i].sem_nsems));
		j += sema[i].sem_nsems;
	}
	KASSERT(j == semtot);

	j = 0;
	new_semu_list = NULL;
	for (suptr = semu_list; suptr != NULL; suptr = suptr->un_next) {
		KASSERT(j < newsemmnu);
		nsuptr = SEMU(new_semu, j);
		memcpy(nsuptr, suptr, SEMUSZ);
		nsuptr->un_next = new_semu_list;
		new_semu_list = nsuptr;
		j++;
	}

	for (i = 0; i < seminfo.semmni; i++) {
		KASSERT(cv_has_waiters(&semcv[i]) == false);
		cv_destroy(&semcv[i]);
	}

	sz = ALIGN(seminfo.semmni * sizeof(struct semid_ds)) +
	    ALIGN(seminfo.semmns * sizeof(struct __sem)) +
	    ALIGN(seminfo.semmni * sizeof(kcondvar_t)) +
	    ALIGN(seminfo.semmnu * seminfo.semusz);
	sz = round_page(sz);

	/* Set the pointers and update the new values */
	sema = new_sema;
	sem = new_sem;
	semcv = new_semcv;
	semu = new_semu;
	semu_list = new_semu_list;

	seminfo.semmni = newsemmni;
	seminfo.semmns = newsemmns;
	seminfo.semmnu = newsemmnu;

	/* Reallocation completed - notify all waiters, if any */
	sem_realloc_state = false;
	cv_broadcast(&sem_realloc_cv);
	mutex_exit(&semlock);

	uvm_km_free(kernel_map, (vaddr_t)old_sema, sz, UVM_KMF_WIRED);
	return 0;
}