/* * ss_read_buffer_static() - static version of ss_read_buffer. * This is to enable inlining in the for loop in ss_read_all_buffer. */ static void ss_read_buffer_static(SSCB *ss, CHAN *ch, boolean dirty_only) { char *val = valPtr(ch,ss); char *buf = bufPtr(ch); ptrdiff_t nch = chNum(ch); /* Must take dbCount for db channels, else we overwrite elements we didn't get */ size_t count = ch->dbch ? ch->dbch->dbCount : ch->count; size_t var_size = ch->type->size * count; if (!ss->dirty[nch] && dirty_only) return; epicsMutexMustLock(ch->varLock); DEBUG("ss %s: before read %s", ss->ssName, ch->varName); print_channel_value(DEBUG, ch, val); memcpy(val, buf, var_size); if (ch->dbch) { /* structure copy */ ch->dbch->ssMetaData[ssNum(ss)] = ch->dbch->metaData; } DEBUG("ss %s: after read %s", ss->ssName, ch->varName); print_channel_value(DEBUG, ch, val); ss->dirty[nch] = FALSE; epicsMutexUnlock(ch->varLock); }
/* * ss_wakeup() -- wake up each state set that is waiting on this event * based on the current event mask; eventNum = 0 means wake all state sets. */ void ss_wakeup(PROG *sp, unsigned eventNum) { unsigned nss; /* Check event number against mask for all state sets: */ for (nss = 0; nss < sp->numSS; nss++) { SSCB *ss = sp->ss + nss; epicsMutexMustLock(sp->lock); /* If event bit in mask is set, wake that state set */ DEBUG("ss_wakeup: eventNum=%d, mask=%u, state set=%d\n", eventNum, ss->mask? *ss->mask : 0, (int)ssNum(ss)); if (eventNum == 0 || (ss->mask && bitTest(ss->mask, eventNum))) { DEBUG("ss_wakeup: waking up state set=%d\n", (int)ssNum(ss)); epicsEventSignal(ss->syncSem); /* wake up ss thread */ } epicsMutexUnlock(sp->lock); } }
/* * Atomically test event flag against outstanding events, then clear it * and return whether it was set. */ epicsShareFunc boolean epicsShareAPI seq_efTestAndClear(SS_ID ss, EV_ID ev_flag) { SPROG *sp = ss->sprog; boolean isSet; assert(ev_flag > 0 && ev_flag <= ss->sprog->numEvFlags); epicsMutexMustLock(sp->programLock); isSet = bitTest(sp->evFlags, ev_flag); bitClear(sp->evFlags, ev_flag); DEBUG("efTestAndClear: ev_flag=%d, isSet=%d, ss=%d\n", ev_flag, isSet, (int)ssNum(ss)); if (sp->options & OPT_SAFE) ss_read_buffer_selective(sp, ss, ev_flag); epicsMutexUnlock(sp->programLock); return isSet; }