Changeset 61c91532 in mainline for uspace/app/kio/kio.c


Ignore:
Timestamp:
2025-04-17T16:18:27Z (5 days ago)
Author:
GitHub <noreply@…>
Children:
634340fd
Parents:
a65ccc4 (diff), 888c06e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
Wayne Thornton <wmthornton-dev@…> (2025-04-17 16:18:27)
git-committer:
GitHub <noreply@…> (2025-04-17 16:18:27)
Message:

Merge branch 'HelenOS:master' into master

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/kio/kio.c

    ra65ccc4 r61c91532  
    11/*
    22 * Copyright (c) 2006 Ondrej Palkovsky
     3 * Copyright (c) 2025 Jiří Zárevúcky
    34 * All rights reserved.
    45 *
     
    3435 */
    3536
     37#include <_bits/decls.h>
     38#include <libarch/config.h>
    3639#include <stdio.h>
    3740#include <async.h>
     
    4750#include <adt/prodcons.h>
    4851#include <tinput.h>
     52#include <uchar.h>
    4953#include <vfs/vfs.h>
    5054
     
    5559typedef struct {
    5660        link_t link;
    57         size_t length;
    58         char32_t *data;
     61        size_t bytes;
     62        char *data;
    5963} item_t;
    6064
    6165static prodcons_t pc;
    62 
    63 /* Pointer to kio area */
    64 static char32_t *kio = (char32_t *) AS_AREA_ANY;
    65 static size_t kio_length;
    6666
    6767/* Notification mutex */
    6868static FIBRIL_MUTEX_INITIALIZE(mtx);
    6969
     70#define READ_BUFFER_SIZE PAGE_SIZE
     71
     72static size_t current_at;
     73static char read_buffer[READ_BUFFER_SIZE];
     74
    7075/** Klog producer
    7176 *
     
    7782 *
    7883 */
    79 static void producer(size_t length, char32_t *data)
    80 {
    81         item_t *item = (item_t *) malloc(sizeof(item_t));
     84static void producer(size_t bytes, char *data)
     85{
     86        item_t *item = malloc(sizeof(item_t));
    8287        if (item == NULL)
    8388                return;
    8489
    85         size_t sz = sizeof(char32_t) * length;
    86         char32_t *buf = (char32_t *) malloc(sz);
    87         if (buf == NULL) {
     90        item->bytes = bytes;
     91        item->data = malloc(bytes);
     92        if (!item->data) {
    8893                free(item);
    8994                return;
    9095        }
    9196
    92         memcpy(buf, data, sz);
     97        memcpy(item->data, data, bytes);
    9398
    9499        link_initialize(&item->link);
    95         item->length = length;
    96         item->data = buf;
    97100        prodcons_produce(&pc, &item->link);
    98101}
     
    120123                item_t *item = list_get_instance(link, item_t, link);
    121124
    122                 for (size_t i = 0; i < item->length; i++)
    123                         putuchar(item->data[i]);
    124 
    125                 if (log != NULL) {
    126                         for (size_t i = 0; i < item->length; i++)
    127                                 fputuc(item->data[i], log);
    128 
     125                fwrite(item->data, 1, item->bytes, stdout);
     126
     127                if (log) {
     128                        fwrite(item->data, 1, item->bytes, log);
    129129                        fflush(log);
    130130                        vfs_sync(fileno(log));
     
    149149static void kio_notification_handler(ipc_call_t *call, void *arg)
    150150{
     151        size_t kio_written = (size_t) ipc_get_arg1(call);
     152
    151153        /*
    152154         * Make sure we process only a single notification
    153155         * at any time to limit the chance of the consumer
    154156         * starving.
    155          *
    156          * Note: Usually the automatic masking of the kio
    157          * notifications on the kernel side does the trick
    158          * of limiting the chance of accidentally copying
    159          * the same data multiple times. However, due to
    160          * the non-blocking architecture of kio notifications,
    161          * this possibility cannot be generally avoided.
    162157         */
    163158
    164159        fibril_mutex_lock(&mtx);
    165160
    166         size_t kio_start = (size_t) ipc_get_arg1(call);
    167         size_t kio_len = (size_t) ipc_get_arg2(call);
    168         size_t kio_stored = (size_t) ipc_get_arg3(call);
    169 
    170         size_t offset = (kio_start + kio_len - kio_stored) % kio_length;
    171 
    172         /* Copy data from the ring buffer */
    173         if (offset + kio_stored >= kio_length) {
    174                 size_t split = kio_length - offset;
    175 
    176                 producer(split, kio + offset);
    177                 producer(kio_stored - split, kio);
    178         } else
    179                 producer(kio_stored, kio + offset);
     161        while (current_at != kio_written) {
     162                size_t read = kio_read(read_buffer, READ_BUFFER_SIZE, current_at);
     163                if (read == 0)
     164                        break;
     165
     166                current_at += read;
     167
     168                if (read > READ_BUFFER_SIZE) {
     169                        /* We missed some data. */
     170                        // TODO: Send a message with the number of lost characters to the consumer.
     171                        read = READ_BUFFER_SIZE;
     172                }
     173
     174                producer(read, read_buffer);
     175        }
    180176
    181177        async_event_unmask(EVENT_KIO);
     
    185181int main(int argc, char *argv[])
    186182{
    187         size_t pages;
    188         errno_t rc = sysinfo_get_value("kio.pages", &pages);
    189         if (rc != EOK) {
    190                 fprintf(stderr, "%s: Unable to get number of kio pages\n",
    191                     NAME);
    192                 return rc;
    193         }
    194 
    195         uintptr_t faddr;
    196         rc = sysinfo_get_value("kio.faddr", &faddr);
    197         if (rc != EOK) {
    198                 fprintf(stderr, "%s: Unable to get kio physical address\n",
    199                     NAME);
    200                 return rc;
    201         }
    202 
    203         size_t size = pages * PAGE_SIZE;
    204         kio_length = size / sizeof(char32_t);
    205 
    206         rc = physmem_map(faddr, pages, AS_AREA_READ | AS_AREA_CACHEABLE,
    207             (void *) &kio);
    208         if (rc != EOK) {
    209                 fprintf(stderr, "%s: Unable to map kio\n", NAME);
    210                 return rc;
    211         }
    212 
    213183        prodcons_initialize(&pc);
    214         rc = async_event_subscribe(EVENT_KIO, kio_notification_handler, NULL);
     184        errno_t rc = async_event_subscribe(EVENT_KIO, kio_notification_handler, NULL);
    215185        if (rc != EOK) {
    216186                fprintf(stderr, "%s: Unable to register kio notifications\n",
Note: See TracChangeset for help on using the changeset viewer.