/** * @brief Reads from a dedicated packet buffer. * * @param[in] udp pointer to a @p stm32_usb_descriptor_t * @param[in] iqp pointer to an @p InputQueue object * @param[in] n maximum number of bytes to copy. This value must * not exceed the maximum packet size for this endpoint. * * @notapi */ static void usb_packet_read_to_queue(stm32_usb_descriptor_t *udp, InputQueue *iqp, size_t n) { size_t nhw; uint32_t *pmap= USB_ADDR2PTR(udp->RXADDR0); nhw = n / 2; while (nhw > 0) { uint32_t w; w = *pmap++; *iqp->q_wrptr++ = (uint8_t)w; if (iqp->q_wrptr >= iqp->q_top) iqp->q_wrptr = iqp->q_buffer; *iqp->q_wrptr++ = (uint8_t)(w >> 8); if (iqp->q_wrptr >= iqp->q_top) iqp->q_wrptr = iqp->q_buffer; nhw--; } /* Last byte for odd numbers.*/ if ((n & 1) != 0) { *iqp->q_wrptr++ = (uint8_t)*pmap; if (iqp->q_wrptr >= iqp->q_top) iqp->q_wrptr = iqp->q_buffer; } /* Updating queue.*/ chSysLockFromIsr(); iqp->q_counter += n; while (notempty(&iqp->q_waiting)) chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_OK; chSysUnlockFromIsr(); }
static void usb_next_ctrl_msg(struct urb *urb, struct st5481_adapter *adapter) { struct st5481_ctrl *ctrl = &adapter->ctrl; int r_index; if (test_and_set_bit(0, &ctrl->busy)) { return; } if ((r_index = fifo_remove(&ctrl->msg_fifo.f)) < 0) { test_and_clear_bit(0, &ctrl->busy); return; } urb->setup_packet = (unsigned char *)&ctrl->msg_fifo.data[r_index]; DBG(1, "request=0x%02x,value=0x%04x,index=%x", ((struct ctrl_msg *)urb->setup_packet)->dr.bRequest, ((struct ctrl_msg *)urb->setup_packet)->dr.wValue, ((struct ctrl_msg *)urb->setup_packet)->dr.wIndex); urb->dev = adapter->usb_dev; SUBMIT_URB(urb, GFP_ATOMIC); }
/** * @brief Signals one thread that is waiting on the condition variable. * @post This function does not reschedule so a call to a rescheduling * function must be performed before unlocking the kernel. Note that * interrupt handlers always reschedule on exit so an explicit * reschedule must not be performed in ISRs. * * @param[in] cp pointer to the @p CondVar structure * * @iclass */ void chCondSignalI(CondVar *cp) { chDbgCheck(cp != NULL, "chCondSignalI"); if (notempty(&cp->c_queue)) chSchReadyI(fifo_remove(&cp->c_queue))->p_u.rdymsg = RDY_OK; }
/** * @brief Performs atomic signal and wait operations on two semaphores. * @pre The configuration option @p CH_USE_SEMSW must be enabled in order * to use this function. * * @param[in] sps pointer to a @p Semaphore structure to be signaled * @param[in] spw pointer to a @p Semaphore structure to be wait on * @return A message specifying how the invoking thread has been * released from the semaphore. * @retval RDY_OK if the thread has not stopped on the semaphore or the * semaphore has been signaled. * @retval RDY_RESET if the semaphore has been reset using @p chSemReset(). * * @api */ msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) { msg_t msg; chDbgCheck((sps != NULL) && (spw != NULL), "chSemSignalWait"); chDbgAssert(((sps->s_cnt >= 0) && isempty(&sps->s_queue)) || ((sps->s_cnt < 0) && notempty(&sps->s_queue)), "chSemSignalWait(), #1", "inconsistent semaphore"); chDbgAssert(((spw->s_cnt >= 0) && isempty(&spw->s_queue)) || ((spw->s_cnt < 0) && notempty(&spw->s_queue)), "chSemSignalWait(), #2", "inconsistent semaphore"); chSysLock(); if (++sps->s_cnt <= 0) chSchReadyI(fifo_remove(&sps->s_queue))->p_u.rdymsg = RDY_OK; if (--spw->s_cnt < 0) { Thread *ctp = currp; sem_insert(ctp, &spw->s_queue); ctp->p_u.wtobjp = spw; chSchGoSleepS(THD_STATE_WTSEM); msg = ctp->p_u.rdymsg; } else { chSchRescheduleS(); msg = RDY_OK; } chSysUnlock(); return msg; }
/** * @brief Resets an input queue. * @details All the data in the input queue is erased and lost, any waiting * thread is resumed with status @p Q_RESET. * @note A reset operation can be used by a low level driver in order to * obtain immediate attention from the high level layers. * * @param[in] iqp pointer to an @p InputQueue structure * * @iclass */ void chIQResetI(InputQueue *iqp) { chDbgCheckClassI(); iqp->q_rdptr = iqp->q_wrptr = iqp->q_buffer; iqp->q_counter = 0; while (notempty(&iqp->q_waiting)) chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_RESET; }
/** * @brief Resets an output queue. * @details All the data in the output queue is erased and lost, any waiting * thread is resumed with status @p Q_RESET. * @note A reset operation can be used by a low level driver in order to * obtain immediate attention from the high level layers. * * @param[in] oqp pointer to an @p OutputQueue structure * * @iclass */ void chOQResetI(OutputQueue *oqp) { chDbgCheckClassI(); oqp->q_rdptr = oqp->q_wrptr = oqp->q_buffer; oqp->q_counter = chQSizeI(oqp); while (notempty(&oqp->q_waiting)) chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = Q_RESET; }
/** * Pop error from queue * @param context - scpi context * @return error number */ int16_t SCPI_ErrorPop(scpi_t * context) { int16_t result = 0; fifo_remove(&context->error_queue, &result); SCPI_ErrorEmitEmpty(context); return result; }
/** * Pop error from queue * @param context - scpi context * @param error * @return */ scpi_bool_t SCPI_ErrorPop(scpi_t * context, scpi_error_t * error) { if (!error || !context) return FALSE; SCPI_ERROR_SETVAL(error, 0, NULL); fifo_remove(&context->error_queue, error); SCPI_ErrorEmitEmpty(context); return TRUE; }
/** * @brief Signals one thread that is waiting on the condition variable. * * @param[in] cp pointer to the @p CondVar structure * * @api */ void chCondSignal(CondVar *cp) { chDbgCheck(cp != NULL, "chCondSignal"); chSysLock(); if (notempty(&cp->c_queue)) chSchWakeupS(fifo_remove(&cp->c_queue), RDY_OK); chSysUnlock(); }
/** * @brief Signals all threads that are waiting on the condition variable. * @post This function does not reschedule so a call to a rescheduling * function must be performed before unlocking the kernel. Note that * interrupt handlers always reschedule on exit so an explicit * reschedule must not be performed in ISRs. * * @param[in] cp pointer to the @p CondVar structure * * @iclass */ void chCondBroadcastI(CondVar *cp) { chDbgCheck(cp != NULL, "chCondBroadcastI"); /* Empties the condition variable queue and inserts all the Threads into the ready list in FIFO order. The wakeup message is set to @p RDY_RESET in order to make a chCondBroadcast() detectable from a chCondSignal().*/ while (cp->c_queue.p_next != (void *)&cp->c_queue) chSchReadyI(fifo_remove(&cp->c_queue))->p_u.rdymsg = RDY_RESET; }
int dogechat_plugin_end (struct t_dogechat_plugin *plugin) { /* make C compiler happy */ (void) plugin; fifo_remove (); return DOGECHAT_RC_OK; }
scpi_bool_t SCPIParser::fifo_add(fifo_t * fifo, int16_t value) { /* FIFO full? */ if (fifo->wr == ((fifo->rd + fifo->size) % (fifo->size + 1))) { fifo_remove(fifo, NULL); } fifo->data[fifo->wr] = value; fifo->wr = (fifo->wr + 1) % (fifo->size + 1); return TRUE; }
/** * @brief Suspends the thread and waits for an incoming message. * @post After receiving a message the function @p chMsgGet() must be * called in order to retrieve the message and then @p chMsgRelease() * must be invoked in order to acknowledge the reception and send * the answer. * @note If the message is a pointer then you can assume that the data * pointed by the message is stable until you invoke @p chMsgRelease() * because the sending thread is suspended until then. * * @return A reference to the thread carrying the message. * * @api */ Thread *chMsgWait(void) { Thread *tp; chSysLock(); if (!chMsgIsPendingI(currp)) chSchGoSleepS(THD_STATE_WTMSG); tp = fifo_remove(&currp->p_msgqueue); tp->p_state = THD_STATE_SNDMSG; chSysUnlock(); return tp; }
/** * Clear error queue * @param context - scpi context */ void SCPI_ErrorClear(scpi_t * context) { #if USE_DEVICE_DEPENDENT_ERROR_INFORMATION scpi_error_t error; while (fifo_remove(&context->error_queue, &error)) { SCPIDEFINE_free(&context->error_info_heap, error.device_dependent_info, false); } #endif fifo_clear(&context->error_queue); SCPI_ErrorEmitEmpty(context); }
void chSchDoRescheduleBehind(void) { Thread *otp; otp = currp; /* Picks the first thread from the ready queue and makes it current.*/ setcurrp(fifo_remove(&rlist.r_queue)); currp->p_state = THD_STATE_CURRENT; otp->p_preempt = CH_TIME_QUANTUM; chSchReadyI(otp); chSysSwitch(currp, otp); }
void chSchGoSleepS(tstate_t newstate) { Thread *otp; (otp = currp)->p_state = newstate; #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif setcurrp(fifo_remove(&rlist.r_queue)); currp->p_state = THD_STATE_CURRENT; chDbgTrace(otp); chSysSwitchI(currp, otp); }
/** * @brief Performs a signal operation on a semaphore. * * @param[in] sp pointer to a @p Semaphore structure * * @api */ void chSemSignal(Semaphore *sp) { chDbgCheck(sp != NULL, "chSemSignal"); chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || ((sp->s_cnt < 0) && notempty(&sp->s_queue)), "chSemSignal(), #1", "inconsistent semaphore"); chSysLock(); if (++sp->s_cnt <= 0) chSchWakeupS(fifo_remove(&sp->s_queue), RDY_OK); chSysUnlock(); }
void fifo_config_change_file_enabled (const void *pointer, void *data, struct t_config_option *option) { /* make C compiler happy */ (void) pointer; (void) data; (void) option; fifo_remove (); if (weechat_config_boolean (fifo_config_file_enabled)) fifo_create (); }
static void testFifo() { scpi_fifo_t fifo; fifo_init(&fifo); int16_t value; fifo.size = 4; #define TEST_FIFO_COUNT(n) \ do { \ fifo_count(&fifo, &value); \ CU_ASSERT_EQUAL(value, n); \ } while(0) \ TEST_FIFO_COUNT(0); CU_ASSERT_TRUE(fifo_add(&fifo, 1)); TEST_FIFO_COUNT(1); CU_ASSERT_TRUE(fifo_add(&fifo, 2)); TEST_FIFO_COUNT(2); CU_ASSERT_TRUE(fifo_add(&fifo, 3)); TEST_FIFO_COUNT(3); CU_ASSERT_TRUE(fifo_add(&fifo, 4)); TEST_FIFO_COUNT(4); CU_ASSERT_TRUE(fifo_add(&fifo, 1)); TEST_FIFO_COUNT(4); CU_ASSERT_EQUAL(fifo.data[0], 1); CU_ASSERT_EQUAL(fifo.data[1], 2); CU_ASSERT_EQUAL(fifo.data[2], 3); CU_ASSERT_EQUAL(fifo.data[3], 4); CU_ASSERT_TRUE(fifo_remove(&fifo, &value)); CU_ASSERT_EQUAL(value, 2); TEST_FIFO_COUNT(3); CU_ASSERT_TRUE(fifo_add(&fifo, 5)); TEST_FIFO_COUNT(4); CU_ASSERT_TRUE(fifo_remove(&fifo, &value)); CU_ASSERT_EQUAL(value, 3); TEST_FIFO_COUNT(3); CU_ASSERT_TRUE(fifo_remove(&fifo, &value)); CU_ASSERT_EQUAL(value, 4); TEST_FIFO_COUNT(2); CU_ASSERT_TRUE(fifo_remove(&fifo, &value)); CU_ASSERT_EQUAL(value, 1); TEST_FIFO_COUNT(1); CU_ASSERT_TRUE(fifo_remove(&fifo, &value)); CU_ASSERT_EQUAL(value, 5); TEST_FIFO_COUNT(0); CU_ASSERT_FALSE(fifo_remove(&fifo, &value)); TEST_FIFO_COUNT(0); }
void chSchGoSleepS(tstate_t newstate) { Thread *otp; chDbgCheckClassS(); (otp = currp)->p_state = newstate; #if CH_TIME_QUANTUM > 0 /* The thread is renouncing its remaining time slices so it will have a new time quantum when it will wakeup.*/ otp->p_preempt = CH_TIME_QUANTUM; #endif setcurrp(fifo_remove(&rlist.r_queue)); currp->p_state = THD_STATE_CURRENT; chSysSwitch(currp, otp); }
/** * Pop error from queue * @param context - scpi context * @return error number */ int16_t SCPI_ErrorPop(scpi_t * context) { int16_t result = 0; /* * // FreeRTOS * if (pdFALSE == xQueueReceive((xQueueHandle)context->error_queue, &result, 0)) { * result = 0; * } */ /* basic FIFO */ fifo_remove((fifo_t *)context->error_queue, &result); return result; }
/** * @brief Adds the specified value to the semaphore counter. * @post This function does not reschedule so a call to a rescheduling * function must be performed before unlocking the kernel. Note that * interrupt handlers always reschedule on exit so an explicit * reschedule must not be performed in ISRs. * * @param[in] sp pointer to a @p Semaphore structure * @param[in] n value to be added to the semaphore counter. The value * must be positive. * * @iclass */ void chSemAddCounterI(Semaphore *sp, cnt_t n) { chDbgCheckClassI(); chDbgCheck((sp != NULL) && (n > 0), "chSemAddCounterI"); chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || ((sp->s_cnt < 0) && notempty(&sp->s_queue)), "chSemAddCounterI(), #1", "inconsistent semaphore"); while (n > 0) { if (++sp->s_cnt <= 0) chSchReadyI(fifo_remove(&sp->s_queue))->p_u.rdymsg = RDY_OK; n--; } }
/** * @brief Writes to a TX FIFO fetching data from a queue. * * @param[in] fifop pointer to the FIFO register * @param[in] oqp pointer to an @p OutputQueue object * @param[in] n maximum number of bytes to copy * * @notapi */ static void otg_fifo_write_from_queue(volatile uint32_t *fifop, OutputQueue *oqp, size_t n) { size_t ntogo; ntogo = n; while (ntogo > 0) { uint32_t w, i; size_t nw = ntogo / 4; if (nw > 0) { size_t streak; uint32_t nw2end = (oqp->q_top - oqp->q_rdptr) / 4; ntogo -= (streak = nw <= nw2end ? nw : nw2end) * 4; oqp->q_rdptr = otg_do_push(fifop, oqp->q_rdptr, streak); if (oqp->q_rdptr >= oqp->q_top) { oqp->q_rdptr = oqp->q_buffer; continue; } } /* If this condition is not satisfied then there is a word lying across queue circular buffer boundary or there are some remaining bytes.*/ if (ntogo <= 0) break; /* One byte at time.*/ w = 0; i = 0; while ((ntogo > 0) && (i < 4)) { w |= (uint32_t)*oqp->q_rdptr++ << (i * 8); if (oqp->q_rdptr >= oqp->q_top) oqp->q_rdptr = oqp->q_buffer; ntogo--; i++; } *fifop = w; } /* Updating queue.*/ chSysLock(); oqp->q_counter += n; while (notempty(&oqp->q_waiting)) chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = Q_OK; chSchRescheduleS(); chSysUnlock(); }
void fifo_config_change_file_path (const void *pointer, void *data, struct t_config_option *option) { /* make C compiler happy */ (void) pointer; (void) data; (void) option; fifo_quiet = 1; fifo_remove (); fifo_create (); fifo_quiet = 0; }
/** * @brief Unlocks the next owned mutex in reverse lock order. * @pre The invoking thread <b>must</b> have at least one owned mutex. * @post The mutex is unlocked and removed from the per-thread stack of * owned mutexes. * * @return A pointer to the unlocked mutex. * * @api */ Mutex *chMtxUnlock(void) { Thread *ctp = currp; Mutex *ump, *mp; chSysLock(); chDbgAssert(ctp->p_mtxlist != NULL, "chMtxUnlock(), #1", "owned mutexes list empty"); chDbgAssert(ctp->p_mtxlist->m_owner == ctp, "chMtxUnlock(), #2", "ownership failure"); /* Removes the top Mutex from the Thread's owned mutexes list and marks it as not owned.*/ ump = ctp->p_mtxlist; ctp->p_mtxlist = ump->m_next; /* If a thread is waiting on the mutex then the fun part begins.*/ if (chMtxQueueNotEmptyS(ump)) { Thread *tp; /* Recalculates the optimal thread priority by scanning the owned mutexes list.*/ tprio_t newprio = ctp->p_realprio; mp = ctp->p_mtxlist; while (mp != NULL) { /* If the highest priority thread waiting in the mutexes list has a greater priority than the current thread base priority then the final priority will have at least that priority.*/ if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio)) newprio = mp->m_queue.p_next->p_prio; mp = mp->m_next; } /* Assigns to the current thread the highest priority among all the waiting threads.*/ ctp->p_prio = newprio; /* Awakens the highest priority thread waiting for the unlocked mutex and assigns the mutex to it.*/ tp = fifo_remove(&ump->m_queue); ump->m_owner = tp; ump->m_next = tp->p_mtxlist; tp->p_mtxlist = ump; chSchWakeupS(tp, RDY_OK); } else ump->m_owner = NULL; chSysUnlock(); return ump; }
/** * @brief Reads a packet from the RXFIFO. * * @param[in] fifop pointer to the FIFO register * @param[in] iqp pointer to an @p InputQueue object * @param[in] n number of bytes to pull from the FIFO * * @notapi */ static void otg_fifo_read_to_queue(volatile uint32_t *fifop, InputQueue *iqp, size_t n) { size_t ntogo; ntogo = n; while (ntogo > 0) { uint32_t w, i; size_t nw = ntogo / 4; if (nw > 0) { size_t streak; uint32_t nw2end = (iqp->q_wrptr - iqp->q_wrptr) / 4; ntogo -= (streak = nw <= nw2end ? nw : nw2end) * 4; iqp->q_wrptr = otg_do_pop(fifop, iqp->q_wrptr, streak); if (iqp->q_wrptr >= iqp->q_top) { iqp->q_wrptr = iqp->q_buffer; continue; } } /* If this condition is not satisfied then there is a word lying across queue circular buffer boundary or there are some remaining bytes.*/ if (ntogo <= 0) break; /* One byte at time.*/ w = *fifop; i = 0; while ((ntogo > 0) && (i < 4)) { *iqp->q_wrptr++ = (uint8_t)(w >> (i * 8)); if (iqp->q_wrptr >= iqp->q_top) iqp->q_wrptr = iqp->q_buffer; ntogo--; i++; } } /* Updating queue.*/ chSysLock(); iqp->q_counter += n; while (notempty(&iqp->q_waiting)) chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_OK; chSchRescheduleS(); chSysUnlock(); }
/** * @brief Performs a signal operation on a semaphore. * @post This function does not reschedule so a call to a rescheduling * function must be performed before unlocking the kernel. Note that * interrupt handlers always reschedule on exit so an explicit * reschedule must not be performed in ISRs. * * @param[in] sp pointer to a @p Semaphore structure * * @iclass */ void chSemSignalI(Semaphore *sp) { chDbgCheck(sp != NULL, "chSemSignalI"); chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || ((sp->s_cnt < 0) && notempty(&sp->s_queue)), "chSemSignalI(), #1", "inconsistent semaphore"); if (++sp->s_cnt <= 0) { /* note, it is done this way in order to allow a tail call on chSchReadyI().*/ Thread *tp = fifo_remove(&sp->s_queue); tp->p_u.rdymsg = RDY_OK; chSchReadyI(tp); } }
/** * @brief Input queue write. * @details A byte value is written into the low end of an input queue. * * @param[in] iqp pointer to an @p InputQueue structure * @param[in] b the byte value to be written in the queue * @return The operation status. * @retval Q_OK if the operation has been completed with success. * @retval Q_FULL if the queue is full and the operation cannot be * completed. * * @iclass */ msg_t chIQPutI(InputQueue *iqp, uint8_t b) { chDbgCheckClassI(); if (chIQIsFullI(iqp)) return Q_FULL; iqp->q_counter++; *iqp->q_wrptr++ = b; if (iqp->q_wrptr >= iqp->q_top) iqp->q_wrptr = iqp->q_buffer; if (notempty(&iqp->q_waiting)) chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_OK; return Q_OK; }
/** * Pop error from queue * @param context - scpi context * @return error number */ INT16 SCPI_ErrorPop(scpi_t * context) { INT16 result = 0; /* * // FreeRTOS * if (pdFALSE == xQueueReceive((xQueueHandle)context->error_queue, &result, 0)) { * result = 0; * } */ /* basic FIFO */ fifo_remove((scpi_fifo_t *) context->error_queue, &result); SCPI_ErrorEmitEmpty(context); return result; }
static void worker_runphase1(workqueue_t *wq) { wip_t *wipslot; tdata_t *pow; int wipslotnum, pownum; for (;;) { pthread_mutex_lock(&wq->wq_queue_lock); while (fifo_empty(wq->wq_queue)) { if (wq->wq_nomorefiles == 1) { pthread_cond_broadcast(&wq->wq_work_avail); pthread_mutex_unlock(&wq->wq_queue_lock); /* on to phase 2 ... */ return; } pthread_cond_wait(&wq->wq_work_avail, &wq->wq_queue_lock); } /* there's work to be done! */ pow = fifo_remove(wq->wq_queue); pownum = wq->wq_nextpownum++; pthread_cond_broadcast(&wq->wq_work_removed); assert(pow != NULL); /* merge it into the right slot */ wipslotnum = pownum % wq->wq_nwipslots; wipslot = &wq->wq_wip[wipslotnum]; pthread_mutex_lock(&wipslot->wip_lock); pthread_mutex_unlock(&wq->wq_queue_lock); wip_add_work(wipslot, pow); if (wipslot->wip_nmerged == wq->wq_maxbatchsz) wip_save_work(wq, wipslot, wipslotnum); pthread_mutex_unlock(&wipslot->wip_lock); } }