本文整理汇总了C++中cv_broadcast函数的典型用法代码示例。如果您正苦于以下问题:C++ cv_broadcast函数的具体用法?C++ cv_broadcast怎么用?C++ cv_broadcast使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了cv_broadcast函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: ehci_intr
/*
* ehci_intr:
*
* EHCI (EHCI) interrupt handling routine.
*/
uint_t
ehci_intr(caddr_t arg1, caddr_t arg2)
{
uint_t intr;
ehci_state_t *ehcip = (ehci_state_t *)arg1;
USB_DPRINTF_L3(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"ehci_intr: Interrupt occurred, arg1 0x%p arg2 0x%p", arg1, arg2);
/* Get the ehci global mutex */
mutex_enter(&ehcip->ehci_int_mutex);
/*
* Now process the actual ehci interrupt events that caused
* invocation of this ehci interrupt handler.
*/
intr = (Get_OpReg(ehci_status) & Get_OpReg(ehci_interrupt));
/* Update kstat values */
ehci_do_intrs_stats(ehcip, intr);
/*
* We could have gotten a spurious interrupts. If so, do not
* claim it. This is quite possible on some architectures
* where more than one PCI slots share the IRQs. If so, the
* associated driver's interrupt routine may get called even
* if the interrupt is not meant for them.
*
* By unclaiming the interrupt, the other driver gets chance
* to service its interrupt.
*/
if (!intr) {
mutex_exit(&ehcip->ehci_int_mutex);
return (DDI_INTR_UNCLAIMED);
}
/* Acknowledge the interrupt */
Set_OpReg(ehci_status, intr);
if (ehcip->ehci_hc_soft_state == EHCI_CTLR_ERROR_STATE) {
mutex_exit(&ehcip->ehci_int_mutex);
return (DDI_INTR_CLAIMED);
}
USB_DPRINTF_L3(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"Interrupt status 0x%x", intr);
/*
* If necessary broadcast that an interrupt has occured. This
* is only necessary during controller init.
*/
if (ehcip->ehci_flags & EHCI_CV_INTR) {
ehcip->ehci_flags &= ~EHCI_CV_INTR;
cv_broadcast(&ehcip->ehci_async_schedule_advance_cv);
}
/* Check for Frame List Rollover */
if (intr & EHCI_INTR_FRAME_LIST_ROLLOVER) {
USB_DPRINTF_L3(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"ehci_intr: Frame List Rollover");
ehci_handle_frame_list_rollover(ehcip);
/* VIA VT6202 looses EHCI_INTR_USB interrupts, workaround. */
if ((ehcip->ehci_vendor_id == PCI_VENDOR_VIA) &&
(ehci_vt62x2_workaround & EHCI_VIA_LOST_INTERRUPTS)) {
ehcip->ehci_missed_intr_sts |= EHCI_INTR_USB;
}
}
/* Check for Advance on Asynchronous Schedule */
if (intr & EHCI_INTR_ASYNC_ADVANCE) {
USB_DPRINTF_L3(PRINT_MASK_INTR, ehcip->ehci_log_hdl,
"ehci_intr: Asynchronous Schedule Advance Notification");
/* Disable async list advance interrupt */
Set_OpReg(ehci_interrupt,
(Get_OpReg(ehci_interrupt) & ~EHCI_INTR_ASYNC_ADVANCE));
/*
* Call cv_broadcast on every this interrupt to wakeup
* all the threads that are waiting the async list advance
* event.
*/
cv_broadcast(&ehcip->ehci_async_schedule_advance_cv);
}
/* Always process completed itds */
ehci_traverse_active_isoc_list(ehcip);
/*
* Check for any USB transaction completion notification. Also
* process any missed USB transaction completion interrupts.
//.........这里部分代码省略.........
开发者ID:andreiw,项目名称:polaris,代码行数:101,代码来源:ehci.c
示例2: drm_queue_vblank_event
int
drm_queue_vblank_event(struct drm_device *dev, int crtc,
union drm_wait_vblank *vblwait, struct drm_file *file_priv)
{
struct drm_pending_vblank_event *vev;
struct timeval now;
u_int seq;
vev = drm_calloc(1, sizeof(*vev));
if (vev == NULL)
return (ENOMEM);
vev->event.base.type = DRM_EVENT_VBLANK;
vev->event.base.length = sizeof(vev->event);
vev->event.user_data = vblwait->request.signal;
vev->base.event = &vev->event.base;
vev->base.file_priv = file_priv;
vev->base.destroy = (void (*) (struct drm_pending_event *))drm_free;
microtime(&now);
mtx_enter(&dev->event_lock);
if (file_priv->event_space < sizeof(vev->event)) {
mtx_leave(&dev->event_lock);
drm_free(vev);
return (ENOMEM);
}
seq = drm_vblank_count(dev, crtc);
file_priv->event_space -= sizeof(vev->event);
DPRINTF("%s: queueing event %d on crtc %d\n", __func__, seq, crtc);
if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) &&
(seq - vblwait->request.sequence) <= (1 << 23)) {
vblwait->request.sequence = seq + 1;
vblwait->reply.sequence = vblwait->request.sequence;
}
vev->event.sequence = vblwait->request.sequence;
if ((seq - vblwait->request.sequence) <= (1 << 23)) {
vev->event.tv_sec = now.tv_sec;
vev->event.tv_usec = now.tv_usec;
DPRINTF("%s: already passed, dequeuing: crtc %d, value %d\n",
__func__, crtc, seq);
drm_vblank_put(dev, crtc);
TAILQ_INSERT_TAIL(&file_priv->evlist, &vev->base, link);
#if !defined(__NetBSD__)
wakeup(&file_priv->evlist);
#else /* !defined(__NetBSD__) */
cv_broadcast(&file_priv->evlist_condvar);
#endif /* !defined(__NetBSD__) */
selwakeup(&file_priv->rsel);
} else {
TAILQ_INSERT_TAIL(&dev->vblank->vb_crtcs[crtc].vbl_events,
&vev->base, link);
}
mtx_leave(&dev->event_lock);
return (0);
}
开发者ID:adegroote,项目名称:netbsd-drmgem,代码行数:63,代码来源:drm_irq.c
示例3: traverse_visitbp
static int
traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp,
const blkptr_t *bp, const zbookmark_phys_t *zb)
{
zbookmark_phys_t czb;
int err = 0;
arc_buf_t *buf = NULL;
prefetch_data_t *pd = td->td_pfd;
boolean_t hard = td->td_flags & TRAVERSE_HARD;
switch (resume_skip_check(td, dnp, zb)) {
case RESUME_SKIP_ALL:
return (0);
case RESUME_SKIP_CHILDREN:
goto post;
case RESUME_SKIP_NONE:
break;
default:
ASSERT(0);
}
if (bp->blk_birth == 0) {
/*
* Since this block has a birth time of 0 it must be one of
* two things: a hole created before the
* SPA_FEATURE_HOLE_BIRTH feature was enabled, or a hole
* which has always been a hole in an object.
*
* If a file is written sparsely, then the unwritten parts of
* the file were "always holes" -- that is, they have been
* holes since this object was allocated. However, we (and
* our callers) can not necessarily tell when an object was
* allocated. Therefore, if it's possible that this object
* was freed and then its object number reused, we need to
* visit all the holes with birth==0.
*
* If it isn't possible that the object number was reused,
* then if SPA_FEATURE_HOLE_BIRTH was enabled before we wrote
* all the blocks we will visit as part of this traversal,
* then this hole must have always existed, so we can skip
* it. We visit blocks born after (exclusive) td_min_txg.
*
* Note that the meta-dnode cannot be reallocated.
*/
if (!send_holes_without_birth_time &&
(!td->td_realloc_possible ||
zb->zb_object == DMU_META_DNODE_OBJECT) &&
td->td_hole_birth_enabled_txg <= td->td_min_txg)
return (0);
} else if (bp->blk_birth <= td->td_min_txg) {
return (0);
}
if (pd != NULL && !pd->pd_exited && prefetch_needed(pd, bp)) {
uint64_t size = BP_GET_LSIZE(bp);
mutex_enter(&pd->pd_mtx);
ASSERT(pd->pd_bytes_fetched >= 0);
while (pd->pd_bytes_fetched < size && !pd->pd_exited)
cv_wait(&pd->pd_cv, &pd->pd_mtx);
pd->pd_bytes_fetched -= size;
cv_broadcast(&pd->pd_cv);
mutex_exit(&pd->pd_mtx);
}
if (BP_IS_HOLE(bp)) {
err = td->td_func(td->td_spa, NULL, bp, zb, dnp, td->td_arg);
if (err != 0)
goto post;
return (0);
}
if (td->td_flags & TRAVERSE_PRE) {
err = td->td_func(td->td_spa, NULL, bp, zb, dnp,
td->td_arg);
if (err == TRAVERSE_VISIT_NO_CHILDREN)
return (0);
if (err != 0)
goto post;
}
if (BP_GET_LEVEL(bp) > 0) {
arc_flags_t flags = ARC_FLAG_WAIT;
int i;
blkptr_t *cbp;
int epb = BP_GET_LSIZE(bp) >> SPA_BLKPTRSHIFT;
err = arc_read(NULL, td->td_spa, bp, arc_getbuf_func, &buf,
ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb);
if (err != 0)
goto post;
cbp = buf->b_data;
for (i = 0; i < epb; i++) {
SET_BOOKMARK(&czb, zb->zb_objset, zb->zb_object,
zb->zb_level - 1,
zb->zb_blkid * epb + i);
traverse_prefetch_metadata(td, &cbp[i], &czb);
}
/* recursively visitbp() blocks below this */
//.........这里部分代码省略.........
开发者ID:bahamas10,项目名称:openzfs,代码行数:101,代码来源:dmu_traverse.c
示例4: brelse
//.........这里部分代码省略.........
/*
* Clear the retry write flag if the buffer was written without
* error. The presence of B_DELWRI means the buffer has not yet
* been written and the presence of B_ERROR means that an error
* is still occurring.
*/
if ((bp->b_flags & (B_ERROR | B_DELWRI | B_RETRYWRI)) == B_RETRYWRI) {
bp->b_flags &= ~B_RETRYWRI;
}
/* Check for anomalous conditions */
if (bp->b_flags & (B_ERROR|B_NOCACHE)) {
if (bp->b_flags & B_NOCACHE) {
/* Don't add to the freelist. Destroy it now */
kmem_free(bp->b_un.b_addr, bp->b_bufsize);
sema_destroy(&bp->b_sem);
sema_destroy(&bp->b_io);
kmem_free(bp, sizeof (struct buf));
return;
}
/*
* If a write failed and we are supposed to retry write,
* don't toss the buffer. Keep it around and mark it
* delayed write in the hopes that it will eventually
* get flushed (and still keep the system running.)
*/
if ((bp->b_flags & (B_READ | B_RETRYWRI)) == B_RETRYWRI) {
bp->b_flags |= B_DELWRI;
/* keep fsflush from trying continuously to flush */
bp->b_start = ddi_get_lbolt();
} else
bp->b_flags |= B_AGE|B_STALE;
bp->b_flags &= ~B_ERROR;
bp->b_error = 0;
}
/*
* If delayed write is set then put in on the delayed
* write list instead of the free buffer list.
*/
index = bio_bhash(bp->b_edev, bp->b_blkno);
hmp = &hbuf[index].b_lock;
mutex_enter(hmp);
hp = &hbuf[index];
dp = (struct buf *)hp;
/*
* Make sure that the number of entries on this list are
* Zero <= count <= total # buffers
*/
ASSERT(hp->b_length >= 0);
ASSERT(hp->b_length < nbuf);
hp->b_length++; /* We are adding this buffer */
if (bp->b_flags & B_DELWRI) {
/*
* This buffer goes on the delayed write buffer list
*/
dp = (struct buf *)&dwbuf[index];
}
ASSERT(bp->b_bufsize > 0);
ASSERT(bp->b_bcount > 0);
ASSERT(bp->b_un.b_addr != NULL);
if (bp->b_flags & B_AGE) {
backp = &dp->av_forw;
(*backp)->av_back = bp;
bp->av_forw = *backp;
*backp = bp;
bp->av_back = dp;
} else {
backp = &dp->av_back;
(*backp)->av_forw = bp;
bp->av_back = *backp;
*backp = bp;
bp->av_forw = dp;
}
mutex_exit(hmp);
if (bfreelist.b_flags & B_WANTED) {
/*
* Should come here very very rarely.
*/
mutex_enter(&bfree_lock);
if (bfreelist.b_flags & B_WANTED) {
bfreelist.b_flags &= ~B_WANTED;
cv_broadcast(&bio_mem_cv);
}
mutex_exit(&bfree_lock);
}
bp->b_flags &= ~(B_WANTED|B_BUSY|B_ASYNC);
/*
* Don't let anyone get the buffer off the freelist before we
* release our hold on it.
*/
sema_v(&bp->b_sem);
}
开发者ID:MatiasNAmendola,项目名称:AuroraUX-SunOS,代码行数:101,代码来源:bio.c
示例5: dm2s_event_handler
/*
* dm2s_event_handler - Mailbox event handler.
*/
void
dm2s_event_handler(scf_event_t event, void *arg)
{
dm2s_t *dm2sp = (dm2s_t *)arg;
queue_t *rq;
ASSERT(dm2sp != NULL);
mutex_enter(&dm2sp->ms_lock);
if (!(dm2sp->ms_state & DM2S_MB_INITED)) {
/*
* Ignore all events if the state flag indicates that the
* mailbox not initialized, this may happen during the close.
*/
mutex_exit(&dm2sp->ms_lock);
DPRINTF(DBG_MBOX,
("Event(0x%X) received - Mailbox not inited\n", event));
return;
}
switch (event) {
case SCF_MB_CONN_OK:
/*
* Now the mailbox is ready to use, lets wake up
* any one waiting for this event.
*/
dm2sp->ms_state |= DM2S_MB_CONN;
cv_broadcast(&dm2sp->ms_wait);
DPRINTF(DBG_MBOX, ("Event received = CONN_OK\n"));
break;
case SCF_MB_MSG_DATA:
if (!DM2S_MBOX_READY(dm2sp)) {
DPRINTF(DBG_MBOX,
("Event(MSG_DATA) received - Mailbox not READY\n"));
break;
}
/*
* A message is available in the mailbox.
* Lets enable the read service procedure
* to receive this message.
*/
if (dm2sp->ms_rq != NULL) {
qenable(dm2sp->ms_rq);
}
DPRINTF(DBG_MBOX, ("Event received = MSG_DATA\n"));
break;
case SCF_MB_SPACE:
if (!DM2S_MBOX_READY(dm2sp)) {
DPRINTF(DBG_MBOX,
("Event(MB_SPACE) received - Mailbox not READY\n"));
break;
}
/*
* Now the mailbox is ready to transmit, lets
* schedule the write service procedure.
*/
if (dm2sp->ms_wq != NULL) {
qenable(dm2sp->ms_wq);
}
DPRINTF(DBG_MBOX, ("Event received = MB_SPACE\n"));
break;
case SCF_MB_DISC_ERROR:
dm2sp->ms_state |= DM2S_MB_DISC;
if (dm2sp->ms_state & DM2S_MB_CONN) {
/*
* If it was previously connected,
* then send a hangup message.
*/
rq = dm2sp->ms_rq;
if (rq != NULL) {
mutex_exit(&dm2sp->ms_lock);
/*
* Send a hangup message to indicate
* disconnect event.
*/
(void) putctl(rq, M_HANGUP);
DTRACE_PROBE1(dm2s_hangup, dm2s_t, dm2sp);
mutex_enter(&dm2sp->ms_lock);
}
} else {
/*
* Signal if the open is waiting for a
* connection.
*/
cv_broadcast(&dm2sp->ms_wait);
}
DPRINTF(DBG_MBOX, ("Event received = DISC_ERROR\n"));
break;
default:
cmn_err(CE_WARN, "Unexpected event received\n");
break;
}
mutex_exit(&dm2sp->ms_lock);
}
开发者ID:andreiw,项目名称:polaris,代码行数:98,代码来源:dm2s.c
示例6: syscall_stage_response
static int /* ERRNO if error, 0 if ok */
syscall_stage_response(
sam_mount_t *mp, /* pointer to mount entry. */
sam_fsstage_arg_t *stage, /* pointer to syscall stage response */
rval_t *rvp, /* returned value pointer */
cred_t *credp) /* credentials pointer. */
{
sam_handle_t *fhandle;
sam_node_t *ip;
vnode_t *vp;
int error;
int opened = 0;
rvp->r_val1 = 0;
fhandle = (sam_handle_t *)&stage->handle;
/* Is this inode still waiting for the stage? */
if ((error = sam_find_ino(mp->mi.m_vfsp, IG_EXISTS,
&fhandle->id, &ip))) {
return (ECANCELED);
}
vp = SAM_ITOV(ip);
if (stage->ret_err == EEXIST) {
/*
* Outstanding stage request already exists, wake up anyone
* waiting
*/
mutex_enter(&ip->rm_mutex);
if (ip->rm_wait) cv_broadcast(&ip->rm_cv);
mutex_exit(&ip->rm_mutex);
sam_rele_ino(ip);
return (0);
}
RW_LOCK_OS(&ip->inode_rwl, RW_WRITER);
if (ip->stage_pid > 0) {
/*
* Another stage is in progress. This can happen if the incore
* inode is released after a nowait stage for copy 1, then stage
* for copy 2.
*/
RW_UNLOCK_OS(&ip->inode_rwl, RW_WRITER);
sam_rele_ino(ip);
return (ECANCELED);
}
ip->flags.b.staging = 1; /* Reset for acquired incore inode */
ip->copy = 0;
ip->stage_off = fhandle->stage_off;
ip->stage_len = fhandle->stage_len;
if (stage->ret_err == 0) {
if ((!ip->di.status.b.offline &&
!(ip->di.rm.ui.flags & RM_DATA_VERIFY)) ||
!ip->di.arch_status ||
ip->stage_err) {
error = ECANCELED;
TRACE(T_SAM_IOCTL_STCAN, vp,
fhandle->id.ino, ip->stage_err,
ip->flags.bits);
} else {
offset_t cur_size = ip->size;
error = 0;
if (!fhandle->flags.b.stage_wait) {
/*
* Allocate file now for nowait stage.
*
* Assert
* permissions based on the uid of the handle
* structure, not the stager. Root can force
* staging, but users have to live with quotas.
*/
if (ip->di.blocks == 0) {
error =
sam_set_unit(ip->mp, &(ip->di));
}
if (error == 0) {
error = sam_map_block(ip, ip->stage_off,
ip->stage_len,
SAM_WRITE_BLOCK, NULL, credp);
ip->size = cur_size;
}
}
if (error == 0) {
/*
* Simulate the open because we don't
* have the path.
*/
if ((error = sam_get_fd(vp,
&rvp->r_val1)) == 0) {
if (vp->v_type == VREG) {
atomic_add_32(&vp->v_rdcnt, 1);
atomic_add_32(&vp->v_wrcnt, 1);
}
ip->stage_pid = SAM_CUR_PID;
ip->no_opens++;
opened = 1;
if (stage->directio) {
sam_set_directio(ip,
//.........这里部分代码省略.........
开发者ID:BackupTheBerlios,项目名称:samqfs,代码行数:101,代码来源:samscall.c
示例7: traverse_visitbp
static int
traverse_visitbp(traverse_data_t *td, const dnode_phys_t *dnp,
arc_buf_t *pbuf, blkptr_t *bp, const zbookmark_t *zb)
{
zbookmark_t czb;
int err = 0, lasterr = 0;
arc_buf_t *buf = NULL;
prefetch_data_t *pd = td->td_pfd;
boolean_t hard = td->td_flags & TRAVERSE_HARD;
boolean_t pause = B_FALSE;
switch (resume_skip_check(td, dnp, zb)) {
case RESUME_SKIP_ALL:
return (0);
case RESUME_SKIP_CHILDREN:
goto post;
case RESUME_SKIP_NONE:
break;
default:
ASSERT(0);
}
if (BP_IS_HOLE(bp)) {
err = td->td_func(td->td_spa, NULL, NULL, pbuf, zb, dnp,
td->td_arg);
return (err);
}
if (bp->blk_birth <= td->td_min_txg)
return (0);
if (pd && !pd->pd_exited &&
((pd->pd_flags & TRAVERSE_PREFETCH_DATA) ||
BP_GET_TYPE(bp) == DMU_OT_DNODE || BP_GET_LEVEL(bp) > 0)) {
mutex_enter(&pd->pd_mtx);
ASSERT(pd->pd_blks_fetched >= 0);
while (pd->pd_blks_fetched == 0 && !pd->pd_exited)
cv_wait(&pd->pd_cv, &pd->pd_mtx);
pd->pd_blks_fetched--;
cv_broadcast(&pd->pd_cv);
mutex_exit(&pd->pd_mtx);
}
if (td->td_flags & TRAVERSE_PRE) {
err = td->td_func(td->td_spa, NULL, bp, pbuf, zb, dnp,
td->td_arg);
if (err == TRAVERSE_VISIT_NO_CHILDREN)
return (0);
if (err == ERESTART)
pause = B_TRUE; /* handle pausing at a common point */
if (err != 0)
goto post;
}
if (BP_GET_LEVEL(bp) > 0) {
uint32_t flags = ARC_WAIT;
int i;
blkptr_t *cbp;
int epb = BP_GET_LSIZE(bp) >> SPA_BLKPTRSHIFT;
err = dsl_read(NULL, td->td_spa, bp, pbuf,
arc_getbuf_func, &buf,
ZIO_PRIORITY_ASYNC_READ, ZIO_FLAG_CANFAIL, &flags, zb);
if (err)
return (err);
/* recursively visitbp() blocks below this */
cbp = buf->b_data;
for (i = 0; i < epb; i++, cbp++) {
SET_BOOKMARK(&czb, zb->zb_objset, zb->zb_object,
zb->zb_level - 1,
zb->zb_blkid * epb + i);
err = traverse_visitbp(td, dnp, buf, cbp, &czb);
if (err) {
if (!hard)
break;
lasterr = err;
}
}
} else if (BP_GET_TYPE(bp) == DMU_OT_DNODE) {
开发者ID:BjoKaSH,项目名称:zfs-osx,代码行数:80,代码来源:dmu_traverse.c
示例8: rtems_bsd_sim_set_state_and_notify
static void
rtems_bsd_sim_set_state_and_notify(struct cam_sim *sim, enum bsd_sim_state state)
{
sim->state = state;
cv_broadcast(&sim->state_changed);
}
开发者ID:vidhoonv,项目名称:rtems-libbsd,代码行数:6,代码来源:rtems-bsd-cam.c
示例9: crypto_unregister_provider
/*
* This routine is used to notify the framework when a provider is being
* removed. Hardware providers call this routine in their detach routines.
* Software providers call this routine in their _fini() routine.
*/
int
crypto_unregister_provider(crypto_kcf_provider_handle_t handle)
{
uint_t mech_idx;
kcf_provider_desc_t *desc;
kcf_prov_state_t saved_state;
/* lookup provider descriptor */
if ((desc = kcf_prov_tab_lookup((crypto_provider_id_t)handle)) == NULL)
return (CRYPTO_UNKNOWN_PROVIDER);
mutex_enter(&desc->pd_lock);
/*
* Check if any other thread is disabling or removing
* this provider. We return if this is the case.
*/
if (desc->pd_state >= KCF_PROV_DISABLED) {
mutex_exit(&desc->pd_lock);
/* Release reference held by kcf_prov_tab_lookup(). */
KCF_PROV_REFRELE(desc);
return (CRYPTO_BUSY);
}
saved_state = desc->pd_state;
desc->pd_state = KCF_PROV_REMOVED;
if (saved_state == KCF_PROV_BUSY) {
/*
* The per-provider taskq threads may be waiting. We
* signal them so that they can start failing requests.
*/
cv_broadcast(&desc->pd_resume_cv);
}
if (desc->pd_prov_type == CRYPTO_SW_PROVIDER) {
/*
* Check if this provider is currently being used.
* pd_irefcnt is the number of holds from the internal
* structures. We add one to account for the above lookup.
*/
if (desc->pd_refcnt > desc->pd_irefcnt + 1) {
desc->pd_state = saved_state;
mutex_exit(&desc->pd_lock);
/* Release reference held by kcf_prov_tab_lookup(). */
KCF_PROV_REFRELE(desc);
/*
* The administrator presumably will stop the clients
* thus removing the holds, when they get the busy
* return value. Any retry will succeed then.
*/
return (CRYPTO_BUSY);
}
}
mutex_exit(&desc->pd_lock);
if (desc->pd_prov_type != CRYPTO_SW_PROVIDER) {
remove_provider(desc);
}
if (desc->pd_prov_type != CRYPTO_LOGICAL_PROVIDER) {
/* remove the provider from the mechanisms tables */
for (mech_idx = 0; mech_idx < desc->pd_mech_list_count;
mech_idx++) {
kcf_remove_mech_provider(
desc->pd_mechanisms[mech_idx].cm_mech_name, desc);
}
}
/* remove provider from providers table */
if (kcf_prov_tab_rem_provider((crypto_provider_id_t)handle) !=
CRYPTO_SUCCESS) {
/* Release reference held by kcf_prov_tab_lookup(). */
KCF_PROV_REFRELE(desc);
return (CRYPTO_UNKNOWN_PROVIDER);
}
delete_kstat(desc);
if (desc->pd_prov_type == CRYPTO_SW_PROVIDER) {
/* Release reference held by kcf_prov_tab_lookup(). */
KCF_PROV_REFRELE(desc);
/*
* Wait till the existing requests complete.
*/
mutex_enter(&desc->pd_lock);
while (desc->pd_state != KCF_PROV_FREED)
cv_wait(&desc->pd_remove_cv, &desc->pd_lock);
mutex_exit(&desc->pd_lock);
} else {
/*
* Wait until requests that have been sent to the provider
* complete.
*/
mutex_enter(&desc->pd_lock);
//.........这里部分代码省略.........
开发者ID:MarkGavalda,项目名称:zfs,代码行数:101,代码来源:kcf_spi.c
示例10: proc_exit
//.........这里部分代码省略.........
/*
* Clear the lwp directory and the lwpid hash table
* now that /proc can't bother us any more.
* We free the memory below, after dropping p->p_lock.
*/
lwpdir = p->p_lwpdir;
lwpdir_sz = p->p_lwpdir_sz;
tidhash = p->p_tidhash;
tidhash_sz = p->p_tidhash_sz;
ret_tidhash = p->p_ret_tidhash;
p->p_lwpdir = NULL;
p->p_lwpfree = NULL;
p->p_lwpdir_sz = 0;
p->p_tidhash = NULL;
p->p_tidhash_sz = 0;
p->p_ret_tidhash = NULL;
/*
* If the process has context ops installed, call the exit routine
* on behalf of this last remaining thread. Normally exitpctx() is
* called during thread_exit() or lwp_exit(), but because this is the
* last thread in the process, we must call it here. By the time
* thread_exit() is called (below), the association with the relevant
* process has been lost.
*
* We also free the context here.
*/
if (p->p_pctx) {
kpreempt_disable();
exitpctx(p);
kpreempt_enable();
freepctx(p, 0);
}
/*
* curthread's proc pointer is changed to point to the 'sched'
* process for the corresponding zone, except in the case when
* the exiting process is in fact a zsched instance, in which
* case the proc pointer is set to p0. We do so, so that the
* process still points at the right zone when we call the VN_RELE()
* below.
*
* This is because curthread's original proc pointer can be freed as
* soon as the child sends a SIGCLD to its parent. We use zsched so
* that for user processes, even in the final moments of death, the
* process is still associated with its zone.
*/
if (p != t->t_procp->p_zone->zone_zsched)
t->t_procp = t->t_procp->p_zone->zone_zsched;
else
t->t_procp = &p0;
mutex_exit(&p->p_lock);
if (!evaporate) {
p->p_pidflag &= ~CLDPEND;
sigcld(p, sqp);
} else {
/*
* Do what sigcld() would do if the disposition
* of the SIGCHLD signal were set to be ignored.
*/
cv_broadcast(&p->p_srwchan_cv);
freeproc(p);
}
mutex_exit(&pidlock);
/*
* We don't release u_cdir and u_rdir until SZOMB is set.
* This protects us against dofusers().
*/
if (cdir)
VN_RELE(cdir);
if (rdir)
VN_RELE(rdir);
if (cwd)
refstr_rele(cwd);
/*
* task_rele() may ultimately cause the zone to go away (or
* may cause the last user process in a zone to go away, which
* signals zsched to go away). So prior to this call, we must
* no longer point at zsched.
*/
t->t_procp = &p0;
kmem_free(lwpdir, lwpdir_sz * sizeof (lwpdir_t));
kmem_free(tidhash, tidhash_sz * sizeof (tidhash_t));
while (ret_tidhash != NULL) {
ret_tidhash_t *next = ret_tidhash->rth_next;
kmem_free(ret_tidhash->rth_tidhash,
ret_tidhash->rth_tidhash_sz * sizeof (tidhash_t));
kmem_free(ret_tidhash, sizeof (*ret_tidhash));
ret_tidhash = next;
}
thread_exit();
/* NOTREACHED */
}
开发者ID:apprisi,项目名称:illumos-gate,代码行数:101,代码来源:exit.c
示例11: usb_process
/*------------------------------------------------------------------------*
* usb_process
*
* This function is the USB process dispatcher.
*------------------------------------------------------------------------*/
static void
usb_process(void *arg)
{
struct usb_process *up = arg;
struct usb_proc_msg *pm;
struct thread *td;
/* in case of attach error, check for suspended */
USB_THREAD_SUSPEND_CHECK();
/* adjust priority */
td = curthread;
thread_lock(td);
sched_prio(td, up->up_prio);
thread_unlock(td);
mtx_lock(up->up_mtx);
up->up_curtd = td;
while (1) {
if (up->up_gone)
break;
/*
* NOTE to reimplementors: dequeueing a command from the
* "used" queue and executing it must be atomic, with regard
* to the "up_mtx" mutex. That means any attempt to queue a
* command by another thread must be blocked until either:
*
* 1) the command sleeps
*
* 2) the command returns
*
* Here is a practical example that shows how this helps
* solving a problem:
*
* Assume that you want to set the baud rate on a USB serial
* device. During the programming of the device you don't
* want to receive nor transmit any data, because it will be
* garbage most likely anyway. The programming of our USB
* device takes 20 milliseconds and it needs to call
* functions that sleep.
*
* Non-working solution: Before we queue the programming
* command, we stop transmission and reception of data. Then
* we queue a programming command. At the end of the
* programming command we enable transmission and reception
* of data.
*
* Problem: If a second programming command is queued while the
* first one is sleeping, we end up enabling transmission
* and reception of data too early.
*
* Working solution: Before we queue the programming command,
* we stop transmission and reception of data. Then we queue
* a programming command. Then we queue a second command
* that only enables transmission and reception of data.
*
* Why it works: If a second programming command is queued
* while the first one is sleeping, then the queueing of a
* second command to enable the data transfers, will cause
* the previous one, which is still on the queue, to be
* removed from the queue, and re-inserted after the last
* baud rate programming command, which then gives the
* desired result.
*/
pm = TAILQ_FIRST(&up->up_qhead);
if (pm) {
DPRINTF("Message pm=%p, cb=%p (enter)\n",
pm, pm->pm_callback);
(pm->pm_callback) (pm);
if (pm == TAILQ_FIRST(&up->up_qhead)) {
/* nothing changed */
TAILQ_REMOVE(&up->up_qhead, pm, pm_qentry);
pm->pm_qentry.tqe_prev = NULL;
}
DPRINTF("Message pm=%p (leave)\n", pm);
continue;
}
/* end if messages - check if anyone is waiting for sync */
if (up->up_dsleep) {
up->up_dsleep = 0;
cv_broadcast(&up->up_drain);
}
up->up_msleep = 1;
cv_wait(&up->up_cv, up->up_mtx);
}
up->up_ptr = NULL;
//.........这里部分代码省略.........
开发者ID:ChristosKa,项目名称:freebsd,代码行数:101,代码来源:usb_process.c
示例12: segkmem_alloc_lp
//.........这里部分代码省略.........
ASSERT(asize >= size);
if (lpthrt != 0) {
/* try to update the throttle value */
lpthrt = atomic_inc_ulong_nv(lpthrtp);
if (lpthrt >= segkmem_lpthrottle_max) {
lpthrt = atomic_cas_ulong(lpthrtp, lpthrt,
segkmem_lpthrottle_max / 4);
}
/*
* when we get above throttle start do an exponential
* backoff at trying large pages and reaping
*/
if (lpthrt > segkmem_lpthrottle_start &&
!ISP2(lpthrt)) {
lpcb->allocs_throttled++;
lpthrt--;
if (ISP2(lpthrt))
kmem_reap();
return (segkmem_alloc(vmp, size, vmflag));
}
}
if (!(vmflag & VM_NOSLEEP) &&
segkmem_heaplp_quantum >= (8 * kmemlp_qnt) &&
vmem_size(kmem_lp_arena, VMEM_FREE) <= kmemlp_qnt &&
asize < (segkmem_heaplp_quantum - kmemlp_qnt)) {
/*
* we are low on free memory in kmem_lp_arena
* we let only one guy to allocate heap_lp
* quantum size chunk that everybody is going to
* share
*/
mutex_enter(&lpcb->lp_lock);
if (lpcb->lp_wait) {
/* we are not the first one - wait */
cv_wait(&lpcb->lp_cv, &lpcb->lp_lock);
if (vmem_size(kmem_lp_arena, VMEM_FREE) <
kmemlp_qnt) {
doalloc = 0;
}
} else if (vmem_size(kmem_lp_arena, VMEM_FREE) <=
kmemlp_qnt) {
/*
* we are the first one, make sure we import
* a large page
*/
if (asize == kmemlp_qnt)
asize += kmemlp_qnt;
dowakeup = 1;
lpcb->lp_wait = 1;
}
mutex_exit(&lpcb->lp_lock);
}
/*
* VM_ABORT flag prevents sleeps in vmem_xalloc when
* large pages are not available. In that case this allocation
* attempt will fail and we will retry allocation with small
* pages. We also do not want to panic if this allocation fails
* because we are going to retry.
*/
if (doalloc) {
addr = vmem_alloc(kmem_lp_arena, asize,
(vmflag | VM_ABORT) & ~VM_PANIC);
if (dowakeup) {
mutex_enter(&lpcb->lp_lock);
ASSERT(lpcb->lp_wait != 0);
lpcb->lp_wait = 0;
cv_broadcast(&lpcb->lp_cv);
mutex_exit(&lpcb->lp_lock);
}
}
if (addr != NULL) {
*sizep = asize;
*lpthrtp = 0;
return (addr);
}
if (vmflag & VM_NOSLEEP)
lpcb->nosleep_allocs_failed++;
else
lpcb->sleep_allocs_failed++;
lpcb->alloc_bytes_failed += size;
/* if large page throttling is not started yet do it */
if (segkmem_use_lpthrottle && lpthrt == 0) {
lpthrt = atomic_cas_ulong(lpthrtp, lpthrt, 1);
}
}
return (segkmem_alloc(vmp, size, vmflag));
}
开发者ID:bahamas10,项目名称:openzfs,代码行数:101,代码来源:seg_kmem.c
示例13: atabusconfig_thread
//.........这里部分代码省略.........
aprint_error_dev(atabus_sc->sc_dev,
"SATA port multiplier not supported\n");
/* no problems going on, all drives are ATA_DRIVET_NONE */
#endif
}
/*
* Attach an ATAPI bus, if needed.
*/
KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL);
for (i = 0; i < chp->ch_ndrives && chp->atapibus == NULL; i++) {
if (chp->ch_drive[i].drive_type == ATA_DRIVET_ATAPI) {
#if NATAPIBUS > 0
(*atac->atac_atapibus_attach)(atabus_sc);
#else
/*
* Fake the autoconfig "not configured" message
*/
aprint_normal("atapibus at %s not configured\n",
device_xname(atac->atac_dev));
chp->atapibus = NULL;
s = splbio();
for (i = 0; i < chp->ch_ndrives; i++) {
if (chp->ch_drive[i].drive_type == ATA_DRIVET_ATAPI)
chp->ch_drive[i].drive_type = ATA_DRIVET_NONE;
}
splx(s);
#endif
break;
}
}
for (i = 0; i < chp->ch_ndrives; i++) {
struct ata_device adev;
if (chp->ch_drive[i].drive_type != ATA_DRIVET_ATA &&
chp->ch_drive[i].drive_type != ATA_DRIVET_OLD) {
continue;
}
if (chp->ch_drive[i].drv_softc != NULL)
continue;
memset(&adev, 0, sizeof(struct ata_device));
adev.adev_bustype = atac->atac_bustype_ata;
adev.adev_channel = chp->ch_channel;
adev.adev_openings = 1;
adev.adev_drv_data = &chp->ch_drive[i];
chp->ch_drive[i].drv_softc = config_found_ia(atabus_sc->sc_dev,
"ata_hl", &adev, ataprint);
if (chp->ch_drive[i].drv_softc != NULL) {
ata_probe_caps(&chp->ch_drive[i]);
} else {
s = splbio();
chp->ch_drive[i].drive_type = ATA_DRIVET_NONE;
splx(s);
}
}
/* now that we know the drives, the controller can set its modes */
if (atac->atac_set_modes) {
(*atac->atac_set_modes)(chp);
ata_print_modes(chp);
}
#if NATARAID > 0
if (atac->atac_cap & ATAC_CAP_RAID) {
for (i = 0; i < chp->ch_ndrives; i++) {
if (chp->ch_drive[i].drive_type == ATA_DRIVET_ATA) {
ata_raid_check_component(
chp->ch_drive[i].drv_softc);
}
}
}
#endif /* NATARAID > 0 */
/*
* reset drive_flags for unattached devices, reset state for attached
* ones
*/
s = splbio();
for (i = 0; i < chp->ch_ndrives; i++) {
if (chp->ch_drive[i].drive_type == ATA_DRIVET_PM)
continue;
if (chp->ch_drive[i].drv_softc == NULL) {
chp->ch_drive[i].drive_flags = 0;
chp->ch_drive[i].drive_type = ATA_DRIVET_NONE;
} else
chp->ch_drive[i].state = 0;
}
splx(s);
mutex_enter(&atabus_qlock);
TAILQ_REMOVE(&atabus_initq_head, atabus_initq, atabus_initq);
cv_broadcast(&atabus_qcv);
mutex_exit(&atabus_qlock);
free(atabus_initq, M_DEVBUF);
ata_delref(chp);
config_pending_decr(atac->atac_dev);
kthread_exit(0);
}
开发者ID:goroutines,项目名称:rumprun,代码行数:101,代码来源:ata.c
示例14: atabusconfig
static void
atabusconfig(struct atabus_softc *atabus_sc)
{
struct ata_channel *chp = atabus_sc->sc_chan;
struct atac_softc *atac = chp->ch_atac;
struct atabus_initq *atabus_initq = NULL;
int i, s, error;
/* we are in the atabus's thread context */
s = splbio();
chp->ch_flags |= ATACH_TH_RUN;
splx(s);
/*
* Probe for the drives attached to controller, unless a PMP
* is already known
*/
/* XXX for SATA devices we will power up all drives at once */
if (chp->ch_satapmp_nports == 0)
(*atac->atac_probe)(chp);
if (chp->ch_ndrives >= 2) {
ATADEBUG_PRINT(("atabusattach: ch_drive_type 0x%x 0x%x\n",
chp->ch_drive[0].drive_type, chp->ch_drive[1].drive_type),
DEBUG_PROBE);
}
/* next operations will occurs in a separate thread */
s = splbio();
chp->ch_flags &= ~ATACH_TH_RUN;
splx(s);
/* Make sure the devices probe in atabus order to avoid jitter. */
mutex_enter(&atabus_qlock);
for (;;) {
atabus_initq = TAILQ_FIRST(&atabus_initq_head);
if (atabus_initq->atabus_sc == atabus_sc)
break;
cv_wait(&atabus_qcv, &atabus_qlock);
}
mutex_exit(&atabus_qlock);
/* If no drives, abort here */
if (chp->ch_drive == NULL)
goto out;
KASSERT(chp->ch_ndrives == 0 || chp->ch_drive != NULL);
for (i = 0; i < chp->ch_ndrives; i++)
if (chp->ch_drive[i].drive_type != ATA_DRIVET_NONE)
break;
if (i == chp->ch_ndrives)
goto out;
/* Shortcut in case we've been shutdown */
if (chp->ch_flags & ATACH_SHUTDOWN)
goto out;
if ((error = kthread_create(PRI_NONE, 0, NULL, atabusconfig_thread,
atabus_sc, &atabus_cfg_lwp,
"%scnf", device_xname(atac->atac_dev))) != 0)
aprint_error_dev(atac->atac_dev,
"unable to create config thread: error %d\n", error);
return;
out:
mutex_enter(&atabus_qlock);
TAILQ_REMOVE(&atabus_initq_head, atabus_initq, atabus_initq);
cv_broadcast(&atabus_qcv);
mutex_exit(&atabus_qlock);
free(atabus_initq, M_DEVBUF);
ata_delref(chp);
config_pending_decr(atac->atac_dev);
}
开发者ID:goroutines,项目名称:rumprun,代码行数:75,代码来源:ata.c
示例15: instructor
/**
* instructor - Piazza answer-editing thread.
*
* Each instructor thread should, for NCYCLES iterations, choose a random
* Piazza question and then update the answer. The answer should always
* consist of a lowercase alphabetic character repeated 10 times, e.g.,
*
* "aaaaaaaaaa"
*
* and each update should increment all ten characters (cycling back to a's
* from z's if a question is updated enough times).
*
* After each update, (including the first update, in which you should create
* the question and initialize the answer to all a's), the instructor should
* print the answer string using piazza_print().
*
* TODO: Implement this.
*/
static void
instructor(void *p, unsigned long which)
{
(void)p;
(void)which;
int i, n;
char letter, *pos;
for (i = 0; i < NCYCLES; ++i) {
// Choose a random Piazza question.
n = random() % NANSWERS;
// If first instructor to see the question, initalize answers
lock_acquire(creation_lock[n]);
if (questions[n] == NULL) {
questions[n] = kmalloc(sizeof(struct piazza_question));
questions[n]->mutex = lock_create("mutex");
questions[n]->readerQ = cv_create("readerQ");
questions[n]->writerQ = cv_create("writerQ");
questions[n]->readers = 0;
questions[n]->writers = 0;
questions[n]->active_writer = 0;
const char *answer = "aaaaaaaaaa"; //TODO: have const here?
questions[n]->pq_answer = kstrdup(answer);
lock_release(creation_lock[n]);
// Print submitted answer
piazza_print(n);
}
// Not the first instructor
else{
lock_release(creation_lock[n]);
// Set up writer lock
lock_acquire(questions[n]->mutex);
questions[n]->writers++;
while(!((questions[n]->readers == 0) && (questions[n]->active_writer == 0)))
cv_wait(questions[n]->writerQ, questions[n]->mutex);
questions[n]->active_writer++;
lock_release(questions[n]->mutex);
/* Start write */
pos = questions[n]->pq_answer;
letter = *pos;
// Update answer
if(letter != 'z'){
while (*(pos) == letter) {
(*pos)++;
pos++;
}
}
// Loop answer back to A's
else{
while (*(pos) == letter) {
*pos = 'a';
pos++;
}
}
// Print submitted answer
piazza_print(n);
/* End write */
// Clean up writer lock
lock_acquire(questions[n]->mutex);
questions[n]->active_writer--;
questions[n]->writers--;
if(questions[n]->writers==0)
cv_broadcast(questions[n]->readerQ, questions[n]->mutex);
else
cv_signal(questions[n]->writerQ, questions[n]->mutex);
lock_release(questions[n]->mutex);
}
}
// Exiting thread
//.........这里部分代码省略.........
开发者ID:MagicZou,项目名称:petrel-os,代码行数:101,代码来源:piazza.c
示例16: crypto_provider_notification
/*
* This routine is used to notify the framework that the state of
* a cryptographic provider has changed. Valid state codes are:
*
* CRYPTO_PROVIDER_READY
* The provider indicates that it can process more requests. A provider
* will notify with this event if it previously has notified us with a
* CRYPTO_PROVIDER_BUSY.
*
* CRYPTO_PROVIDER_BUSY
* The provider can not take more requests.
*
* CRYPTO_PROVIDER_FAILED
* The provider encountered an internal error. The framework will not
* be sending any more requests to the provider. The provider may notify
* with a CRYPTO_PROVIDER_READY, if it is able to recover from the error.
*
* This routine can be called from user or interrupt context.
*/
void
crypto_provider_notification(crypto_kcf_provider_handle_t handle, uint_t state)
{
kcf_provider_desc_t *pd;
/* lookup the provider from the given handle */
if ((pd = kcf_prov_tab_lookup((crypto_provider_id_t)handle)) == NULL)
return;
mutex_enter(&pd->pd_lock);
if (pd->pd_state <= KCF_PROV_VERIFICATION_FAILED)
goto out;
if (pd->pd_prov_type == CRYPTO_LOGICAL_PROVIDER) {
cmn_err(CE_WARN, "crypto_provider_notification: "
"logical provider (%x) ignored\n", handle);
goto out;
}
switch (state) {
case CRYPTO_PROVIDER_READY:
switch (pd->pd_state) {
case KCF_PROV_BUSY:
pd->pd_state = KCF_PROV_READY;
/*
* Signal the per-provider taskq threads that they
* can start submitting requests.
*/
cv_broadcast(&pd->pd_resume_cv);
break;
case KCF_PROV_FAILED:
/*
* The provider recovered from the error. Let us
* use it now.
*/
pd->pd_state = KCF_PROV_READY;
break;
default:
break;
}
break;
case CRYPTO_PROVIDER_BUSY:
switch (pd->pd_state) {
case KCF_PROV_READY:
pd->pd_state = KCF_PROV_BUSY;
break;
default:
break;
}
break;
case CRYPTO_PROVIDER_FAILED:
/*
* We note the failure and return. The per-provider taskq
* threads check this flag and start failing the
* requests, if it is set. See process_req_hwp() for details.
*/
switch (pd->pd_state) {
case KCF_PROV_READY:
pd->pd_state = KCF_PROV_FAILED;
break;
case KCF_PROV_BUSY:
pd->pd_state = KCF_PROV_FAILED;
/*
* The per-provider taskq threads may be waiting. We
* signal them so that they can start failing requests.
*/
cv_broadcast(&pd->pd_resume_cv);
break;
default:
break;
}
break;
default:
break;
}
out:
mutex_exit(&pd->pd_lock);
//.........这里部分代码省略.........
开发者ID:MarkGavalda,项目名称:zfs,代码行数:101,代码来源:kcf_spi.c
|
请发表评论