Changes in uspace/app/kio/kio.c [690ad20:28a5ebd] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/kio/kio.c
r690ad20 r28a5ebd 1 1 /* 2 2 * Copyright (c) 2006 Ondrej Palkovsky 3 * Copyright (c) 2025 Jiří Zárevúcky4 3 * All rights reserved. 5 4 * … … 35 34 */ 36 35 37 #include <_bits/decls.h>38 #include <libarch/config.h>39 36 #include <stdio.h> 40 37 #include <async.h> … … 50 47 #include <adt/prodcons.h> 51 48 #include <tinput.h> 52 #include <uchar.h>53 49 #include <vfs/vfs.h> 54 50 … … 59 55 typedef struct { 60 56 link_t link; 61 size_t bytes;62 char *data;57 size_t length; 58 char32_t *data; 63 59 } item_t; 64 60 65 61 static 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; 66 66 67 67 /* Notification mutex */ 68 68 static FIBRIL_MUTEX_INITIALIZE(mtx); 69 69 70 #define READ_BUFFER_SIZE PAGE_SIZE71 72 static size_t current_at;73 static char read_buffer[READ_BUFFER_SIZE];74 75 70 /** Klog producer 76 71 * … … 82 77 * 83 78 */ 84 static void producer(size_t bytes, char*data)85 { 86 item_t *item = malloc(sizeof(item_t));79 static void producer(size_t length, char32_t *data) 80 { 81 item_t *item = (item_t *) malloc(sizeof(item_t)); 87 82 if (item == NULL) 88 83 return; 89 84 90 item->bytes = bytes;91 item->data = malloc(bytes);92 if ( !item->data) {85 size_t sz = sizeof(char32_t) * length; 86 char32_t *buf = (char32_t *) malloc(sz); 87 if (buf == NULL) { 93 88 free(item); 94 89 return; 95 90 } 96 91 97 memcpy( item->data, data, bytes);92 memcpy(buf, data, sz); 98 93 99 94 link_initialize(&item->link); 95 item->length = length; 96 item->data = buf; 100 97 prodcons_produce(&pc, &item->link); 101 98 } … … 123 120 item_t *item = list_get_instance(link, item_t, link); 124 121 125 fwrite(item->data, 1, item->bytes, stdout); 126 127 if (log) { 128 fwrite(item->data, 1, item->bytes, log); 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 129 129 fflush(log); 130 130 vfs_sync(fileno(log)); … … 149 149 static void kio_notification_handler(ipc_call_t *call, void *arg) 150 150 { 151 size_t kio_written = (size_t) ipc_get_arg1(call);152 153 151 /* 154 152 * Make sure we process only a single notification 155 153 * at any time to limit the chance of the consumer 156 154 * 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. 157 162 */ 158 163 159 164 fibril_mutex_lock(&mtx); 160 165 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 } 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); 176 180 177 181 async_event_unmask(EVENT_KIO); … … 181 185 int main(int argc, char *argv[]) 182 186 { 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 183 213 prodcons_initialize(&pc); 184 errno_trc = async_event_subscribe(EVENT_KIO, kio_notification_handler, NULL);214 rc = async_event_subscribe(EVENT_KIO, kio_notification_handler, NULL); 185 215 if (rc != EOK) { 186 216 fprintf(stderr, "%s: Unable to register kio notifications\n",
Note:
See TracChangeset
for help on using the changeset viewer.