Changeset d5b37b6 in mainline for uspace/app/kio/kio.c


Ignore:
Timestamp:
2025-04-17T15:14:03Z (5 days ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
master
Children:
690ad20
Parents:
571cc2d
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2025-04-11 17:35:09)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2025-04-17 15:14:03)
Message:

Use a new syscall, SYS_KIO_READ, for reading from KIO buffer

Originally, the buffer memory was shared between kernel and
uspace, presumably to avoid the overhead of syscalls.
However, this makes synchronization with kernel impossible,
so it is not possible to ensure it works reliably without
random glitches. Also, relative to everything else /app/kio
does with the data, the syscall overhead is positively tiny.

File:
1 edited

Legend:

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

    r571cc2d rd5b37b6  
    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
     
    6165static prodcons_t pc;
    6266
    63 /* Pointer to kio area */
    64 static char32_t *kio = (char32_t *) AS_AREA_ANY;
    65 static size_t kio_length;
    66 
    6767/* Notification mutex */
    6868static FIBRIL_MUTEX_INITIALIZE(mtx);
    6969
    70 static size_t last_notification;
     70#define READ_BUFFER_SIZE (PAGE_SIZE / sizeof(char32_t))
     71
     72static size_t current_at;
     73static char32_t read_buffer[READ_BUFFER_SIZE];
    7174
    7275/** Klog producer
     
    151154static void kio_notification_handler(ipc_call_t *call, void *arg)
    152155{
     156        size_t kio_written = (size_t) ipc_get_arg1(call);
     157
    153158        /*
    154159         * Make sure we process only a single notification
     
    159164        fibril_mutex_lock(&mtx);
    160165
    161         size_t kio_written = (size_t) ipc_get_arg1(call);
    162 
    163         /* This works just fine even when kio_written overflows. */
    164         size_t new_chars = kio_written - last_notification;
    165         last_notification = kio_written;
    166 
    167         if (new_chars > kio_length) {
    168                 /* We missed some data. */
    169                 // TODO: Send a message with the number of lost bytes to the consumer.
    170                 new_chars = kio_length;
    171         }
    172 
    173         size_t offset = (kio_written - new_chars) % kio_length;
    174 
    175         /* Copy data from the ring buffer */
    176         if (offset + new_chars > kio_length) {
    177                 size_t split = kio_length - offset;
    178 
    179                 producer(split, kio + offset);
    180                 producer(new_chars - split, kio);
    181         } else {
    182                 producer(new_chars, kio + offset);
     166        while (current_at != kio_written) {
     167                size_t read = kio_read(read_buffer, READ_BUFFER_SIZE, current_at);
     168                if (read == 0)
     169                        break;
     170
     171                current_at += read;
     172
     173                if (read > READ_BUFFER_SIZE) {
     174                        /* We missed some data. */
     175                        // TODO: Send a message with the number of lost characters to the consumer.
     176                        read = READ_BUFFER_SIZE;
     177                }
     178
     179                producer(read, read_buffer);
    183180        }
    184181
     
    189186int main(int argc, char *argv[])
    190187{
    191         size_t pages;
    192         errno_t rc = sysinfo_get_value("kio.pages", &pages);
    193         if (rc != EOK) {
    194                 fprintf(stderr, "%s: Unable to get number of kio pages\n",
    195                     NAME);
    196                 return rc;
    197         }
    198 
    199         uintptr_t faddr;
    200         rc = sysinfo_get_value("kio.faddr", &faddr);
    201         if (rc != EOK) {
    202                 fprintf(stderr, "%s: Unable to get kio physical address\n",
    203                     NAME);
    204                 return rc;
    205         }
    206 
    207         size_t size = pages * PAGE_SIZE;
    208         kio_length = size / sizeof(char32_t);
    209 
    210         rc = physmem_map(faddr, pages, AS_AREA_READ | AS_AREA_CACHEABLE,
    211             (void *) &kio);
    212         if (rc != EOK) {
    213                 fprintf(stderr, "%s: Unable to map kio\n", NAME);
    214                 return rc;
    215         }
    216 
    217188        prodcons_initialize(&pc);
    218         rc = async_event_subscribe(EVENT_KIO, kio_notification_handler, NULL);
     189        errno_t rc = async_event_subscribe(EVENT_KIO, kio_notification_handler, NULL);
    219190        if (rc != EOK) {
    220191                fprintf(stderr, "%s: Unable to register kio notifications\n",
Note: See TracChangeset for help on using the changeset viewer.