Changeset c4cfe4c in mainline for uspace/app/kio/kio.c
- Timestamp:
- 2025-04-17T16:01:16Z (5 days ago)
- Branches:
- master
- Children:
- 888c06e
- Parents:
- 1db4e2ae (diff), 250a435 (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:
- Jiří Zárevúcky <zarevucky.jiri@…> (2025-04-17 15:51:11)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2025-04-17 16:01:16)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/kio/kio.c
r1db4e2ae rc4cfe4c 1 1 /* 2 2 * Copyright (c) 2006 Ondrej Palkovsky 3 * Copyright (c) 2025 Jiří Zárevúcky 3 4 * All rights reserved. 4 5 * … … 34 35 */ 35 36 37 #include <_bits/decls.h> 38 #include <libarch/config.h> 36 39 #include <stdio.h> 37 40 #include <async.h> … … 47 50 #include <adt/prodcons.h> 48 51 #include <tinput.h> 52 #include <uchar.h> 49 53 #include <vfs/vfs.h> 50 54 … … 55 59 typedef struct { 56 60 link_t link; 57 size_t length;58 char 32_t*data;61 size_t bytes; 62 char *data; 59 63 } item_t; 60 64 61 65 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_SIZE 71 72 static size_t current_at; 73 static char read_buffer[READ_BUFFER_SIZE]; 74 70 75 /** Klog producer 71 76 * … … 77 82 * 78 83 */ 79 static void producer(size_t length, char32_t*data)80 { 81 item_t *item = (item_t *)malloc(sizeof(item_t));84 static void producer(size_t bytes, char *data) 85 { 86 item_t *item = malloc(sizeof(item_t)); 82 87 if (item == NULL) 83 88 return; 84 89 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) { 88 93 free(item); 89 94 return; 90 95 } 91 96 92 memcpy( buf, data, sz);97 memcpy(item->data, data, bytes); 93 98 94 99 link_initialize(&item->link); 95 item->length = length;96 item->data = buf;97 100 prodcons_produce(&pc, &item->link); 98 101 } … … 120 123 item_t *item = list_get_instance(link, item_t, link); 121 124 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); 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 151 153 /* 152 154 * Make sure we process only a single notification 153 155 * at any time to limit the chance of the consumer 154 156 * starving. 155 *156 * Note: Usually the automatic masking of the kio157 * notifications on the kernel side does the trick158 * of limiting the chance of accidentally copying159 * the same data multiple times. However, due to160 * the non-blocking architecture of kio notifications,161 * this possibility cannot be generally avoided.162 157 */ 163 158 164 159 fibril_mutex_lock(&mtx); 165 160 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 } 180 176 181 177 async_event_unmask(EVENT_KIO); … … 185 181 int main(int argc, char *argv[]) 186 182 { 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 213 183 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); 215 185 if (rc != EOK) { 216 186 fprintf(stderr, "%s: Unable to register kio notifications\n",
Note:
See TracChangeset
for help on using the changeset viewer.