Skip to content

Commit

Permalink
Split serial_[en/de]queue into serial_[en/de]queue and serial_[en/de]…
Browse files Browse the repository at this point in the history
…queue_local

Signed-off-by: Courtney Darville <courtneydarville94@outlook.com>
  • Loading branch information
Courtney3141 authored and Ivan-Velickovic committed Jan 30, 2025
1 parent fd43046 commit b02dd83
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 49 deletions.
4 changes: 2 additions & 2 deletions drivers/serial/arm/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ static void tx_provide(void)
bool transferred = false;
while (reprocess) {
char c;
while (!(uart_regs->fr & PL011_FR_TXFF) && !serial_dequeue(&tx_queue_handle, NULL, &c)) {
while (!(uart_regs->fr & PL011_FR_TXFF) && !serial_dequeue(&tx_queue_handle, &c)) {
uart_regs->dr = (uint32_t)c;
transferred = true;
}
Expand Down Expand Up @@ -79,7 +79,7 @@ static void rx_return(void)
while (reprocess) {
while (!(uart_regs->fr & PL011_FR_RXFE) && !serial_queue_full(&rx_queue_handle, rx_queue_handle.queue->tail)) {
char c = (char)(uart_regs->dr & PL011_DR_DATA_MASK);
serial_enqueue(&rx_queue_handle, NULL, c);
serial_enqueue(&rx_queue_handle, c);
enqueued = true;
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/serial/imx/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ static void tx_provide(void)
bool transferred = false;
while (reprocess) {
char c;
while (!(uart_regs->ts & UART_TST_TX_FIFO_FULL) && !serial_dequeue(&tx_queue_handle, NULL, &c)) {
while (!(uart_regs->ts & UART_TST_TX_FIFO_FULL) && !serial_dequeue(&tx_queue_handle, &c)) {
uart_regs->txd = (uint32_t)c;
transferred = true;
}
Expand Down Expand Up @@ -80,7 +80,7 @@ static void rx_return(void)
while (reprocess) {
while (!(uart_regs->ts & UART_TST_RX_FIFO_EMPTY) && !serial_queue_full(&rx_queue_handle, rx_queue_handle.queue->tail)) {
char c = (char) uart_regs->rxd;
serial_enqueue(&rx_queue_handle, NULL, c);
serial_enqueue(&rx_queue_handle, c);
enqueued = true;
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/serial/meson/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ static void tx_provide(void)
bool transferred = false;
while (reprocess) {
char c;
while (!(uart_regs->sr & AML_UART_TX_FULL) && !serial_dequeue(&tx_queue_handle, NULL, &c)) {
while (!(uart_regs->sr & AML_UART_TX_FULL) && !serial_dequeue(&tx_queue_handle, &c)) {
uart_regs->wfifo = (uint32_t)c;
transferred = true;
}
Expand Down Expand Up @@ -111,7 +111,7 @@ static void rx_return(void)
while (reprocess) {
while (!(uart_regs->sr & AML_UART_RX_EMPTY) && !serial_queue_full(&rx_queue_handle, rx_queue_handle.queue->tail)) {
char c = (char) uart_regs->rfifo;
serial_enqueue(&rx_queue_handle, NULL, c);
serial_enqueue(&rx_queue_handle, c);
enqueued = true;
}

Expand Down
4 changes: 2 additions & 2 deletions drivers/serial/snps/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ static void tx_provide(void)
while (reprocess) {
char c;

while ((*REG_PTR(UART_LSR) & UART_LSR_THRE) && !serial_dequeue(&tx_queue_handle, NULL, &c)) {
while ((*REG_PTR(UART_LSR) & UART_LSR_THRE) && !serial_dequeue(&tx_queue_handle, &c)) {
*REG_PTR(UART_THR) = c;
transferred = true;
}
Expand Down Expand Up @@ -89,7 +89,7 @@ static void rx_return(void)
while ((*REG_PTR(UART_LSR) & UART_LSR_DR)
&& !serial_queue_full(&rx_queue_handle, rx_queue_handle.queue->tail)) {
char c = *REG_PTR(UART_RBR);
int err = serial_enqueue(&rx_queue_handle, NULL, c);
int err = serial_enqueue(&rx_queue_handle, c);
assert(!err);
enqueued = true;
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/serial/virtio/console.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ static void tx_provide(void)
bool transferred = false;
while (reprocess) {
char c;
while (!virtio_avail_full_tx(&tx_virtq) && !serial_dequeue(&tx_queue_handle, NULL, &c)) {
while (!virtio_avail_full_tx(&tx_virtq) && !serial_dequeue(&tx_queue_handle, &c)) {

/* First, allocate somewhere to put the character */
uint32_t char_idx = -1;
Expand Down Expand Up @@ -249,7 +249,7 @@ static void rx_return(void)
assert(!(pkt.flags & VIRTQ_DESC_F_NEXT));

uint32_t char_idx = addr - virtio_rx_char_paddr;
serial_enqueue(&rx_queue_handle, NULL, virtio_rx_char[char_idx]);
serial_enqueue(&rx_queue_handle, virtio_rx_char[char_idx]);

/* Free the packet descriptor */
int err = ialloc_free(&rx_ialloc_desc, pkt_used.id);
Expand Down
2 changes: 1 addition & 1 deletion examples/serial/client.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ void notified(microkit_channel ch)
bool reprocess = true;
char c;
while (reprocess) {
while (!serial_dequeue(&rx_queue_handle, NULL, &c)) {
while (!serial_dequeue(&rx_queue_handle, &c)) {
if (c == '\r') {
sddf_putchar_unbuffered('\\');
sddf_putchar_unbuffered('r');
Expand Down
93 changes: 62 additions & 31 deletions include/sddf/serial/queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,17 @@ static inline int serial_queue_full(serial_queue_handle_t *queue_handle, uint32_
}

/**
* Enqueue a char into a queue.
* Enqueue a character into a queue. Update the shared tail so the character
* is visible to the consumer.
*
* @param queue_handle queue to enqueue into.
* @param local_tail address of the tail to be incremented. This allows for clients to
* enqueue multiple characters before making the changes visible.
* Leave NULL to increment shared queue tail.
* @param character character to be enqueued.
*
* @return -1 when queue is empty, 0 on success.
* @return -1 when queue is full, 0 on success.
*/
static inline int serial_enqueue(serial_queue_handle_t *queue_handle, uint32_t *local_tail,
char character)
static inline int serial_enqueue(serial_queue_handle_t *queue_handle, char character)
{
uint32_t *tail = (local_tail == NULL) ? &queue_handle->queue->tail : local_tail;
uint32_t *tail = &queue_handle->queue->tail;

if (serial_queue_full(queue_handle, *tail)) {
return -1;
Expand All @@ -95,20 +92,39 @@ static inline int serial_enqueue(serial_queue_handle_t *queue_handle, uint32_t *
}

/**
* Dequeue a char from a queue.
* Enqueue a character locally into a queue. Update a local tail variable so the
* character is not visible to the consumer.
*
* @param queue_handle queue to enqueue into.
* @param local_tail address of the tail to be used and incremented.
* @param character character to be enqueued.
*
* @return -1 when queue is full, 0 on success.
*/
static inline int serial_enqueue_local(serial_queue_handle_t *queue_handle, uint32_t *local_tail, char character)
{
if (serial_queue_full(queue_handle, *local_tail)) {
return -1;
}

queue_handle->data_region[*local_tail % queue_handle->capacity] = character;
(*local_tail)++;

return 0;
}

/**
* Dequeue a character from a queue. Update the shared head so the removal of the
* character is visible to the producer.
*
* @param queue_handle queue to dequeue from.
* @param local_head address of the head to be incremented. This allows for clients to
* dequeue multiple characters before making the changes visible.
* Leave NULL to increment shared queue head.
* @param character character to copy into.
* @param character address of character to copy into.
*
* @return -1 when queue is empty, 0 on success.
*/
static inline int serial_dequeue(serial_queue_handle_t *queue_handle, uint32_t *local_head,
char *character)
static inline int serial_dequeue(serial_queue_handle_t *queue_handle, char *character)
{
uint32_t *head = (local_head == NULL) ? &queue_handle->queue->head : local_head;
uint32_t *head = &queue_handle->queue->head;

if (serial_queue_empty(queue_handle, *head)) {
return -1;
Expand All @@ -120,15 +136,36 @@ static inline int serial_dequeue(serial_queue_handle_t *queue_handle, uint32_t *
return 0;
}

/**
* Dequeue a character locally from a queue. Update a local head variable so the
* removal of the character is not visible to the producer.
*
* @param queue_handle queue to dequeue from.
* @param local_head address of the head to be used and incremented.
* @param character character to copy into.
*
* @return -1 when queue is empty, 0 on success.
*/
static inline int serial_dequeue_local(serial_queue_handle_t *queue_handle, uint32_t *local_head, char *character)
{
if (serial_queue_empty(queue_handle, *local_head)) {
return -1;
}

*character = queue_handle->data_region[*local_head % queue_handle->capacity];
(*local_head)++;

return 0;
}

/**
* Update the value of the tail in the shared data structure to make
* locally enqueued data visible.
*
* @param queue_handle queue to update.
* @param local_tail tail which points to the last character enqueued.
*/
static inline void serial_update_shared_tail(serial_queue_handle_t *queue_handle,
uint32_t local_tail)
static inline void serial_update_shared_tail(serial_queue_handle_t *queue_handle, uint32_t local_tail)
{
uint32_t current_length = serial_queue_length(queue_handle);
uint32_t new_length = local_tail - queue_handle->queue->head;
Expand All @@ -153,8 +190,7 @@ static inline void serial_update_shared_tail(serial_queue_handle_t *queue_handle
* @param queue_handle queue to update.
* @param local_head head which points to the next character to dequeue.
*/
static inline void serial_update_shared_head(serial_queue_handle_t *queue_handle,
uint32_t local_head)
static inline void serial_update_shared_head(serial_queue_handle_t *queue_handle, uint32_t local_head)
{
uint32_t current_length = serial_queue_length(queue_handle);
uint32_t new_length = queue_handle->queue->tail - local_head;
Expand Down Expand Up @@ -219,9 +255,7 @@ static inline uint32_t serial_queue_contiguous_free(serial_queue_handle_t *queue
*
* @return Number of characters actually enqueued.
*/
static inline uint32_t serial_enqueue_batch(serial_queue_handle_t *queue_handle,
uint32_t num,
const char *src)
static inline uint32_t serial_enqueue_batch(serial_queue_handle_t *queue_handle, uint32_t num, const char *src)
{
char *dst = queue_handle->data_region + (queue_handle->queue->tail % queue_handle->capacity);
uint32_t avail = serial_queue_free(queue_handle);
Expand Down Expand Up @@ -254,13 +288,13 @@ static inline uint32_t serial_enqueue_batch(serial_queue_handle_t *queue_handle,
static inline void serial_transfer_all(serial_queue_handle_t *free_queue_handle,
serial_queue_handle_t *active_queue_handle)
{
assert(serial_queue_length(active_queue_handle)
<= serial_queue_free(free_queue_handle));
assert(serial_queue_length(active_queue_handle) <= serial_queue_free(free_queue_handle));

/* Copy in contiguous chunks */
while (serial_queue_length(active_queue_handle)) {
uint32_t num_active = serial_queue_contiguous_length(active_queue_handle);
char *src = active_queue_handle->data_region + (active_queue_handle->queue->head % active_queue_handle->capacity);
char *src = active_queue_handle->data_region
+ (active_queue_handle->queue->head % active_queue_handle->capacity);

uint32_t transferred = serial_enqueue_batch(free_queue_handle, num_active, src);
assert(transferred == num_active);
Expand All @@ -282,11 +316,8 @@ static inline void serial_transfer_all(serial_queue_handle_t *free_queue_handle,
* @param col_end_len length of end string.
*/
static inline void serial_transfer_all_colour(serial_queue_handle_t *free_queue_handle,
serial_queue_handle_t *active_queue_handle,
const char *col_start,
uint16_t col_start_len,
const char *col_end,
uint16_t col_end_len)
serial_queue_handle_t *active_queue_handle, const char *col_start,
uint16_t col_start_len, const char *col_end, uint16_t col_end_len)
{
assert(serial_queue_length(active_queue_handle) + col_start_len + col_end_len
<= serial_queue_free(free_queue_handle));
Expand Down
6 changes: 3 additions & 3 deletions serial/components/virt_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ void rx_return(void)
uint32_t local_tail = rx_queue_handle_cli[current_client].queue->tail;
char c = '\0';
while (reprocess) {
while (!serial_dequeue(&rx_queue_handle_drv, NULL, &c)) {
while (!serial_dequeue(&rx_queue_handle_drv, &c)) {
switch (current_mode) {
case normal:
if (c == config.switch_char) {
current_mode = switched;
} else {
if (!serial_enqueue(&rx_queue_handle_cli[current_client], &local_tail, c)) {
if (!serial_enqueue_local(&rx_queue_handle_cli[current_client], &local_tail, c)) {
transferred = true;
}
}
Expand All @@ -56,7 +56,7 @@ void rx_return(void)
current_mode = number;
} else {
if (c == config.switch_char) {
if (!serial_enqueue(&rx_queue_handle_cli[current_client], &local_tail, c)) {
if (!serial_enqueue_local(&rx_queue_handle_cli[current_client], &local_tail, c)) {
transferred = true;
}
} else {
Expand Down
2 changes: 1 addition & 1 deletion serial/components/virt_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ bool process_tx_queue(uint32_t client)
if (config.enable_colour) {
const char *client_colour = colours[client % ARRAY_SIZE(colours)];
serial_transfer_all_colour(&tx_queue_handle_drv, handle, client_colour, COLOUR_BEGIN_LEN, COLOUR_END,
COLOUR_END_LEN);
COLOUR_END_LEN);
} else {
serial_transfer_all(&tx_queue_handle_drv, handle);
}
Expand Down
6 changes: 3 additions & 3 deletions util/putchar_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ void _sddf_putchar(char character)
}

if (character == '\n') {
serial_enqueue(tx_queue_handle, &local_tail, '\r');
serial_enqueue_local(tx_queue_handle, &local_tail, '\r');
}
serial_enqueue(tx_queue_handle, &local_tail, character);
serial_enqueue_local(tx_queue_handle, &local_tail, character);

/* Make changes visible to virtualiser if character is flush or if queue is now filled */
if (serial_queue_full(tx_queue_handle, local_tail) || character == FLUSH_CHAR) {
Expand All @@ -43,7 +43,7 @@ void sddf_putchar_unbuffered(char character)
return;
}

serial_enqueue(tx_queue_handle, &local_tail, character);
serial_enqueue_local(tx_queue_handle, &local_tail, character);

serial_update_shared_tail(tx_queue_handle, local_tail);
if (serial_require_producer_signal(tx_queue_handle)) {
Expand Down

0 comments on commit b02dd83

Please sign in to comment.