rc_t VBlobHeaderReplace( VBlobHeader *targ, const VBlobHeader *src ) { BlobHeaders *parent; struct VBlobHeaderData *data; atomic32_t temp; if (src == NULL || targ == NULL) return RC(rcVDB, rcHeader, rcCopying, rcParam, rcNull); if (src->vt != &VBlobHeader_vt[1] || targ->vt != &VBlobHeader_vt[0]) return RC(rcVDB, rcHeader, rcCopying, rcParam, rcInvalid); if (atomic32_read(&targ->refcount) != 1) return RC(rcVDB, rcHeader, rcCopying, rcParam, rcInvalid); data = calloc(1, sizeof(*data)); if (data == NULL) return RC(rcVDB, rcHeader, rcCopying, rcMemory, rcExhausted); *data = *src->parent->data; atomic32_set(&data->refcount, 1); parent = (BlobHeaders *)targ->parent; VBlobHeaderDataRelease(parent->data); parent->data = data; atomic32_set(&temp, atomic32_read(&src->refcount)); *targ = *src; atomic32_set(&targ->refcount, atomic32_read(&temp)); targ->parent = parent; targ->vt = &VBlobHeader_vt[0]; return 0; }
inline int pkt_fifo_put(pkt_fifo_t *fifo, pkt_node_t *node) { uint32_t in = fifo->in; uint32_t size = fifo->size; uint32_t count = atomic32_read(&fifo->count); pkt_buf_t *pkt = fifo->pkt; if (unlikely(count >= size)) { applog(APP_LOG_LEVEL_DEBUG, APP_VPU_LOG_MASK_IO, "pkt_fifo_put count: %u, size: %u, fifo no space for new node\n", count, size); return -1; } memcpy(pkt[in].pkt, node->pkt, node->pkt_len); pkt[in].pkt_len = node->pkt_len; atomic32_add(&fifo->count, 1); in = in + 1; if (unlikely(in >= size)) { in = 0; } fifo->in = in; return 0; }
/* Sealed * ask if the queue has been closed off * meaning there will be no further push operations * * NB - if "self" is NULL, the return value is "true" * since a NULL queue cannot accept items via push */ LIB_EXPORT bool CC KQueueSealed ( const KQueue *self ) { QMSG ( "%s[%p] called\n", __func__, self ); if ( self != NULL ) return atomic32_read ( & self -> sealed ) != 0; return false; }
/* Hangup * has the program received a SIGHUP */ rc_t CC Hangup ( void ) { if ( atomic32_read ( & hangup ) == 0 ) return 0; LOGMSG ( klogInfo, "HANGUP...\n" ); return RC ( rcExe, rcProcess, rcExecuting, rcProcess, rcIncomplete ); }
/* Quitting * is the program supposed to exit */ rc_t CC Quitting ( void ) { if ( atomic32_read ( & quitting ) == 0 ) return 0; LOGMSG ( klogInfo, "EXITING..." ); return RC ( rcExe, rcProcess, rcExecuting, rcProcess, rcCanceled ); }
bool CC XTaskerIsDoneSet ( const struct XTasker * self ) { if ( self != NULL ) { return atomic32_read ( & ( self -> is_done ) ) != 0; } return false; } /* XTaskerIsDoneSet () */
bool CC XTaskerIsRunning ( const struct XTasker * self ) { if ( self != NULL ) { return atomic32_read ( & ( self -> is_run ) ) != 0; } return false; } /* XTaskerIsRunning () */
inline int pkt_fifo_get(pkt_fifo_t *fifo, pkt_node_t *node) { uint32_t out; uint32_t size; uint32_t count; pkt_buf_t *pkt; if (fifo == NULL || node == NULL) { applog(APP_LOG_LEVEL_DEBUG, APP_VPU_LOG_MASK_WORKER, "pkt_fifo_get fifo: %p, node: %p", fifo, node); return -1; //no data in fifo } out = fifo->out; size = fifo->size; count = atomic32_read(&fifo->count); pkt = fifo->pkt; if (count <= 0) { return -2; } if (unlikely(out >= size)) { applog(APP_LOG_LEVEL_DEBUG, APP_VPU_LOG_MASK_WORKER, "pkt_fifo_get out: %u, size: %u", out, size); return -3; } node->pkt = pkt[out].pkt; node->pkt_len = pkt[out].pkt_len; atomic32_sub(&fifo->count, 1); out = out + 1; if (unlikely(out >= size)) { out = 0; } fifo->out = out; return 0; }
/* Pop * pop an object from queue * * "item" [ OUT, OPAQUE* ] - return parameter for popped item * * "tm" [ IN, NULL OKAY ] - pointer to system specific timeout * structure. if the queue is empty, wait for indicated period * of time for an object to become available, or return status * code indicating a timeout. when NULL and queue is empty, * Pop will time out immediately and return status code. */ LIB_EXPORT rc_t CC KQueuePop ( KQueue *self, void **item, timeout_t *tm ) { rc_t rc; if ( item == NULL ) rc = RC ( rcCont, rcQueue, rcRemoving, rcParam, rcNull ); else { * item = NULL; if ( self == NULL ) rc = RC ( rcCont, rcQueue, rcRemoving, rcSelf, rcNull ); else { QMSG ( "%s[%p]: acquiring read lock ( %p )\n", __func__, self, self -> rl ); rc = KLockAcquire ( self -> rl ); if ( rc == 0 ) { QMSG ( "%s[%p]: waiting on read semaphore...\n", __func__, self ); rc = KSemaphoreTimedWait ( self -> rc, self -> rl, ( atomic32_read ( & self -> sealed ) != 0 ) ? NULL : tm ); QMSG ( "%s[%p]: ...done, rc = %R.\n", __func__, self, rc ); if ( rc == 0 ) { uint32_t r, idx; /* got an element */ QMSG ( "%s[%p]: asserting self -> read ( %u ) != self -> write ( %u )\n", __func__, self -> read, self -> write ); assert ( self -> read != self -> write ); /* read element */ r = self -> read & self -> imask; QMSG ( "%s[%p]: read index is %u, masked against 0x%x\n", __func__, self, r, self -> imask ); idx = r & self -> bmask; * item = self -> buffer [ idx ]; QMSG ( "%s[%p]: read item from buffer [ %u ], using mask 0x%x\n", __func__, self, idx, self -> bmask ); self -> buffer [ idx ] = NULL; self -> read = r + 1; QMSG ( "%s[%p]: unlocking read lock. ( %p )\n", __func__, self, self -> rl ); KLockUnlock ( self -> rl ); /* let write know there's a free slot available */ QMSG ( "%s[%p]: acquiring write lock ( %p )\n", __func__, self, self -> wl ); if ( KLockAcquire ( self -> wl ) == 0 ) { QMSG ( "%s[%p]: signaling write semaphore\n", __func__, self ); KSemaphoreSignal ( self -> wc ); QMSG ( "%s[%p]: unlocking write lock ( %p )\n", __func__, self, self -> wl ); KLockUnlock ( self -> wl ); } } else { QMSG ( "%s[%p]: unlocking read lock. ( %p )\n", __func__, self, self -> rl ); KLockUnlock ( self -> rl ); if ( atomic32_read ( & self -> sealed ) != 0 ) { switch ( ( int ) GetRCObject ( rc ) ) { case ( int ) rcTimeout: case ( int ) rcSemaphore: rc = RC ( rcCont, rcQueue, rcRemoving, rcData, rcDone ); QMSG ( "%s[%p]: resetting rc to %R\n", __func__, self, rc ); break; } } } } } } return rc; }
/* Push * add an object to the queue * * "item" [ IN, OPAQUE ] - pointer to item being queued * * "tm" [ IN, NULL OKAY ] - pointer to system specific timeout * structure. if the queue is full, wait for indicated period * of time for space to become available, or return status * code indicating a timeout. when NULL and queue is full, * Push will time out immediately and return status code. */ LIB_EXPORT rc_t CC KQueuePush ( KQueue *self, const void *item, timeout_t *tm ) { rc_t rc; if ( self == NULL ) return RC ( rcCont, rcQueue, rcInserting, rcSelf, rcNull ); if ( atomic32_read ( & self -> sealed ) != 0 ) { QMSG ( "%s[%p]: failed to insert into queue due to seal\n", __func__, self ); return RC ( rcCont, rcQueue, rcInserting, rcQueue, rcReadonly ); } if ( item == NULL ) return RC ( rcCont, rcQueue, rcInserting, rcParam, rcNull ); QMSG ( "%s[%p]: acquiring write lock ( %p )...\n", __func__, self, self -> wl ); rc = KLockAcquire ( self -> wl ); QMSG ( "%s[%p]: ...done, rc = %R\n", __func__, self, rc ); if ( rc == 0 ) { QMSG ( "%s[%p]: waiting on write semaphore...\n", __func__, self ); rc = KSemaphoreTimedWait ( self -> wc, self -> wl, tm ); QMSG ( "%s[%p]: ...done, rc = %R.\n", __func__, self, rc ); if ( rc == 0 ) { uint32_t w; /* re-check the seal */ if ( atomic32_read ( & self -> sealed ) != 0 ) { QMSG ( "%s[%p]: queue has been sealed\n", __func__, self ); /* not a disaster if semaphore not signaled */ QMSG ( "%s[%p]: signaling write semaphore\n", __func__, self ); KSemaphoreSignal ( self -> wc ); QMSG ( "%s[%p]: unlocking write lock\n", __func__, self ); KLockUnlock ( self -> wl ); QMSG ( "%s[%p]: failed to insert into queue due to seal\n", __func__, self ); return RC ( rcCont, rcQueue, rcInserting, rcQueue, rcReadonly ); } /* insert item */ w = self -> write & self -> imask; QMSG ( "%s[%p]: write index is %u, masked against 0x%x\n", __func__, self, w, self -> imask ); self -> buffer [ w & self -> bmask ] = ( void* ) item; QMSG ( "%s[%p]: inserted item into buffer [ %u ], using mask 0x%x\n", __func__, self, w & self -> bmask, self -> bmask ); self -> write = w + 1; QMSG ( "%s[%p]: unlocking write lock ( %p ).\n", __func__, self, self -> wl ); KLockUnlock ( self -> wl ); /* let listeners know about item */ QMSG ( "%s[%p]: acquiring read lock ( %p )\n", __func__, self, self -> rl ); if ( KLockAcquire ( self -> rl ) == 0 ) { QMSG ( "%s[%p]: signaling read semaphore\n", __func__, self ); KSemaphoreSignal ( self -> rc ); QMSG ( "%s[%p]: unlocking read lock ( %p )\n", __func__, self, self -> rl ); KLockUnlock ( self -> rl ); } } else { QMSG ( "%s[%p]: unlocking write lock ( %p ).\n", __func__, self, self -> wl ); KLockUnlock ( self -> wl ); if ( atomic32_read ( & self -> sealed ) != 0 ) { switch ( ( int ) GetRCObject ( rc ) ) { case ( int ) rcTimeout: case ( int ) rcSemaphore: rc = RC ( rcCont, rcQueue, rcInserting, rcQueue, rcReadonly ); QMSG ( "%s[%p]: resetting rc to %R\n", __func__, self, rc ); break; } } } } return rc; }