static void queues2_execute(void) { unsigned i; size_t n; /* Initial empty state */ test_assert_lock(1, chOQIsEmptyI(&oq), "not empty"); /* Queue filling */ for (i = 0; i < TEST_QUEUES_SIZE; i++) chOQPut(&oq, 'A' + i); test_assert_lock(2, chOQIsFullI(&oq), "still has space"); /* Queue emptying */ for (i = 0; i < TEST_QUEUES_SIZE; i++) { char c; chSysLock(); c = chOQGetI(&oq); chSysUnlock(); test_emit_token(c); } test_assert_lock(3, chOQIsEmptyI(&oq), "still full"); test_assert_sequence(4, "ABCD"); test_assert_lock(5, chOQGetI(&oq) == Q_EMPTY, "failed to report Q_EMPTY"); /* Writing the whole thing */ n = chOQWriteTimeout(&oq, wa[1], TEST_QUEUES_SIZE * 2, TIME_IMMEDIATE); test_assert(6, n == TEST_QUEUES_SIZE, "wrong returned size"); test_assert_lock(7, chOQIsFullI(&oq), "not full"); threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, thread2, NULL); test_assert_lock(8, chOQGetFullI(&oq) == TEST_QUEUES_SIZE, "not empty"); test_wait_threads(); /* Testing reset */ chSysLock(); chOQResetI(&oq); chSysUnlock(); test_assert_lock(9, chOQGetFullI(&oq) == 0, "still full"); /* Partial writes */ n = chOQWriteTimeout(&oq, wa[1], TEST_QUEUES_SIZE / 2, TIME_IMMEDIATE); test_assert(10, n == TEST_QUEUES_SIZE / 2, "wrong returned size"); n = chOQWriteTimeout(&oq, wa[1], TEST_QUEUES_SIZE / 2, TIME_IMMEDIATE); test_assert(11, n == TEST_QUEUES_SIZE / 2, "wrong returned size"); test_assert_lock(12, chOQIsFullI(&oq), "not full"); /* Timeout */ test_assert(13, chOQPutTimeout(&oq, 0, 10) == Q_TIMEOUT, "wrong timeout return"); }
/** * @brief Output queue write with timeout. * @details The function writes data from a buffer to an output queue. The * operation completes when the specified amount of data has been * transferred or after the specified timeout or if the queue has * been reset. * @note The function is not atomic, if you need atomicity it is suggested * to use a semaphore or a mutex for mutual exclusion. * @note The callback is invoked after writing each character into the * buffer. * * @param[in] oqp pointer to an @p output_queue_t structure * @param[out] bp pointer to the data buffer * @param[in] n the maximum amount of data to be transferred, the * value 0 is reserved * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The number of bytes effectively transferred. * * @api */ size_t chOQWriteTimeout(output_queue_t *oqp, const uint8_t *bp, size_t n, systime_t time) { qnotify_t nfy = oqp->q_notify; size_t w = 0; chDbgCheck(n > 0); chSysLock(); while (true) { while (chOQIsFullI(oqp)) { if (chThdEnqueueTimeoutS(&oqp->q_waiting, time) != Q_OK) { chSysUnlock(); return w; } } oqp->q_counter--; *oqp->q_wrptr++ = *bp++; if (oqp->q_wrptr >= oqp->q_top) oqp->q_wrptr = oqp->q_buffer; if (nfy) nfy(oqp); chSysUnlock(); /* Gives a preemption chance in a controlled point.*/ w++; if (--n == 0) return w; chSysLock(); } }
/** * @brief Output queue write with timeout. * @details The function writes data from a buffer to an output queue. The * operation completes when the specified amount of data has been * transferred or after the specified timeout or if the queue has * been reset. * @note The function is not atomic, if you need atomicity it is suggested * to use a semaphore or a mutex for mutual exclusion. * @note The callback is invoked after writing each character into the * buffer. * * @param[in] oqp pointer to an @p OutputQueue structure * @param[out] bp pointer to the data buffer * @param[in] n the maximum amount of data to be transferred, the * value 0 is reserved * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The number of bytes effectively transferred. * * @api */ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp, size_t n, systime_t time) { qnotify_t nfy = oqp->q_notify; size_t w = 0; chDbgCheck(n > 0, "chOQWriteTimeout"); chSysLock(); while (TRUE) { while (chOQIsFullI(oqp)) { if (qwait((GenericQueue *)oqp, time) != Q_OK) { chSysUnlock(); return w; } } oqp->q_counter--; *oqp->q_wrptr++ = *bp++; if (oqp->q_wrptr >= oqp->q_top) oqp->q_wrptr = oqp->q_buffer; if (nfy) nfy(oqp); chSysUnlock(); /* Gives a preemption chance in a controlled point.*/ w++; if (--n == 0) return w; chSysLock(); } }
/** * @brief Output queue write with timeout. * @details The function writes data from a buffer to an output queue. The * operation completes when the specified amount of data has been * transferred or after the specified timeout or if the queue has * been reset. * @note The function is not atomic, if you need atomicity it is suggested * to use a semaphore or a mutex for mutual exclusion. * @note The queue callback is invoked before entering a sleep state and at * the end of the transfer. * * @param[in] oqp pointer to an @p OutputQueue structure * @param[out] bp pointer to the data buffer * @param[in] n the maximum amount of data to be transferred, the * value 0 is reserved * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The number of bytes effectively transferred. * * @api */ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp, size_t n, systime_t time) { qnotify_t nfy = oqp->q_notify; size_t w = 0; chDbgCheck(n > 0, "chOQWriteTimeout"); chSysLock(); while (TRUE) { if (chOQIsFullI(oqp)) { if (nfy) nfy(oqp); if ((chSemWaitTimeoutS(&oqp->q_sem, time) != RDY_OK)) { chSysUnlock(); return w; } } else chSemFastWaitI(&oqp->q_sem); *oqp->q_wrptr++ = *bp++; if (oqp->q_wrptr >= oqp->q_top) oqp->q_wrptr = oqp->q_buffer; chSysUnlock(); /* Gives a preemption chance in a controlled point.*/ w++; if (--n == 0) { chSysLock(); if (nfy) nfy(oqp); chSysUnlock(); return w; } chSysLock(); } }
/** * @brief Output queue write with timeout. * @details This function writes a byte value to an output queue. If the queue * is full then the calling thread is suspended until there is space * in the queue or a timeout occurs. * @note The callback is invoked after writing the character into the * buffer. * * @param[in] oqp pointer to an @p output_queue_t structure * @param[in] b the byte value to be written in the queue * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The operation status. * @retval Q_OK if the operation succeeded. * @retval Q_TIMEOUT if the specified time expired. * @retval Q_RESET if the queue has been reset. * * @api */ msg_t chOQPutTimeout(output_queue_t *oqp, uint8_t b, systime_t time) { chSysLock(); while (chOQIsFullI(oqp)) { msg_t msg; if ((msg = chThdEnqueueTimeoutS(&oqp->q_waiting, time)) < Q_OK) { chSysUnlock(); return msg; } } oqp->q_counter--; *oqp->q_wrptr++ = b; if (oqp->q_wrptr >= oqp->q_top) oqp->q_wrptr = oqp->q_buffer; if (oqp->q_notify) oqp->q_notify(oqp); chSysUnlock(); return Q_OK; }
/** * @brief Output queue write with timeout. * @details This function writes a byte value to an output queue. If the queue * is full then the calling thread is suspended until there is space * in the queue or a timeout occurs. * @note The callback is invoked after writing the character into the * buffer. * * @param[in] oqp pointer to an @p OutputQueue structure * @param[in] b the byte value to be written in the queue * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The operation status. * @retval Q_OK if the operation succeeded. * @retval Q_TIMEOUT if the specified time expired. * @retval Q_RESET if the queue has been reset. * * @api */ msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time) { chSysLock(); while (chOQIsFullI(oqp)) { msg_t msg; if ((msg = qwait((GenericQueue *)oqp, time)) < Q_OK) { chSysUnlock(); return msg; } } oqp->q_counter--; *oqp->q_wrptr++ = b; if (oqp->q_wrptr >= oqp->q_top) oqp->q_wrptr = oqp->q_buffer; if (oqp->q_notify) oqp->q_notify(oqp); chSysUnlock(); return Q_OK; }
/** * @brief Output queue write with timeout. * @details This function writes a byte value to an output queue. If the queue * is full then the calling thread is suspended until there is space * in the queue or a timeout occurs. * @note The callback is invoked after writing the character into the * buffer. * * @param[in] oqp pointer to an @p output_queue_t structure * @param[in] b the byte value to be written in the queue * @param[in] timeout the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . * @return The operation status. * @retval Q_OK if the operation succeeded. * @retval Q_TIMEOUT if the specified time expired. * @retval Q_RESET if the queue has been reset. * * @api */ msg_t chOQPutTimeout(output_queue_t *oqp, uint8_t b, systime_t timeout) { chSysLock(); while (chOQIsFullI(oqp)) { msg_t msg = chThdEnqueueTimeoutS(&oqp->waiting, timeout); if (msg < Q_OK) { chSysUnlock(); return msg; } } oqp->counter--; *oqp->wrptr++ = b; if (oqp->wrptr >= oqp->top) { oqp->wrptr = oqp->buffer; } if (oqp->notify != NULL) { oqp->notify(oqp); } chSysUnlock(); return Q_OK; }
bool OutQueue::isFullI(void) { return (bool)chOQIsFullI(&oq); }
static bool_t putwouldblock(void *ip) { return chOQIsFullI(&((SerialDriver *)ip)->oqueue); }