Changeset af77459 in mainline


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

Simplify kio buffer bookkeeping

We only really need to know the number of characters written.
The rest is easily inferred from buffer size.

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/console/console.c

    r1db4e2ae raf77459  
    7676static MUTEX_INITIALIZE(console_mutex, MUTEX_RECURSIVE);
    7777
    78 /** First kernel log characters */
    79 static size_t kio_start = 0;
    80 
    81 /** Number of valid kernel log characters */
    82 static size_t kio_len = 0;
    83 
    84 /** Number of stored (not printed) kernel log characters */
    85 static size_t kio_stored = 0;
    86 
    87 /** Number of stored kernel log characters for uspace */
    88 static size_t kio_uspace = 0;
     78/** Number of characters written to buffer. Periodically overflows. */
     79static size_t kio_written = 0;
     80
     81/** Number of characters written to output devices. Periodically overflows. */
     82static size_t kio_processed = 0;
     83
     84/** Last notification sent to uspace. */
     85static size_t kio_notified = 0;
    8986
    9087/** Kernel log spinlock */
     
    259256        spinlock_lock(&kio_lock);
    260257
    261         if (kio_uspace > 0) {
    262                 if (event_notify_3(EVENT_KIO, true, kio_start, kio_len,
    263                     kio_uspace) == EOK)
    264                         kio_uspace = 0;
     258        if (kio_notified != kio_written) {
     259                if (event_notify_1(EVENT_KIO, true, kio_written) == EOK)
     260                        kio_notified = kio_written;
    265261        }
    266262
     
    281277
    282278        /* Print characters that weren't printed earlier */
    283         while (kio_stored > 0) {
    284                 char32_t tmp = kio[(kio_start + kio_len - kio_stored) % KIO_LENGTH];
    285                 kio_stored--;
     279        while (kio_written != kio_processed) {
     280                char32_t tmp = kio[kio_processed % KIO_LENGTH];
     281                kio_processed++;
    286282
    287283                /*
     
    304300void kio_push_char(const char32_t ch)
    305301{
    306         kio[(kio_start + kio_len) % KIO_LENGTH] = ch;
    307         if (kio_len < KIO_LENGTH)
    308                 kio_len++;
    309         else
    310                 kio_start = (kio_start + 1) % KIO_LENGTH;
    311 
    312         if (kio_stored < kio_len)
    313                 kio_stored++;
    314 
    315         /* The character is stored for uspace */
    316         if (kio_uspace < kio_len)
    317                 kio_uspace++;
     302        kio[kio_written % KIO_LENGTH] = ch;
     303        kio_written++;
    318304}
    319305
  • uspace/app/kio/kio.c

    r1db4e2ae raf77459  
    6868static FIBRIL_MUTEX_INITIALIZE(mtx);
    6969
     70static size_t last_notification;
     71
    7072/** Klog producer
    7173 *
     
    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;
     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;
    171174
    172175        /* Copy data from the ring buffer */
    173         if (offset + kio_stored >= kio_length) {
     176        if (offset + new_chars > kio_length) {
    174177                size_t split = kio_length - offset;
    175178
    176179                producer(split, kio + offset);
    177                 producer(kio_stored - split, kio);
    178         } else
    179                 producer(kio_stored, kio + offset);
     180                producer(new_chars - split, kio);
     181        } else {
     182                producer(new_chars, kio + offset);
     183        }
    180184
    181185        async_event_unmask(EVENT_KIO);
Note: See TracChangeset for help on using the changeset viewer.