/* ARGSUSED */ static int fips140_actions(dev_t dev, caddr_t arg, int mode, int *rval, int cmd) { crypto_fips140_t fips140_info; uint32_t rv = CRYPTO_SUCCESS; int error = 0; if (copyin(arg, &fips140_info, sizeof (crypto_fips140_t)) != 0) return (EFAULT); switch (cmd) { case CRYPTO_FIPS140_STATUS: fips140_info.fips140_status = global_fips140_mode; break; case CRYPTO_FIPS140_SET: /* If the mode has been determined, there is nothing to set */ mutex_enter(&fips140_mode_lock); if (fips140_info.fips140_op == FIPS140_ENABLE && global_fips140_mode == FIPS140_MODE_UNSET) { /* * If FIPS 140 is enabled, all approriate modules * must be loaded and validated. This can be done in * the background as the rest of the OS comes up. */ global_fips140_mode = FIPS140_MODE_VALIDATING; (void) thread_create(NULL, 0, kcf_fips140_validate, NULL, 0, &p0, TS_RUN, MAXCLSYSPRI); cv_signal(&cv_fips140); } else if (fips140_info.fips140_op == FIPS140_DISABLE && global_fips140_mode == FIPS140_MODE_UNSET) { /* * If FIPS 140 is not enabled, any modules that are * waiting for validation must be released so they * can be verified. */ global_fips140_mode = FIPS140_MODE_DISABLED; kcf_activate(); cv_signal(&cv_fips140); } else if (fips140_info.fips140_op != FIPS140_DISABLE && fips140_info.fips140_op != FIPS140_ENABLE) { rv = CRYPTO_ARGUMENTS_BAD; } mutex_exit(&fips140_mode_lock); break; default: rv = CRYPTO_ARGUMENTS_BAD; } fips140_info.fips140_return_value = rv; if (copyout(&fips140_info, arg, sizeof (crypto_fips140_t)) != 0) error = EFAULT; return (error); }
void female(void *p, unsigned long which) { struct semaphore * whalematingMenuSemaphore = (struct semaphore *)p; (void)which; female_start(); // Implement this function lock_acquire(whaleLock); // Implement this function if (wchan_isempty(maleCv->cv_wchan) || wchan_isempty(matchMakerCv->cv_wchan)) { cv_wait(femaleCv,whaleLock); }else{ cv_signal(maleCv,whaleLock); cv_signal(matchMakerCv,whaleLock); } lock_release(whaleLock); female_end(); // 08 Feb 2012 : GWA : Please do not change this code. This is so that your // whalemating driver can return to the menu cleanly. V(whalematingMenuSemaphore); return; }
/*ARGSUSED*/ void ipmi_complete_request(struct ipmi_softc *sc, struct ipmi_request *req) { struct ipmi_device *dev; IPMI_LOCK_ASSERT(sc); if (req->ir_status == IRS_CANCELED) { ASSERT(req->ir_owner == NULL); ipmi_free_request(req); return; } req->ir_status = IRS_COMPLETED; /* * Anonymous requests (from inside the driver) always have a * waiter that we awaken. */ if (req->ir_owner == NULL) { cv_signal(&req->ir_cv); } else { dev = req->ir_owner; TAILQ_INSERT_TAIL(&dev->ipmi_completed_requests, req, ir_link); pollwakeup(dev->ipmi_pollhead, POLLIN | POLLRDNORM); dev->ipmi_status &= ~IPMI_BUSY; if (dev->ipmi_status & IPMI_CLOSING) cv_signal(&dev->ipmi_cv); } }
static void male(void *p, unsigned long which) { (void)p; kprintf("male whale #%ld starting\n", which); lock_acquire(lk_male); no_males++; if(no_females==0 || no_mm ==0 ) { ismwaiting=1; cv_wait(cv_male,lk_male); ismwaiting=0; } if(isfwaiting==0) cv_signal(cv_female,lk_female); if(ismmwaiting==0) cv_signal(cv_mm,lk_mm); kprintf("male whale #%ld ending\n", which); lock_release(lk_male); }
void matchmaker(void *p, unsigned long which) { struct semaphore * whalematingMenuSemaphore = (struct semaphore *)p; (void)which; matchmaker_start(); lock_acquire(wm_lock); while(1) { cv_wait(wm_mmcv,wm_lock); lock_acquire(wm_lock); if(males > 0 && females > 0) { kprintf("Ready to match!"); break; } } cv_signal(wm_mcv,wm_lock); cv_signal(wm_fcv,wm_lock); males--; females--; lock_release(wm_lock); matchmaker_end(); // 08 Feb 2012 : GWA : Please do not change this code. This is so that your // whalemating driver can return to the menu cleanly. V(whalematingMenuSemaphore); return; }
static void bcm2835_audio_callback(void *param, const VCHI_CALLBACK_REASON_T reason, void *msg_handle) { struct bcm2835_audio_info *sc = (struct bcm2835_audio_info *)param; int32_t status; uint32_t msg_len; VC_AUDIO_MSG_T m; if (reason != VCHI_CALLBACK_MSG_AVAILABLE) return; status = vchi_msg_dequeue(sc->vchi_handle, &m, sizeof m, &msg_len, VCHI_FLAGS_NONE); if (m.type == VC_AUDIO_MSG_TYPE_RESULT) { sc->msg_result = m.u.result.success; cv_signal(&sc->msg_avail_cv); } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) { struct bcm2835_audio_chinfo *ch = m.u.complete.cookie; int count = m.u.complete.count & 0xffff; int perr = (m.u.complete.count & (1U << 30)) != 0; ch->complete_pos = (ch->complete_pos + count) % sndbuf_getsize(ch->buffer); ch->free_buffer += count; if (perr || ch->free_buffer >= VCHIQ_AUDIO_PACKET_SIZE) { chn_intr(ch->channel); cv_signal(&sc->data_cv); } } else printf("%s: unknown m.type: %d\n", __func__, m.type); }
/* * sanitize the squeue etc. Some of the processing * needs to be done from inside the perimeter. */ void ip_squeue_clean_ring(ill_t *ill, ill_rx_ring_t *rx_ring) { squeue_t *sqp; ASSERT(ILL_MAC_PERIM_HELD(ill)); ASSERT(rx_ring != NULL); /* Just clean one squeue */ mutex_enter(&ill->ill_lock); if (rx_ring->rr_ring_state == RR_FREE) { mutex_exit(&ill->ill_lock); return; } rx_ring->rr_ring_state = RR_FREE_INPROG; sqp = rx_ring->rr_sqp; mutex_enter(&sqp->sq_lock); sqp->sq_state |= SQS_POLL_CLEANUP; cv_signal(&sqp->sq_worker_cv); mutex_exit(&ill->ill_lock); while (!(sqp->sq_state & SQS_POLL_CLEANUP_DONE)) cv_wait(&sqp->sq_ctrlop_done_cv, &sqp->sq_lock); sqp->sq_state &= ~SQS_POLL_CLEANUP_DONE; ASSERT(!(sqp->sq_state & (SQS_POLL_THR_CONTROL | SQS_WORKER_THR_CONTROL | SQS_POLL_QUIESCE_DONE | SQS_POLL_THR_QUIESCED))); cv_signal(&sqp->sq_worker_cv); mutex_exit(&sqp->sq_lock); /* * Move the squeue to sqset_global_list[0] which holds the set of * squeues not bound to any cpu. Note that the squeue is still * considered bound to an ill as long as SQS_ILL_BOUND is set. */ mutex_enter(&sqset_lock); ip_squeue_set_move(sqp, sqset_global_list[0]); mutex_exit(&sqset_lock); /* * CPU going offline can also trigger a move of the squeue to the * unbound set sqset_global_list[0]. However the squeue won't be * recycled for the next use as long as the SQS_ILL_BOUND flag * is set. Hence we clear the SQS_ILL_BOUND flag only towards the * end after the move. */ mutex_enter(&sqp->sq_lock); sqp->sq_state &= ~SQS_ILL_BOUND; mutex_exit(&sqp->sq_lock); mutex_enter(&ill->ill_lock); rx_ring->rr_ring_state = RR_FREE; mutex_exit(&ill->ill_lock); }
static void catlock(void * unusedpointer, unsigned long catnumber) { int i; for (i = 0; i < TIMES_EATING; i++) { lock_acquire(openbowl_lock); while (bowl1->who != FREE && bowl2->who != FREE) { cv_wait(free_bowl, openbowl_lock); } while (bowl1->who == MOUSE || bowl2->who == MOUSE) { cv_wait(free_bowl, openbowl_lock); } if (bowl1->who == FREE) { //[lock bowl 1, eat from bowl 1], release bowl1_lock, release openbowl_lock, cv_signal(free_bowl, openbowl_lock), increment cats[catnumber]; lock_acquire(bowl_1); bowl1->who = CAT; lock_release(openbowl_lock); lock_eat("cat", catnumber, 1, i); bowl1->who = FREE; cv_signal(free_bowl, openbowl_lock); lock_release(bowl_1); } else if (bowl2 ->who == FREE) { //[lock bowl 2, eat from bowl 2], change who==null, release bowl2_lock, release openbowl_lock, cv_signal(free_bowl, openbowl_lock), increment cats[catnumber]; lock_acquire(bowl_2); bowl2->who = CAT; lock_release(openbowl_lock); lock_eat("cat", catnumber, 2, i); bowl2->who = FREE; cv_signal(free_bowl, openbowl_lock); lock_release(bowl_2); } else { i--; //error shouldn't have made it here! } // check to see if everyone's eaten the same number of times. If I am more, cv_wait(fair_share), else cv_broadcast(fair_share) } /* * Avoid unused variable warnings. */ (void) unusedpointer; (void) catnumber; }
void _sx_xunlock(struct sx *sx, const char *file, int line) { _sx_assert(sx, SX_XLOCKED, file, line); mtx_lock(sx->sx_lock); MPASS(sx->sx_cnt == -1); WITNESS_UNLOCK(&sx->sx_object, LOP_EXCLUSIVE, file, line); /* Release. */ sx->sx_cnt++; sx->sx_xholder = NULL; /* * Wake up waiters if there are any. Give precedence to slock waiters. */ if (sx->sx_shrd_wcnt > 0) cv_broadcast(&sx->sx_shrd_cv); else if (sx->sx_excl_wcnt > 0) cv_signal(&sx->sx_excl_cv); LOCK_LOG_LOCK("XUNLOCK", &sx->sx_object, 0, 0, file, line); mtx_unlock(sx->sx_lock); }
ACPI_STATUS AcpiOsSignalSemaphore(ACPI_SEMAPHORE Handle, UINT32 Units) { struct acpi_sema *as = (struct acpi_sema *)Handle; UINT32 i; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); if (as == NULL || Units == 0) return_ACPI_STATUS (AE_BAD_PARAMETER); mtx_lock(&as->as_lock); ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "return %u units to %s, units %u, waiters %d\n", Units, as->as_name, as->as_units, as->as_waiters)); if (as->as_maxunits != ACPI_NO_UNIT_LIMIT && (as->as_maxunits < Units || as->as_maxunits - Units < as->as_units)) { ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "exceeded max units %u\n", as->as_maxunits)); mtx_unlock(&as->as_lock); return_ACPI_STATUS (AE_LIMIT); } as->as_units += Units; if (as->as_waiters > 0 && ACPISEM_AVAIL(as, Units)) for (i = 0; i < Units; i++) cv_signal(&as->as_cv); mtx_unlock(&as->as_lock); return_ACPI_STATUS (AE_OK); }
void male(void *p, unsigned long which) { struct semaphore * whalematingMenuSemaphore = (struct semaphore *)p; //(void)which; male_start(); // Implement this function //extern int male_tail, female_head, female_tail; //extern unsigned long male_pop[]; //extern struct lock *pop_lock; //extern struct cv *maker_cv; lock_acquire(pop_lock); male_pop[male_tail++] = which; if(female_head != female_tail) cv_signal(maker_cv, pop_lock); lock_release(pop_lock); male_end(); // 08 Feb 2012 : GWA : Please do not change this code. This is so that your // whalemating driver can return to the menu cleanly. V(whalematingMenuSemaphore); return; }
/* * issue a empty sync op to help empty the delta/log map or the log */ static void top_issue_sync(void *arg) { ufsvfs_t *ufsvfsp = (ufsvfs_t *)arg; ml_unit_t *ul = (ml_unit_t *)ufsvfsp->vfs_log; mt_map_t *mtm = ul->un_logmap; int error = 0; if ((curthread->t_flag & T_DONTBLOCK) == 0) curthread->t_flag |= T_DONTBLOCK; top_begin_sync(ufsvfsp, TOP_COMMIT_ASYNC, 0, &error); if (!error) { top_end_sync(ufsvfsp, &error, TOP_COMMIT_ASYNC, 0); } /* * If we are a taskq thread, decrement mtm_taskq_sync_count and * wake up the thread waiting on the mtm_cv if the mtm_taskq_sync_count * hits zero. */ if (taskq_member(system_taskq, curthread)) { mutex_enter(&mtm->mtm_lock); mtm->mtm_taskq_sync_count--; if (mtm->mtm_taskq_sync_count == 0) { cv_signal(&mtm->mtm_cv); } mutex_exit(&mtm->mtm_lock); } }
int sys_ksem_post(struct thread *td, struct ksem_post_args *uap) { struct file *fp; struct ksem *ks; int error; error = ksem_get(td, uap->id, CAP_SEM_POST, &fp); if (error) return (error); ks = fp->f_data; mtx_lock(&sem_lock); #ifdef MAC error = mac_posixsem_check_post(td->td_ucred, fp->f_cred, ks); if (error) goto err; #endif if (ks->ks_value == SEM_VALUE_MAX) { error = EOVERFLOW; goto err; } ++ks->ks_value; if (ks->ks_waiters > 0) cv_signal(&ks->ks_cv); error = 0; vfs_timestamp(&ks->ks_ctime); err: mtx_unlock(&sem_lock); fdrop(fp, td); return (error); }
/* * Same as above, but forces the page to be detached from the object * and go into free pool. */ void sf_ext_free_nocache(void *arg1, void *arg2) { struct sf_buf *sf = arg1; struct sendfile_sync *sfs = arg2; vm_page_t pg = sf_buf_page(sf); sf_buf_free(sf); vm_page_lock(pg); if (vm_page_unwire(pg, PQ_NONE)) { vm_object_t obj; /* Try to free the page, but only if it is cheap to. */ if ((obj = pg->object) == NULL) vm_page_free(pg); else if (!vm_page_xbusied(pg) && VM_OBJECT_TRYWLOCK(obj)) { vm_page_free(pg); VM_OBJECT_WUNLOCK(obj); } else vm_page_deactivate(pg); } vm_page_unlock(pg); if (sfs != NULL) { mtx_lock(&sfs->mtx); KASSERT(sfs->count > 0, ("Sendfile sync botchup count == 0")); if (--sfs->count == 0) cv_signal(&sfs->cv); mtx_unlock(&sfs->mtx); } }
static void trim_thread(void *arg) { spa_t *spa = arg; zio_t *zio; for (;;) { mutex_enter(&spa->spa_trim_lock); if (spa->spa_trim_thread == NULL) { spa->spa_trim_thread = curthread; cv_signal(&spa->spa_trim_cv); mutex_exit(&spa->spa_trim_lock); thread_exit(); } cv_wait(&spa->spa_trim_cv, &spa->spa_trim_lock); mutex_exit(&spa->spa_trim_lock); zio = zio_root(spa, NULL, NULL, ZIO_FLAG_CANFAIL); spa_config_enter(spa, SCL_STATE, FTAG, RW_READER); trim_map_commit(spa, zio, spa->spa_root_vdev); (void) zio_wait(zio); trim_map_commit_done(spa, spa->spa_root_vdev); spa_config_exit(spa, SCL_STATE, FTAG); } }
static int ipmi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) { if (cmd != DDI_DETACH) return (DDI_FAILURE); if (ipmi_found == B_FALSE) return (DDI_SUCCESS); if (!list_is_empty(&dev_list)) return (DDI_FAILURE); /* poke the taskq so that it can terminate */ sc->ipmi_detaching = 1; cv_signal(&sc->ipmi_request_added); ddi_remove_minor_node(dip, NULL); ipmi_dip = NULL; taskq_destroy(sc->ipmi_kthread); list_destroy(&dev_list); id_space_destroy(minor_ids); ipmi_attached = B_FALSE; return (DDI_SUCCESS); }
void _sx_sunlock(struct sx *sx, const char *file, int line) { _sx_assert(sx, SX_SLOCKED, file, line); mtx_lock(sx->sx_lock); WITNESS_UNLOCK(&sx->sx_object, 0, file, line); /* Release. */ sx->sx_cnt--; /* * If we just released the last shared lock, wake any waiters up, giving * exclusive lockers precedence. In order to make sure that exclusive * lockers won't be blocked forever, don't wake shared lock waiters if * there are exclusive lock waiters. */ if (sx->sx_excl_wcnt > 0) { if (sx->sx_cnt == 0) cv_signal(&sx->sx_excl_cv); } else if (sx->sx_shrd_wcnt > 0) cv_broadcast(&sx->sx_shrd_cv); LOCK_LOG_LOCK("SUNLOCK", &sx->sx_object, 0, 0, file, line); mtx_unlock(sx->sx_lock); }
void taskq_dispatch_ent(taskq_t *tq, task_func_t func, void *arg, uint_t flags, taskq_ent_t *t) { ASSERT(func != NULL); ASSERT(!(tq->tq_flags & TASKQ_DYNAMIC)); /* * Mark it as a prealloc'd task. This is important * to ensure that we don't free it later. */ t->tqent_flags |= TQENT_FLAG_PREALLOC; /* * Enqueue the task to the underlying queue. */ mutex_enter(&tq->tq_lock); if (flags & TQ_FRONT) { t->tqent_next = tq->tq_task.tqent_next; t->tqent_prev = &tq->tq_task; } else { t->tqent_next = &tq->tq_task; t->tqent_prev = tq->tq_task.tqent_prev; } t->tqent_next->tqent_prev = t; t->tqent_prev->tqent_next = t; t->tqent_func = func; t->tqent_arg = arg; cv_signal(&tq->tq_dispatch_cv); mutex_exit(&tq->tq_lock); }
static void trim_thread(void *arg) { spa_t *spa = arg; zio_t *zio; #ifdef _KERNEL (void) snprintf(curthread->td_name, sizeof(curthread->td_name), "trim %s", spa_name(spa)); #endif for (;;) { mutex_enter(&spa->spa_trim_lock); if (spa->spa_trim_thread == NULL) { spa->spa_trim_thread = curthread; cv_signal(&spa->spa_trim_cv); mutex_exit(&spa->spa_trim_lock); thread_exit(); } (void) cv_timedwait(&spa->spa_trim_cv, &spa->spa_trim_lock, hz * trim_max_interval); mutex_exit(&spa->spa_trim_lock); zio = zio_root(spa, NULL, NULL, ZIO_FLAG_CANFAIL); spa_config_enter(spa, SCL_STATE, FTAG, RW_READER); trim_map_commit(spa, zio, spa->spa_root_vdev); (void) zio_wait(zio); trim_map_commit_done(spa, spa->spa_root_vdev); spa_config_exit(spa, SCL_STATE, FTAG); } }
static int bcm2835_audio_detach(device_t dev) { int r; struct bcm2835_audio_info *sc; sc = pcm_getdevinfo(dev); /* Stop worker thread */ BCM2835_AUDIO_LOCK(sc); sc->worker_state = WORKER_STOPPING; cv_signal(&sc->worker_cv); /* Wait for thread to exit */ while (sc->worker_state != WORKER_STOPPED) cv_wait_sig(&sc->worker_cv, &sc->lock); BCM2835_AUDIO_UNLOCK(sc); r = pcm_unregister(dev); if (r) return r; mtx_destroy(&sc->lock); cv_destroy(&sc->worker_cv); bcm2835_audio_release(sc); free(sc, M_DEVBUF); return 0; }
/* * Wake up to wake_threads threads that are blocked on the futex at memid. */ static int futex_wake(memid_t *memid, int wake_threads) { fwaiter_t *fwp, *next; int index; int ret = 0; index = HASH_FUNC(memid); mutex_enter(&futex_hash_lock[index]); for (fwp = futex_hash[index]; fwp && ret < wake_threads; fwp = next) { next = fwp->fw_next; if (MEMID_EQUAL(&fwp->fw_memid, memid)) { futex_hashout(fwp); fwp->fw_woken = 1; cv_signal(&fwp->fw_cv); ret++; } } mutex_exit(&futex_hash_lock[index]); return (ret); }
void *thread_srv_fun(void *arg) { int inx; Msg *msg; arg = arg; // touch for (inx = 0; inx < loop; inx++) { cv_wait(&cv_srv); msg = msg_queue_remove(&mutex_srv, &queue_srv); assert(msg != NULL); if (!nocopy) { if (csize) memcpy(recv_buffer2, msg->cbuf, csize); if (dsize) memcpy(recv_buffer, msg->dbuf, dsize); } if (csize) free(msg->cbuf); if (dsize) free(msg->dbuf); if (bidir) { if (csize) memcpy(send_buffer2, recv_buffer2, csize); if (dsize) memcpy(send_buffer, recv_buffer, dsize); } msg_queue_add(&mutex_cli, &queue_cli, msg); cv_signal(&cv_cli); } return NULL; }
/* * Restart polling etc. Needs to be inside the perimeter to * prevent races. */ void ip_squeue_restart_ring(ill_t *ill, ill_rx_ring_t *rx_ring) { squeue_t *sqp; ASSERT(ILL_MAC_PERIM_HELD(ill)); ASSERT(rx_ring != NULL); sqp = rx_ring->rr_sqp; mutex_enter(&sqp->sq_lock); /* * Handle change in number of rings between the quiesce and * restart operations by checking for a previous quiesce before * attempting a restart. */ if (!(sqp->sq_state & SQS_POLL_QUIESCE_DONE)) { mutex_exit(&sqp->sq_lock); return; } sqp->sq_state |= SQS_POLL_RESTART; cv_signal(&sqp->sq_worker_cv); while (!(sqp->sq_state & SQS_POLL_RESTART_DONE)) cv_wait(&sqp->sq_ctrlop_done_cv, &sqp->sq_lock); sqp->sq_state &= ~SQS_POLL_RESTART_DONE; mutex_exit(&sqp->sq_lock); }
static int bcmchan_trigger(kobj_t obj, void *data, int go) { struct bcm2835_audio_chinfo *ch = data; struct bcm2835_audio_info *sc = ch->parent; if (!PCMTRIG_COMMON(go)) return (0); bcm2835_audio_lock(sc); switch (go) { case PCMTRIG_START: bcm2835_audio_start(ch); ch->playback_state = PLAYBACK_STARTING; /* wakeup worker thread */ cv_signal(&sc->data_cv); break; case PCMTRIG_STOP: case PCMTRIG_ABORT: ch->playback_state = 1; bcm2835_audio_stop(ch); break; default: break; } bcm2835_audio_unlock(sc); return 0; }
/* * Detach mapped page and release resources back to the system. Called * by mbuf(9) code when last reference to a page is freed. */ void sf_ext_free(void *arg1, void *arg2) { struct sf_buf *sf = arg1; struct sendfile_sync *sfs = arg2; vm_page_t pg = sf_buf_page(sf); sf_buf_free(sf); vm_page_lock(pg); /* * Check for the object going away on us. This can * happen since we don't hold a reference to it. * If so, we're responsible for freeing the page. */ if (vm_page_unwire(pg, PQ_INACTIVE) && pg->object == NULL) vm_page_free(pg); vm_page_unlock(pg); if (sfs != NULL) { mtx_lock(&sfs->mtx); KASSERT(sfs->count > 0, ("Sendfile sync botchup count == 0")); if (--sfs->count == 0) cv_signal(&sfs->cv); mtx_unlock(&sfs->mtx); } }
static int bcm2835_audio_detach(device_t dev) { int r; struct bcm2835_audio_info *sc; sc = pcm_getdevinfo(dev); /* Stop worker thread */ sc->unloading = 1; cv_signal(&sc->data_cv); r = pcm_unregister(dev); if (r) return r; mtx_destroy(&sc->vchi_lock); mtx_destroy(&sc->msg_avail_lock); cv_destroy(&sc->msg_avail_cv); mtx_destroy(&sc->data_lock); cv_destroy(&sc->data_cv); bcm2835_audio_release(sc); if (sc->lock) { snd_mtxfree(sc->lock); sc->lock = NULL; } free(sc, M_DEVBUF); return 0; }
taskqid_t taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t tqflags) { task_t *t; if (taskq_now) { func(arg); return (1); } mutex_enter(&tq->tq_lock); ASSERT(tq->tq_flags & TASKQ_ACTIVE); if ((t = task_alloc(tq, tqflags)) == NULL) { mutex_exit(&tq->tq_lock); return (0); } t->task_next = &tq->tq_task; t->task_prev = tq->tq_task.task_prev; t->task_next->task_prev = t; t->task_prev->task_next = t; t->task_func = func; t->task_arg = arg; cv_signal(&tq->tq_dispatch_cv); mutex_exit(&tq->tq_lock); return (1); }
/* * Stop the thread to setup switching mode. */ void vsw_setup_switching_stop(vsw_t *vswp) { kt_did_t tid = 0; /* * Signal the setup_switching thread to stop and wait until it stops. */ mutex_enter(&vswp->sw_thr_lock); if (vswp->sw_thread != NULL) { tid = vswp->sw_thread->t_did; vswp->sw_thr_flags |= VSW_SWTHR_STOP; cv_signal(&vswp->sw_thr_cv); } mutex_exit(&vswp->sw_thr_lock); if (tid != 0) thread_join(tid); (void) atomic_swap_32(&vswp->switching_setup_done, B_FALSE); vswp->mac_open_retries = 0; }
void nskernd_stop(void) { mutex_enter(&nskernd_lock); if (proc_nskernd == NULL) { nskernd_norun = 1; mutex_exit(&nskernd_lock); return; } while (nskernd_u_wait == 0) { nskernd_k_wait++; cv_wait(&nskernd_k_cv, &nskernd_lock); nskernd_k_wait--; if (proc_nskernd == NULL) { mutex_exit(&nskernd_lock); return; } } nskernd_kdata.command = NSKERND_STOP; nskernd_kdata.data1 = (uint64_t)1; /* kernel has done cleanup */ nskernd_cleanup(); cv_signal(&nskernd_u_cv); mutex_exit(&nskernd_lock); }
/* * iscsi_thread_send_wakeup - */ boolean_t iscsi_thread_send_wakeup( iscsi_thread_t *thread ) { boolean_t ret = B_FALSE; ASSERT(thread != NULL); ASSERT(thread->signature == SIG_ISCSI_THREAD); mutex_enter(&thread->mgnt.mtx); switch (thread->state) { case ISCSI_THREAD_STATE_STARTED: mutex_enter(&thread->sign.mtx); if (!(thread->sign.bitmap & ISCSI_THREAD_SIGNAL_WAKEUP)) { thread->sign.bitmap |= ISCSI_THREAD_SIGNAL_WAKEUP; cv_signal(&thread->sign.cdv); } mutex_exit(&thread->sign.mtx); ret = B_TRUE; break; default: break; } mutex_exit(&thread->mgnt.mtx); return (ret); }