Changeset b0f00a9 in mainline for uspace/lib/c/generic
- Timestamp:
- 2011-11-06T22:21:05Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/fix-logger-deadlock, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 898e847
- Parents:
- 2bdf8313 (diff), 7b5f4c9 (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. - Location:
- uspace/lib/c/generic
- Files:
-
- 8 added
- 4 deleted
- 43 edited
- 3 moved
-
adt/hash_set.c (added)
-
adt/hash_table.c (modified) (9 diffs)
-
adt/list.c (modified) (3 diffs)
-
adt/measured_strings.c (modified) (11 diffs)
-
adt/prodcons.c (modified) (1 diff)
-
as.c (modified) (2 diffs)
-
assert.c (modified) (2 diffs)
-
async.c (modified) (72 diffs)
-
async_sess.c (deleted)
-
cfg.c (added)
-
clipboard.c (modified) (9 diffs)
-
ddi.c (modified) (2 diffs)
-
device/char_dev.c (modified) (3 diffs)
-
device/hw_res.c (modified) (1 diff)
-
device/hw_res_parsed.c (added)
-
device/nic.c (added)
-
devman.c (modified) (5 diffs)
-
devmap.c (deleted)
-
elf/elf_load.c (moved) (moved from uspace/srv/loader/elf_load.c ) (9 diffs)
-
event.c (modified) (3 diffs)
-
fibril.c (modified) (4 diffs)
-
fibril_synch.c (modified) (3 diffs)
-
io/console.c (modified) (1 diff)
-
io/io.c (modified) (18 diffs)
-
io/klog.c (modified) (2 diffs)
-
io/printf_core.c (modified) (5 diffs)
-
io/screenbuffer.c (deleted)
-
io/vprintf.c (modified) (1 diff)
-
ipc.c (modified) (6 diffs)
-
l18n/langs.c (added)
-
libc.c (modified) (3 diffs)
-
loader.c (modified) (13 diffs)
-
loc.c (added)
-
malloc.c (modified) (13 diffs)
-
net/icmp_api.c (modified) (3 diffs)
-
net/icmp_common.c (modified) (1 diff)
-
net/modules.c (modified) (4 diffs)
-
net/packet.c (modified) (8 diffs)
-
net/socket_client.c (modified) (32 diffs)
-
ns.c (added)
-
private/async.h (modified) (2 diffs)
-
private/io.h (modified) (1 diff)
-
private/loader.h (added)
-
private/ns.h (moved) (moved from uspace/lib/c/generic/private/async_sess.h ) (1 diff)
-
private/stdio.h (moved) (moved from uspace/srv/hid/fb/msim.c ) (3 diffs)
-
private/thread.h (modified) (1 diff)
-
rtld/elf_load.c (deleted)
-
rtld/module.c (modified) (7 diffs)
-
rtld/rtld.c (modified) (1 diff)
-
rtld/symbol.c (modified) (6 diffs)
-
str.c (modified) (7 diffs)
-
str_error.c (modified) (2 diffs)
-
sysinfo.c (modified) (1 diff)
-
task.c (modified) (12 diffs)
-
thread.c (modified) (2 diffs)
-
time.c (modified) (2 diffs)
-
udebug.c (modified) (1 diff)
-
vfs/vfs.c (modified) (35 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/adt/hash_table.c
r2bdf8313 rb0f00a9 54 54 * 55 55 */ 56 inthash_table_create(hash_table_t *h, hash_count_t m, hash_count_t max_keys,56 bool hash_table_create(hash_table_t *h, hash_count_t m, hash_count_t max_keys, 57 57 hash_table_operations_t *op) 58 58 { … … 61 61 assert(max_keys > 0); 62 62 63 h->entry = malloc(m * sizeof(li nk_t));63 h->entry = malloc(m * sizeof(list_t)); 64 64 if (!h->entry) 65 65 return false; 66 66 67 memset((void *) h->entry, 0, m * sizeof(li nk_t));67 memset((void *) h->entry, 0, m * sizeof(list_t)); 68 68 69 69 hash_count_t i; … … 78 78 } 79 79 80 /** Remove all elements from the hash table 81 * 82 * @param h Hash table to be cleared 83 */ 84 void hash_table_clear(hash_table_t *h) 85 { 86 for (hash_count_t chain = 0; chain < h->entries; ++chain) { 87 link_t *cur; 88 link_t *next; 89 90 for (cur = h->entry[chain].head.next; 91 cur != &h->entry[chain].head; 92 cur = next) { 93 next = cur->next; 94 list_remove(cur); 95 h->op->remove_callback(cur); 96 } 97 } 98 } 99 80 100 /** Destroy a hash table instance. 81 101 * … … 123 143 assert(chain < h->entries); 124 144 125 link_t *cur; 126 for (cur = h->entry[chain].next; cur != &h->entry[chain]; 127 cur = cur->next) { 145 list_foreach(h->entry[chain], cur) { 128 146 if (h->op->compare(key, h->max_keys, cur)) { 129 147 /* … … 152 170 h->op->remove_callback); 153 171 assert(keys <= h->max_keys); 154 155 link_t *cur;156 172 157 173 if (keys == h->max_keys) { … … 161 177 */ 162 178 163 cur = hash_table_find(h, key);179 link_t *cur = hash_table_find(h, key); 164 180 if (cur) { 165 181 list_remove(cur); … … 176 192 hash_index_t chain; 177 193 for (chain = 0; chain < h->entries; chain++) { 178 for (cur = h->entry[chain].next; cur != &h->entry[chain]; 194 for (link_t *cur = h->entry[chain].head.next; 195 cur != &h->entry[chain].head; 179 196 cur = cur->next) { 180 197 if (h->op->compare(key, keys, cur)) { … … 193 210 } 194 211 195 /** Apply fu cntion to all items in hash table.212 /** Apply function to all items in hash table. 196 213 * 197 214 * @param h Hash table. … … 201 218 */ 202 219 void hash_table_apply(hash_table_t *h, void (*f)(link_t *, void *), void *arg) 203 { 204 hash_index_t bucket; 205 link_t *cur; 206 207 for (bucket = 0; bucket < h->entries; bucket++) { 208 for (cur = h->entry[bucket].next; cur != &h->entry[bucket]; 209 cur = cur->next) { 220 { 221 for (hash_index_t bucket = 0; bucket < h->entries; bucket++) { 222 link_t *cur; 223 link_t *next; 224 225 for (cur = h->entry[bucket].head.next; cur != &h->entry[bucket].head; 226 cur = next) { 227 /* 228 * The next pointer must be stored prior to the functor 229 * call to allow using destructor as the functor (the 230 * free function could overwrite the cur->next pointer). 231 */ 232 next = cur->next; 210 233 f(cur, arg); 211 234 } -
uspace/lib/c/generic/adt/list.c
r2bdf8313 rb0f00a9 30 30 * @{ 31 31 */ 32 /** @file 32 33 /** 34 * @file 35 * @brief Functions completing doubly linked circular list implementation. 36 * 37 * This file contains some of the functions implementing doubly linked circular lists. 38 * However, this ADT is mostly implemented in @ref list.h. 33 39 */ 34 40 35 41 #include <adt/list.h> 36 42 #include <bool.h> 37 43 38 44 /** Check for membership 39 45 * 40 * Check whether link is contained in the list head.41 * The membership is defined as pointer equivalence.46 * Check whether link is contained in a list. 47 * Membership is defined as pointer equivalence. 42 48 * 43 * @param link Item to look for.44 * @param headList to look in.49 * @param link Item to look for. 50 * @param list List to look in. 45 51 * 46 * @return true if link is contained in head, false otherwise.52 * @return true if link is contained in list, false otherwise. 47 53 * 48 54 */ 49 int list_member(const link_t *link, const li nk_t *head)55 int list_member(const link_t *link, const list_t *list) 50 56 { 51 int found = 0;52 link_t *hlp = head->next;57 bool found = false; 58 link_t *hlp = list->head.next; 53 59 54 while (hlp != head) {60 while (hlp != &list->head) { 55 61 if (hlp == link) { 56 found = 1;62 found = true; 57 63 break; 58 64 } … … 63 69 } 64 70 65 66 71 /** Concatenate two lists 67 72 * 68 * Concatenate lists head1 and head2, producing a single69 * list head1 containing items from both (in head1, head270 * order) and empty list head2.73 * Concatenate lists @a list1 and @a list2, producing a single 74 * list @a list1 containing items from both (in @a list1, @a list2 75 * order) and empty list @a list2. 71 76 * 72 * @param head1First list and concatenated output73 * @param head2Second list and empty output.77 * @param list1 First list and concatenated output 78 * @param list2 Second list and empty output. 74 79 * 75 80 */ 76 void list_concat(li nk_t *head1, link_t *head2)81 void list_concat(list_t *list1, list_t *list2) 77 82 { 78 if (list_empty( head2))83 if (list_empty(list2)) 79 84 return; 80 81 head2->next->prev = head1->prev;82 head2->prev->next = head1;83 head1->prev->next = head2->next;84 head1->prev = head2->prev;85 list_initialize( head2);85 86 list2->head.next->prev = list1->head.prev; 87 list2->head.prev->next = &list1->head; 88 list1->head.prev->next = list2->head.next; 89 list1->head.prev = list2->head.prev; 90 list_initialize(list2); 86 91 } 87 88 92 89 93 /** Count list items … … 91 95 * Return the number of items in the list. 92 96 * 93 * @param link List to count. 94 * 95 * @return Number of items in the list. 96 * 97 * @param list List to count. 98 * @return Number of items in the list. 97 99 */ 98 unsigned int list_count(const li nk_t *link)100 unsigned int list_count(const list_t *list) 99 101 { 100 102 unsigned int count = 0; 101 link_t *hlp = link->next;102 103 103 while (hlp !=link) {104 list_foreach(*list, link) { 104 105 count++; 105 hlp = hlp->next;106 106 } 107 107 -
uspace/lib/c/generic/adt/measured_strings.c
r2bdf8313 rb0f00a9 297 297 * size has to be negotiated in advance. 298 298 * 299 * @param[in] phone The other module phone.299 * @param[in] exch Exchange. 300 300 * @param[out] strings The returned measured strings array. 301 301 * @param[out] data The measured strings data. This memory block stores the … … 304 304 * @return EOK on success. 305 305 * @return EINVAL if the strings or data parameter is NULL. 306 * @return EINVAL if the phone or count parameter is not positive.306 * @return EINVAL if the exch or count parameter is invalid. 307 307 * @return EINVAL if the sent array differs in size. 308 308 * @return ENOMEM if there is not enough memory left. … … 310 310 * async_data_read_start() function. 311 311 */ 312 int 313 measured_strings_return(int phone, measured_string_t **strings, uint8_t **data, 314 size_t count) 312 int measured_strings_return(async_exch_t *exch, measured_string_t **strings, 313 uint8_t **data, size_t count) 315 314 { 316 315 size_t *lengths; … … 319 318 int rc; 320 319 321 if (( phone < 0) || (!strings) || (!data) || (count <= 0))320 if ((exch == NULL) || (!strings) || (!data) || (count <= 0)) 322 321 return EINVAL; 323 322 … … 326 325 return ENOMEM; 327 326 328 rc = async_data_read_start( phone, lengths,327 rc = async_data_read_start(exch, lengths, 329 328 sizeof(size_t) * (count + 1)); 330 329 if (rc != EOK) { … … 351 350 (*strings)[index].length = lengths[index]; 352 351 if (lengths[index] > 0) { 353 rc = async_data_read_start( phone, next, lengths[index]);352 rc = async_data_read_start(exch, next, lengths[index]); 354 353 if (rc != EOK) { 355 354 free(lengths); … … 375 374 * size has to be negotiated in advance. 376 375 * 377 * @param[in] phone The other module phone.376 * @param[in] exch Exchange. 378 377 * @param[in] strings The measured strings array to be transferred. 379 378 * @param[in] count The measured strings array size. 380 379 * @return EOK on success. 381 380 * @return EINVAL if the strings parameter is NULL. 382 * @return EINVAL if the phone or count parameter is not positive.381 * @return EINVAL if the exch or count parameter is invalid. 383 382 * @return Other error codes as defined for the 384 383 * async_data_write_start() function. 385 384 */ 386 int 387 measured_strings_send(int phone, const measured_string_t *strings, 385 int measured_strings_send(async_exch_t *exch, const measured_string_t *strings, 388 386 size_t count) 389 387 { … … 392 390 int rc; 393 391 394 if (( phone < 0) || (!strings) || (count <= 0))392 if ((exch == NULL) || (!strings) || (count <= 0)) 395 393 return EINVAL; 396 394 … … 399 397 return ENOMEM; 400 398 401 rc = async_data_write_start( phone, lengths,399 rc = async_data_write_start(exch, lengths, 402 400 sizeof(size_t) * (count + 1)); 403 401 if (rc != EOK) { … … 410 408 for (index = 0; index < count; index++) { 411 409 if (strings[index].length > 0) { 412 rc = async_data_write_start( phone, strings[index].value,410 rc = async_data_write_start(exch, strings[index].value, 413 411 strings[index].length); 414 412 if (rc != EOK) … … 422 420 /** @} 423 421 */ 424 -
uspace/lib/c/generic/adt/prodcons.c
r2bdf8313 rb0f00a9 61 61 fibril_condvar_wait(&pc->cv, &pc->mtx); 62 62 63 link_t *head = pc->list.next;63 link_t *head = list_first(&pc->list); 64 64 list_remove(head); 65 65 -
uspace/lib/c/generic/as.c
r2bdf8313 rb0f00a9 35 35 #include <as.h> 36 36 #include <libc.h> 37 #include <errno.h> 37 38 #include <unistd.h> 38 39 #include <align.h> … … 114 115 } 115 116 117 /** Find mapping to physical address. 118 * 119 * @param address Virtual address in question (virtual). 120 * @param[out] frame Frame address (physical). 121 * @return Error code. 122 * @retval EOK No error, @p frame holds the translation. 123 * @retval ENOENT Mapping not found. 124 */ 125 int as_get_physical_mapping(const void *address, uintptr_t *frame) 126 { 127 uintptr_t tmp_frame; 128 uintptr_t virt = (uintptr_t) address; 129 130 int rc = (int) __SYSCALL2(SYS_PAGE_FIND_MAPPING, 131 (sysarg_t) virt, (sysarg_t) &tmp_frame); 132 if (rc != EOK) { 133 return rc; 134 } 135 136 if (frame != NULL) { 137 *frame = tmp_frame; 138 } 139 140 return EOK; 141 } 142 116 143 /** @} 117 144 */ -
uspace/lib/c/generic/assert.c
r2bdf8313 rb0f00a9 37 37 #include <atomic.h> 38 38 #include <stacktrace.h> 39 #include <stdint.h> 39 40 40 #define MSG_START "Assertion failed (" 41 #define MSG_FILE ") in file \"" 42 #define MSG_LINE "\", line " 43 #define MSG_END ".\n" 41 static atomic_t failed_asserts = {0}; 44 42 45 static atomic_t failed_asserts; 46 47 void assert_abort(const char *cond, const char *file, const char *line) 43 void assert_abort(const char *cond, const char *file, unsigned int line) 48 44 { 49 45 /* 50 46 * Send the message safely to klog. Nested asserts should not occur. 51 47 */ 52 klog_write(MSG_START, str_size(MSG_START)); 53 klog_write(cond, str_size(cond)); 54 klog_write(MSG_FILE, str_size(MSG_FILE)); 55 klog_write(file, str_size(file)); 56 klog_write(MSG_LINE, str_size(MSG_LINE)); 57 klog_write(line, str_size(line)); 58 klog_write(MSG_END, str_size(MSG_END)); 59 48 klog_printf("Assertion failed (%s) in file \"%s\", line %u.\n", 49 cond, file, line); 50 60 51 /* 61 52 * Check if this is a nested or parallel assert. … … 69 60 * assertions. 70 61 */ 71 printf( MSG_START "%s" MSG_FILE "%s" MSG_LINE "%s" MSG_END,62 printf("Assertion failed (%s) in file \"%s\", line %u.\n", 72 63 cond, file, line); 73 64 stacktrace_print(); 74 65 75 66 abort(); 76 67 } -
uspace/lib/c/generic/async.c
r2bdf8313 rb0f00a9 40 40 * programming. 41 41 * 42 * You should be able to write very simple multithreaded programs, the async 43 * framework will automatically take care of most synchronization problems. 42 * You should be able to write very simple multithreaded programs. The async 43 * framework will automatically take care of most of the synchronization 44 * problems. 44 45 * 45 46 * Example of use (pseudo C): … … 53 54 * int fibril1(void *arg) 54 55 * { 55 * conn = async_connect_me_to(); 56 * c1 = async_send(conn); 57 * c2 = async_send(conn); 56 * conn = async_connect_me_to(...); 57 * 58 * exch = async_exchange_begin(conn); 59 * c1 = async_send(exch); 60 * async_exchange_end(exch); 61 * 62 * exch = async_exchange_begin(conn); 63 * c2 = async_send(exch); 64 * async_exchange_end(exch); 65 * 58 66 * async_wait_for(c1); 59 67 * async_wait_for(c2); … … 90 98 #include <ipc/ipc.h> 91 99 #include <async.h> 100 #include "private/async.h" 92 101 #undef LIBC_ASYNC_C_ 93 102 94 103 #include <futex.h> 95 104 #include <fibril.h> 96 #include <stdio.h>97 105 #include <adt/hash_table.h> 98 106 #include <adt/list.h> … … 100 108 #include <errno.h> 101 109 #include <sys/time.h> 102 #include < arch/barrier.h>110 #include <libarch/barrier.h> 103 111 #include <bool.h> 112 #include <malloc.h> 113 #include <mem.h> 104 114 #include <stdlib.h> 105 #include <malloc.h> 106 #include "private/async.h" 107 115 #include <macros.h> 116 117 #define CLIENT_HASH_TABLE_BUCKETS 32 118 #define CONN_HASH_TABLE_BUCKETS 32 119 120 /** Session data */ 121 struct async_sess { 122 /** List of inactive exchanges */ 123 list_t exch_list; 124 125 /** Exchange management style */ 126 exch_mgmt_t mgmt; 127 128 /** Session identification */ 129 int phone; 130 131 /** First clone connection argument */ 132 sysarg_t arg1; 133 134 /** Second clone connection argument */ 135 sysarg_t arg2; 136 137 /** Third clone connection argument */ 138 sysarg_t arg3; 139 140 /** Exchange mutex */ 141 fibril_mutex_t mutex; 142 143 /** Number of opened exchanges */ 144 atomic_t refcnt; 145 146 /** Mutex for stateful connections */ 147 fibril_mutex_t remote_state_mtx; 148 149 /** Data for stateful connections */ 150 void *remote_state_data; 151 }; 152 153 /** Exchange data */ 154 struct async_exch { 155 /** Link into list of inactive exchanges */ 156 link_t sess_link; 157 158 /** Link into global list of inactive exchanges */ 159 link_t global_link; 160 161 /** Session pointer */ 162 async_sess_t *sess; 163 164 /** Exchange identification */ 165 int phone; 166 }; 167 168 /** Async framework global futex */ 108 169 atomic_t async_futex = FUTEX_INITIALIZER; 109 170 … … 111 172 atomic_t threads_in_ipc_wait = { 0 }; 112 173 113 typedef struct { 114 awaiter_t wdata; 115 116 /** If reply was received. */ 117 bool done; 118 119 /** Pointer to where the answer data is stored. */ 120 ipc_call_t *dataptr; 121 122 sysarg_t retval; 123 } amsg_t; 124 125 /** 126 * Structures of this type are used to group information about 127 * a call and about a message queue link. 128 */ 174 /** Naming service session */ 175 async_sess_t *session_ns; 176 177 /** Call data */ 129 178 typedef struct { 130 179 link_t link; 180 131 181 ipc_callid_t callid; 132 182 ipc_call_t call; 133 183 } msg_t; 134 184 185 /** Message data */ 135 186 typedef struct { 136 sysarg_t in_task_hash; 187 awaiter_t wdata; 188 189 /** If reply was received. */ 190 bool done; 191 192 /** Pointer to where the answer data is stored. */ 193 ipc_call_t *dataptr; 194 195 sysarg_t retval; 196 } amsg_t; 197 198 /* Client connection data */ 199 typedef struct { 137 200 link_t link; 138 int refcnt; 201 202 task_id_t in_task_id; 203 atomic_t refcnt; 139 204 void *data; 140 205 } client_t; 141 206 207 /* Server connection data */ 142 208 typedef struct { 143 209 awaiter_t wdata; … … 146 212 link_t link; 147 213 148 /** Incoming client task hash. */ 149 sysarg_t in_task_hash; 214 /** Incoming client task ID. */ 215 task_id_t in_task_id; 216 150 217 /** Incoming phone hash. */ 151 218 sysarg_t in_phone_hash; … … 155 222 156 223 /** Messages that should be delivered to this fibril. */ 157 li nk_t msg_queue;224 list_t msg_queue; 158 225 159 226 /** Identification of the opening call. */ … … 161 228 /** Call data of the opening call. */ 162 229 ipc_call_t call; 230 /** Local argument or NULL if none. */ 231 void *carg; 163 232 164 233 /** Identification of the closing call. */ … … 166 235 167 236 /** Fibril function that will be used to handle the connection. */ 168 void (*cfibril)(ipc_callid_t, ipc_call_t *);237 async_client_conn_t cfibril; 169 238 } connection_t; 170 239 171 240 /** Identifier of the incoming connection handled by the current fibril. */ 172 static fibril_local connection_t * FIBRIL_connection;241 static fibril_local connection_t *fibril_connection; 173 242 174 243 static void *default_client_data_constructor(void) … … 196 265 } 197 266 198 void *async_client_data_get(void)199 {200 assert(FIBRIL_connection);201 return FIBRIL_connection->client->data;202 }203 204 267 /** Default fibril function that gets called to handle new connection. 205 268 * … … 208 271 * @param callid Hash of the incoming call. 209 272 * @param call Data of the incoming call. 210 * 211 */ 212 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call) 273 * @param arg Local argument 274 * 275 */ 276 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call, 277 void *arg) 213 278 { 214 279 ipc_answer_0(callid, ENOENT); 215 280 } 216 217 /**218 * Pointer to a fibril function that will be used to handle connections.219 */220 static async_client_conn_t client_connection = default_client_connection;221 281 222 282 /** Default fibril function that gets called to handle interrupt notifications. … … 226 286 * @param callid Hash of the incoming call. 227 287 * @param call Data of the incoming call. 288 * @param arg Local argument. 228 289 * 229 290 */ … … 232 293 } 233 294 234 /** 235 * Pointer to a fibril function that will be used to handle interrupt 236 * notifications. 237 */ 238 static async_client_conn_t interrupt_received = default_interrupt_received; 295 static async_client_conn_t client_connection = default_client_connection; 296 static async_interrupt_handler_t interrupt_received = default_interrupt_received; 297 298 /** Setter for client_connection function pointer. 299 * 300 * @param conn Function that will implement a new connection fibril. 301 * 302 */ 303 void async_set_client_connection(async_client_conn_t conn) 304 { 305 client_connection = conn; 306 } 307 308 /** Setter for interrupt_received function pointer. 309 * 310 * @param intr Function that will implement a new interrupt 311 * notification fibril. 312 */ 313 void async_set_interrupt_received(async_interrupt_handler_t intr) 314 { 315 interrupt_received = intr; 316 } 317 318 /** Mutex protecting inactive_exch_list and avail_phone_cv. 319 * 320 */ 321 static FIBRIL_MUTEX_INITIALIZE(async_sess_mutex); 322 323 /** List of all currently inactive exchanges. 324 * 325 */ 326 static LIST_INITIALIZE(inactive_exch_list); 327 328 /** Condition variable to wait for a phone to become available. 329 * 330 */ 331 static FIBRIL_CONDVAR_INITIALIZE(avail_phone_cv); 239 332 240 333 static hash_table_t client_hash_table; … … 242 335 static LIST_INITIALIZE(timeout_list); 243 336 244 #define CLIENT_HASH_TABLE_BUCKETS 32245 #define CONN_HASH_TABLE_BUCKETS 32246 247 337 static hash_index_t client_hash(unsigned long key[]) 248 338 { 249 339 assert(key); 340 250 341 return (((key[0]) >> 4) % CLIENT_HASH_TABLE_BUCKETS); 251 342 } … … 253 344 static int client_compare(unsigned long key[], hash_count_t keys, link_t *item) 254 345 { 346 assert(key); 347 assert(keys == 2); 348 assert(item); 349 255 350 client_t *client = hash_table_get_instance(item, client_t, link); 256 return (key[0] == client->in_task_hash); 351 return (key[0] == LOWER32(client->in_task_id) && 352 (key[1] == UPPER32(client->in_task_id))); 257 353 } 258 354 … … 278 374 { 279 375 assert(key); 376 280 377 return (((key[0]) >> 4) % CONN_HASH_TABLE_BUCKETS); 281 378 } … … 292 389 static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item) 293 390 { 391 assert(key); 392 assert(item); 393 294 394 connection_t *conn = hash_table_get_instance(item, connection_t, link); 295 395 return (key[0] == conn->in_phone_hash); … … 314 414 void async_insert_timeout(awaiter_t *wd) 315 415 { 416 assert(wd); 417 316 418 wd->to_event.occurred = false; 317 419 wd->to_event.inlist = true; 318 420 319 link_t *tmp = timeout_list. next;320 while (tmp != &timeout_list ) {421 link_t *tmp = timeout_list.head.next; 422 while (tmp != &timeout_list.head) { 321 423 awaiter_t *cur 322 424 = list_get_instance(tmp, awaiter_t, to_event.link); … … 328 430 } 329 431 330 list_ append(&wd->to_event.link, tmp);432 list_insert_before(&wd->to_event.link, tmp); 331 433 } 332 434 … … 346 448 static bool route_call(ipc_callid_t callid, ipc_call_t *call) 347 449 { 450 assert(call); 451 348 452 futex_down(&async_futex); 349 453 … … 400 504 static int notification_fibril(void *arg) 401 505 { 506 assert(arg); 507 402 508 msg_t *msg = (msg_t *) arg; 403 509 interrupt_received(msg->callid, &msg->call); … … 420 526 static bool process_notification(ipc_callid_t callid, ipc_call_t *call) 421 527 { 528 assert(call); 529 422 530 futex_down(&async_futex); 423 531 … … 458 566 ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs) 459 567 { 460 assert(FIBRIL_connection); 568 assert(call); 569 assert(fibril_connection); 461 570 462 571 /* Why doing this? 463 * GCC 4.1.0 coughs on FIBRIL_connection-> dereference.572 * GCC 4.1.0 coughs on fibril_connection-> dereference. 464 573 * GCC 4.1.1 happilly puts the rdhwr instruction in delay slot. 465 574 * I would never expect to find so many errors in 466 575 * a compiler. 467 576 */ 468 connection_t *conn = FIBRIL_connection;577 connection_t *conn = fibril_connection; 469 578 470 579 futex_down(&async_futex); … … 518 627 } 519 628 520 msg_t *msg = list_get_instance( conn->msg_queue.next, msg_t, link);629 msg_t *msg = list_get_instance(list_first(&conn->msg_queue), msg_t, link); 521 630 list_remove(&msg->link); 522 631 … … 529 638 } 530 639 640 static client_t *async_client_get(task_id_t client_id, bool create) 641 { 642 unsigned long key[2] = { 643 LOWER32(client_id), 644 UPPER32(client_id), 645 }; 646 client_t *client = NULL; 647 648 futex_down(&async_futex); 649 link_t *lnk = hash_table_find(&client_hash_table, key); 650 if (lnk) { 651 client = hash_table_get_instance(lnk, client_t, link); 652 atomic_inc(&client->refcnt); 653 } else if (create) { 654 client = malloc(sizeof(client_t)); 655 if (client) { 656 client->in_task_id = client_id; 657 client->data = async_client_data_create(); 658 659 atomic_set(&client->refcnt, 1); 660 hash_table_insert(&client_hash_table, key, &client->link); 661 } 662 } 663 664 futex_up(&async_futex); 665 return client; 666 } 667 668 static void async_client_put(client_t *client) 669 { 670 bool destroy; 671 unsigned long key[2] = { 672 LOWER32(client->in_task_id), 673 UPPER32(client->in_task_id) 674 }; 675 676 futex_down(&async_futex); 677 678 if (atomic_predec(&client->refcnt) == 0) { 679 hash_table_remove(&client_hash_table, key, 2); 680 destroy = true; 681 } else 682 destroy = false; 683 684 futex_up(&async_futex); 685 686 if (destroy) { 687 if (client->data) 688 async_client_data_destroy(client->data); 689 690 free(client); 691 } 692 } 693 694 void *async_get_client_data(void) 695 { 696 assert(fibril_connection); 697 return fibril_connection->client->data; 698 } 699 700 void *async_get_client_data_by_id(task_id_t client_id) 701 { 702 client_t *client = async_client_get(client_id, false); 703 if (!client) 704 return NULL; 705 if (!client->data) { 706 async_client_put(client); 707 return NULL; 708 } 709 710 return client->data; 711 } 712 713 void async_put_client_data_by_id(task_id_t client_id) 714 { 715 client_t *client = async_client_get(client_id, false); 716 717 assert(client); 718 assert(client->data); 719 720 /* Drop the reference we got in async_get_client_data_by_hash(). */ 721 async_client_put(client); 722 723 /* Drop our own reference we got at the beginning of this function. */ 724 async_client_put(client); 725 } 726 531 727 /** Wrapper for client connection fibril. 532 728 * … … 541 737 static int connection_fibril(void *arg) 542 738 { 739 assert(arg); 740 543 741 /* 544 742 * Setup fibril-local connection pointer. 545 743 */ 546 FIBRIL_connection = (connection_t *) arg; 547 548 futex_down(&async_futex); 744 fibril_connection = (connection_t *) arg; 549 745 550 746 /* … … 553 749 * hash in a new tracking structure. 554 750 */ 555 556 unsigned long key = FIBRIL_connection->in_task_hash; 557 link_t *lnk = hash_table_find(&client_hash_table, &key); 558 559 client_t *client; 560 561 if (lnk) { 562 client = hash_table_get_instance(lnk, client_t, link); 563 client->refcnt++; 564 } else { 565 client = malloc(sizeof(client_t)); 566 if (!client) { 567 ipc_answer_0(FIBRIL_connection->callid, ENOMEM); 568 futex_up(&async_futex); 569 return 0; 570 } 571 572 client->in_task_hash = FIBRIL_connection->in_task_hash; 573 574 async_serialize_start(); 575 client->data = async_client_data_create(); 576 async_serialize_end(); 577 578 client->refcnt = 1; 579 hash_table_insert(&client_hash_table, &key, &client->link); 580 } 581 582 futex_up(&async_futex); 583 584 FIBRIL_connection->client = client; 751 752 client_t *client = async_client_get(fibril_connection->in_task_id, true); 753 if (!client) { 754 ipc_answer_0(fibril_connection->callid, ENOMEM); 755 return 0; 756 } 757 758 fibril_connection->client = client; 585 759 586 760 /* 587 761 * Call the connection handler function. 588 762 */ 589 FIBRIL_connection->cfibril(FIBRIL_connection->callid,590 & FIBRIL_connection->call);763 fibril_connection->cfibril(fibril_connection->callid, 764 &fibril_connection->call, fibril_connection->carg); 591 765 592 766 /* 593 767 * Remove the reference for this client task connection. 594 768 */ 595 bool destroy; 596 597 futex_down(&async_futex); 598 599 if (--client->refcnt == 0) { 600 hash_table_remove(&client_hash_table, &key, 1); 601 destroy = true; 602 } else 603 destroy = false; 604 605 futex_up(&async_futex); 606 607 if (destroy) { 608 if (client->data) 609 async_client_data_destroy(client->data); 610 611 free(client); 612 } 769 async_client_put(client); 613 770 614 771 /* … … 616 773 */ 617 774 futex_down(&async_futex); 618 key = FIBRIL_connection->in_phone_hash;775 unsigned long key = fibril_connection->in_phone_hash; 619 776 hash_table_remove(&conn_hash_table, &key, 1); 620 777 futex_up(&async_futex); … … 623 780 * Answer all remaining messages with EHANGUP. 624 781 */ 625 while (!list_empty(& FIBRIL_connection->msg_queue)) {782 while (!list_empty(&fibril_connection->msg_queue)) { 626 783 msg_t *msg = 627 list_get_instance( FIBRIL_connection->msg_queue.next, msg_t,628 link);784 list_get_instance(list_first(&fibril_connection->msg_queue), 785 msg_t, link); 629 786 630 787 list_remove(&msg->link); … … 637 794 * i.e. IPC_M_PHONE_HUNGUP. 638 795 */ 639 if ( FIBRIL_connection->close_callid)640 ipc_answer_0( FIBRIL_connection->close_callid, EOK);641 642 free( FIBRIL_connection);796 if (fibril_connection->close_callid) 797 ipc_answer_0(fibril_connection->close_callid, EOK); 798 799 free(fibril_connection); 643 800 return 0; 644 801 } … … 646 803 /** Create a new fibril for a new connection. 647 804 * 648 * Create new fibril for connection, fill in connection structures and insert s805 * Create new fibril for connection, fill in connection structures and insert 649 806 * it into the hash table, so that later we can easily do routing of messages to 650 807 * particular fibrils. 651 808 * 652 * @param in_task_ hashIdentification of the incoming connection.809 * @param in_task_id Identification of the incoming connection. 653 810 * @param in_phone_hash Identification of the incoming connection. 654 811 * @param callid Hash of the opening IPC_M_CONNECT_ME_TO call. … … 659 816 * @param cfibril Fibril function that should be called upon opening the 660 817 * connection. 818 * @param carg Extra argument to pass to the connection fibril 661 819 * 662 820 * @return New fibril id or NULL on failure. 663 821 * 664 822 */ 665 fid_t async_new_connection( sysarg_t in_task_hash, sysarg_t in_phone_hash,823 fid_t async_new_connection(task_id_t in_task_id, sysarg_t in_phone_hash, 666 824 ipc_callid_t callid, ipc_call_t *call, 667 void (*cfibril)(ipc_callid_t, ipc_call_t *))825 async_client_conn_t cfibril, void *carg) 668 826 { 669 827 connection_t *conn = malloc(sizeof(*conn)); … … 675 833 } 676 834 677 conn->in_task_ hash = in_task_hash;835 conn->in_task_id = in_task_id; 678 836 conn->in_phone_hash = in_phone_hash; 679 837 list_initialize(&conn->msg_queue); 680 838 conn->callid = callid; 681 839 conn->close_callid = 0; 840 conn->carg = carg; 682 841 683 842 if (call) … … 721 880 static void handle_call(ipc_callid_t callid, ipc_call_t *call) 722 881 { 882 assert(call); 883 723 884 /* Unrouted call - take some default action */ 724 885 if ((callid & IPC_CALLID_NOTIFICATION)) { … … 731 892 case IPC_M_CONNECT_ME_TO: 732 893 /* Open new connection with fibril, etc. */ 733 async_new_connection(call->in_task_ hash, IPC_GET_ARG5(*call),734 callid, call, client_connection );894 async_new_connection(call->in_task_id, IPC_GET_ARG5(*call), 895 callid, call, client_connection, NULL); 735 896 return; 736 897 } … … 752 913 futex_down(&async_futex); 753 914 754 link_t *cur = timeout_list.next;755 while (cur != &timeout_list) {915 link_t *cur = list_first(&timeout_list); 916 while (cur != NULL) { 756 917 awaiter_t *waiter = 757 918 list_get_instance(cur, awaiter_t, to_event.link); … … 759 920 if (tv_gt(&waiter->to_event.expires, &tv)) 760 921 break; 761 762 cur = cur->next;763 922 764 923 list_remove(&waiter->to_event.link); … … 774 933 fibril_add_ready(waiter->fid); 775 934 } 935 936 cur = list_first(&timeout_list); 776 937 } 777 938 … … 800 961 suseconds_t timeout; 801 962 if (!list_empty(&timeout_list)) { 802 awaiter_t *waiter = list_get_instance( timeout_list.next,803 awaiter_t, to_event.link);963 awaiter_t *waiter = list_get_instance( 964 list_first(&timeout_list), awaiter_t, to_event.link); 804 965 805 966 struct timeval tv; … … 878 1039 void __async_init(void) 879 1040 { 880 if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 1,881 &client_hash_table_ops))1041 if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 1042 2, &client_hash_table_ops)) 882 1043 abort(); 883 1044 884 if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS, 1,885 &conn_hash_table_ops))1045 if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS, 1046 1, &conn_hash_table_ops)) 886 1047 abort(); 1048 1049 session_ns = (async_sess_t *) malloc(sizeof(async_sess_t)); 1050 if (session_ns == NULL) 1051 abort(); 1052 1053 session_ns->mgmt = EXCHANGE_ATOMIC; 1054 session_ns->phone = PHONE_NS; 1055 session_ns->arg1 = 0; 1056 session_ns->arg2 = 0; 1057 session_ns->arg3 = 0; 1058 1059 fibril_mutex_initialize(&session_ns->remote_state_mtx); 1060 session_ns->remote_state_data = NULL; 1061 1062 list_initialize(&session_ns->exch_list); 1063 fibril_mutex_initialize(&session_ns->mutex); 1064 atomic_set(&session_ns->refcnt, 0); 887 1065 } 888 1066 … … 899 1077 * 900 1078 */ 901 static void reply_received(void *arg, int retval, ipc_call_t *data) 902 { 1079 void reply_received(void *arg, int retval, ipc_call_t *data) 1080 { 1081 assert(arg); 1082 903 1083 futex_down(&async_futex); 904 1084 … … 930 1110 * completion. 931 1111 * 932 * @param phoneid Handle of the phone that will be used for the send.933 * @param method Service-defined method.1112 * @param exch Exchange for sending the message. 1113 * @param imethod Service-defined interface and method. 934 1114 * @param arg1 Service-defined payload argument. 935 1115 * @param arg2 Service-defined payload argument. … … 942 1122 * 943 1123 */ 944 aid_t async_send_fast( int phoneid, sysarg_tmethod, sysarg_t arg1,1124 aid_t async_send_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, 945 1125 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr) 946 1126 { 1127 if (exch == NULL) 1128 return 0; 1129 947 1130 amsg_t *msg = malloc(sizeof(amsg_t)); 948 949 if (!msg) 1131 if (msg == NULL) 950 1132 return 0; 951 1133 … … 961 1143 msg->wdata.active = true; 962 1144 963 ipc_call_async_4( phoneid,method, arg1, arg2, arg3, arg4, msg,1145 ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4, msg, 964 1146 reply_received, true); 965 1147 … … 972 1154 * completion. 973 1155 * 974 * @param phoneid Handle of the phone that will be used for the send.975 * @param method Service-defined method.1156 * @param exch Exchange for sending the message. 1157 * @param imethod Service-defined interface and method. 976 1158 * @param arg1 Service-defined payload argument. 977 1159 * @param arg2 Service-defined payload argument. … … 985 1167 * 986 1168 */ 987 aid_t async_send_slow( int phoneid, sysarg_tmethod, sysarg_t arg1,1169 aid_t async_send_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, 988 1170 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, 989 1171 ipc_call_t *dataptr) 990 1172 { 1173 if (exch == NULL) 1174 return 0; 1175 991 1176 amsg_t *msg = malloc(sizeof(amsg_t)); 992 1177 993 if ( !msg)1178 if (msg == NULL) 994 1179 return 0; 995 1180 … … 1005 1190 msg->wdata.active = true; 1006 1191 1007 ipc_call_async_5( phoneid, method, arg1, arg2, arg3, arg4, arg5, msg,1008 reply_received, true);1192 ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4, arg5, 1193 msg, reply_received, true); 1009 1194 1010 1195 return (aid_t) msg; … … 1020 1205 void async_wait_for(aid_t amsgid, sysarg_t *retval) 1021 1206 { 1207 assert(amsgid); 1208 1022 1209 amsg_t *msg = (amsg_t *) amsgid; 1023 1210 … … 1056 1243 int async_wait_timeout(aid_t amsgid, sysarg_t *retval, suseconds_t timeout) 1057 1244 { 1245 assert(amsgid); 1246 1058 1247 amsg_t *msg = (amsg_t *) amsgid; 1059 1248 … … 1124 1313 } 1125 1314 1126 /** Setter for client_connection function pointer.1127 *1128 * @param conn Function that will implement a new connection fibril.1129 *1130 */1131 void async_set_client_connection(async_client_conn_t conn)1132 {1133 client_connection = conn;1134 }1135 1136 /** Setter for interrupt_received function pointer.1137 *1138 * @param intr Function that will implement a new interrupt1139 * notification fibril.1140 */1141 void async_set_interrupt_received(async_client_conn_t intr)1142 {1143 interrupt_received = intr;1144 }1145 1146 1315 /** Pseudo-synchronous message sending - fast version. 1147 1316 * … … 1151 1320 * transferring more arguments, see the slower async_req_slow(). 1152 1321 * 1153 * @param phoneid Hash of the phone through which to make the call.1154 * @param method Method of the call.1322 * @param exch Exchange for sending the message. 1323 * @param imethod Interface and method of the call. 1155 1324 * @param arg1 Service-defined payload argument. 1156 1325 * @param arg2 Service-defined payload argument. … … 1166 1335 * 1167 1336 */ 1168 sysarg_t async_req_fast( int phoneid, sysarg_tmethod, sysarg_t arg1,1337 sysarg_t async_req_fast(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, 1169 1338 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2, 1170 1339 sysarg_t *r3, sysarg_t *r4, sysarg_t *r5) 1171 1340 { 1341 if (exch == NULL) 1342 return ENOENT; 1343 1172 1344 ipc_call_t result; 1173 aid_t eid = async_send_4(phoneid,method, arg1, arg2, arg3, arg4,1345 aid_t aid = async_send_4(exch, imethod, arg1, arg2, arg3, arg4, 1174 1346 &result); 1175 1347 1176 1348 sysarg_t rc; 1177 async_wait_for( eid, &rc);1349 async_wait_for(aid, &rc); 1178 1350 1179 1351 if (r1) … … 1199 1371 * Send message asynchronously and return only after the reply arrives. 1200 1372 * 1201 * @param phoneid Hash of the phone through which to make the call.1202 * @param method Method of the call.1373 * @param exch Exchange for sending the message. 1374 * @param imethod Interface and method of the call. 1203 1375 * @param arg1 Service-defined payload argument. 1204 1376 * @param arg2 Service-defined payload argument. … … 1215 1387 * 1216 1388 */ 1217 sysarg_t async_req_slow( int phoneid, sysarg_tmethod, sysarg_t arg1,1389 sysarg_t async_req_slow(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, 1218 1390 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1, 1219 1391 sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5) 1220 1392 { 1393 if (exch == NULL) 1394 return ENOENT; 1395 1221 1396 ipc_call_t result; 1222 aid_t eid = async_send_5(phoneid,method, arg1, arg2, arg3, arg4, arg5,1397 aid_t aid = async_send_5(exch, imethod, arg1, arg2, arg3, arg4, arg5, 1223 1398 &result); 1224 1399 1225 1400 sysarg_t rc; 1226 async_wait_for( eid, &rc);1401 async_wait_for(aid, &rc); 1227 1402 1228 1403 if (r1) … … 1244 1419 } 1245 1420 1246 void async_msg_0(int phone, sysarg_t imethod) 1247 { 1248 ipc_call_async_0(phone, imethod, NULL, NULL, true); 1249 } 1250 1251 void async_msg_1(int phone, sysarg_t imethod, sysarg_t arg1) 1252 { 1253 ipc_call_async_1(phone, imethod, arg1, NULL, NULL, true); 1254 } 1255 1256 void async_msg_2(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2) 1257 { 1258 ipc_call_async_2(phone, imethod, arg1, arg2, NULL, NULL, true); 1259 } 1260 1261 void async_msg_3(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, 1262 sysarg_t arg3) 1263 { 1264 ipc_call_async_3(phone, imethod, arg1, arg2, arg3, NULL, NULL, true); 1265 } 1266 1267 void async_msg_4(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, 1268 sysarg_t arg3, sysarg_t arg4) 1269 { 1270 ipc_call_async_4(phone, imethod, arg1, arg2, arg3, arg4, NULL, NULL, 1271 true); 1272 } 1273 1274 void async_msg_5(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, 1275 sysarg_t arg3, sysarg_t arg4, sysarg_t arg5) 1276 { 1277 ipc_call_async_5(phone, imethod, arg1, arg2, arg3, arg4, arg5, NULL, 1278 NULL, true); 1421 void async_msg_0(async_exch_t *exch, sysarg_t imethod) 1422 { 1423 if (exch != NULL) 1424 ipc_call_async_0(exch->phone, imethod, NULL, NULL, true); 1425 } 1426 1427 void async_msg_1(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1) 1428 { 1429 if (exch != NULL) 1430 ipc_call_async_1(exch->phone, imethod, arg1, NULL, NULL, true); 1431 } 1432 1433 void async_msg_2(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, 1434 sysarg_t arg2) 1435 { 1436 if (exch != NULL) 1437 ipc_call_async_2(exch->phone, imethod, arg1, arg2, NULL, NULL, 1438 true); 1439 } 1440 1441 void async_msg_3(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, 1442 sysarg_t arg2, sysarg_t arg3) 1443 { 1444 if (exch != NULL) 1445 ipc_call_async_3(exch->phone, imethod, arg1, arg2, arg3, NULL, 1446 NULL, true); 1447 } 1448 1449 void async_msg_4(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, 1450 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4) 1451 { 1452 if (exch != NULL) 1453 ipc_call_async_4(exch->phone, imethod, arg1, arg2, arg3, arg4, 1454 NULL, NULL, true); 1455 } 1456 1457 void async_msg_5(async_exch_t *exch, sysarg_t imethod, sysarg_t arg1, 1458 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5) 1459 { 1460 if (exch != NULL) 1461 ipc_call_async_5(exch->phone, imethod, arg1, arg2, arg3, arg4, 1462 arg5, NULL, NULL, true); 1279 1463 } 1280 1464 … … 1313 1497 } 1314 1498 1315 int async_forward_fast(ipc_callid_t callid, int phoneid, sysarg_t imethod, 1316 sysarg_t arg1, sysarg_t arg2, unsigned int mode) 1317 { 1318 return ipc_forward_fast(callid, phoneid, imethod, arg1, arg2, mode); 1319 } 1320 1321 int async_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod, 1322 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, 1323 unsigned int mode) 1324 { 1325 return ipc_forward_slow(callid, phoneid, imethod, arg1, arg2, arg3, arg4, 1326 arg5, mode); 1499 int async_forward_fast(ipc_callid_t callid, async_exch_t *exch, 1500 sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, unsigned int mode) 1501 { 1502 if (exch == NULL) 1503 return ENOENT; 1504 1505 return ipc_forward_fast(callid, exch->phone, imethod, arg1, arg2, mode); 1506 } 1507 1508 int async_forward_slow(ipc_callid_t callid, async_exch_t *exch, 1509 sysarg_t imethod, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, 1510 sysarg_t arg4, sysarg_t arg5, unsigned int mode) 1511 { 1512 if (exch == NULL) 1513 return ENOENT; 1514 1515 return ipc_forward_slow(callid, exch->phone, imethod, arg1, arg2, arg3, 1516 arg4, arg5, mode); 1327 1517 } 1328 1518 … … 1331 1521 * Ask through phone for a new connection to some service. 1332 1522 * 1333 * @param phone Phone handle used for contacting the other side.1523 * @param exch Exchange for sending the message. 1334 1524 * @param arg1 User defined argument. 1335 1525 * @param arg2 User defined argument. … … 1337 1527 * @param client_receiver Connection handing routine. 1338 1528 * 1339 * @return New phone handle on success or a negative error code. 1340 * 1341 */ 1342 int async_connect_to_me(int phone, sysarg_t arg1, sysarg_t arg2, 1343 sysarg_t arg3, async_client_conn_t client_receiver) 1344 { 1345 sysarg_t task_hash; 1529 * @return Zero on success or a negative error code. 1530 * 1531 */ 1532 int async_connect_to_me(async_exch_t *exch, sysarg_t arg1, sysarg_t arg2, 1533 sysarg_t arg3, async_client_conn_t client_receiver, void *carg) 1534 { 1535 if (exch == NULL) 1536 return ENOENT; 1537 1346 1538 sysarg_t phone_hash; 1347 int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, 1348 NULL, NULL, NULL, &task_hash, &phone_hash); 1539 sysarg_t rc; 1540 1541 aid_t req; 1542 ipc_call_t answer; 1543 req = async_send_3(exch, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, 1544 &answer); 1545 async_wait_for(req, &rc); 1546 if (rc != EOK) 1547 return (int) rc; 1548 1549 phone_hash = IPC_GET_ARG5(answer); 1550 1551 if (client_receiver != NULL) 1552 async_new_connection(answer.in_task_id, phone_hash, 0, NULL, 1553 client_receiver, carg); 1554 1555 return EOK; 1556 } 1557 1558 /** Wrapper for making IPC_M_CONNECT_ME calls using the async framework. 1559 * 1560 * Ask through for a cloned connection to some service. 1561 * 1562 * @param mgmt Exchange management style. 1563 * @param exch Exchange for sending the message. 1564 * 1565 * @return New session on success or NULL on error. 1566 * 1567 */ 1568 async_sess_t *async_connect_me(exch_mgmt_t mgmt, async_exch_t *exch) 1569 { 1570 if (exch == NULL) { 1571 errno = ENOENT; 1572 return NULL; 1573 } 1574 1575 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 1576 if (sess == NULL) { 1577 errno = ENOMEM; 1578 return NULL; 1579 } 1580 1581 ipc_call_t result; 1582 1583 amsg_t *msg = malloc(sizeof(amsg_t)); 1584 if (msg == NULL) { 1585 free(sess); 1586 errno = ENOMEM; 1587 return NULL; 1588 } 1589 1590 msg->done = false; 1591 msg->dataptr = &result; 1592 1593 msg->wdata.to_event.inlist = false; 1594 1595 /* 1596 * We may sleep in the next method, 1597 * but it will use its own means 1598 */ 1599 msg->wdata.active = true; 1600 1601 ipc_call_async_0(exch->phone, IPC_M_CONNECT_ME, msg, 1602 reply_received, true); 1603 1604 sysarg_t rc; 1605 async_wait_for((aid_t) msg, &rc); 1606 1607 if (rc != EOK) { 1608 errno = rc; 1609 free(sess); 1610 return NULL; 1611 } 1612 1613 int phone = (int) IPC_GET_ARG5(result); 1614 1615 if (phone < 0) { 1616 errno = phone; 1617 free(sess); 1618 return NULL; 1619 } 1620 1621 sess->mgmt = mgmt; 1622 sess->phone = phone; 1623 sess->arg1 = 0; 1624 sess->arg2 = 0; 1625 sess->arg3 = 0; 1626 1627 fibril_mutex_initialize(&sess->remote_state_mtx); 1628 sess->remote_state_data = NULL; 1629 1630 list_initialize(&sess->exch_list); 1631 fibril_mutex_initialize(&sess->mutex); 1632 atomic_set(&sess->refcnt, 0); 1633 1634 return sess; 1635 } 1636 1637 static int async_connect_me_to_internal(int phone, sysarg_t arg1, sysarg_t arg2, 1638 sysarg_t arg3, sysarg_t arg4) 1639 { 1640 ipc_call_t result; 1641 1642 amsg_t *msg = malloc(sizeof(amsg_t)); 1643 if (msg == NULL) 1644 return ENOENT; 1645 1646 msg->done = false; 1647 msg->dataptr = &result; 1648 1649 msg->wdata.to_event.inlist = false; 1650 1651 /* 1652 * We may sleep in the next method, 1653 * but it will use its own means 1654 */ 1655 msg->wdata.active = true; 1656 1657 ipc_call_async_4(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, arg4, 1658 msg, reply_received, true); 1659 1660 sysarg_t rc; 1661 async_wait_for((aid_t) msg, &rc); 1662 1349 1663 if (rc != EOK) 1350 1664 return rc; 1351 1665 1352 if (client_receiver != NULL) 1353 async_new_connection(task_hash, phone_hash, 0, NULL, 1354 client_receiver); 1355 1356 return EOK; 1666 return (int) IPC_GET_ARG5(result); 1357 1667 } 1358 1668 1359 1669 /** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework. 1360 1670 * 1361 * Ask through phone for a new connection to some service. 1362 * 1363 * @param phone Phone handle used for contacting the other side. 1364 * @param arg1 User defined argument. 1365 * @param arg2 User defined argument. 1366 * @param arg3 User defined argument. 1367 * 1368 * @return New phone handle on success or a negative error code. 1369 * 1370 */ 1371 int async_connect_me_to(int phone, sysarg_t arg1, sysarg_t arg2, 1671 * Ask through for a new connection to some service. 1672 * 1673 * @param mgmt Exchange management style. 1674 * @param exch Exchange for sending the message. 1675 * @param arg1 User defined argument. 1676 * @param arg2 User defined argument. 1677 * @param arg3 User defined argument. 1678 * 1679 * @return New session on success or NULL on error. 1680 * 1681 */ 1682 async_sess_t *async_connect_me_to(exch_mgmt_t mgmt, async_exch_t *exch, 1683 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3) 1684 { 1685 if (exch == NULL) { 1686 errno = ENOENT; 1687 return NULL; 1688 } 1689 1690 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 1691 if (sess == NULL) { 1692 errno = ENOMEM; 1693 return NULL; 1694 } 1695 1696 int phone = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3, 1697 0); 1698 1699 if (phone < 0) { 1700 errno = phone; 1701 free(sess); 1702 return NULL; 1703 } 1704 1705 sess->mgmt = mgmt; 1706 sess->phone = phone; 1707 sess->arg1 = arg1; 1708 sess->arg2 = arg2; 1709 sess->arg3 = arg3; 1710 1711 fibril_mutex_initialize(&sess->remote_state_mtx); 1712 sess->remote_state_data = NULL; 1713 1714 list_initialize(&sess->exch_list); 1715 fibril_mutex_initialize(&sess->mutex); 1716 atomic_set(&sess->refcnt, 0); 1717 1718 return sess; 1719 } 1720 1721 /** Set arguments for new connections. 1722 * 1723 * FIXME This is an ugly hack to work around the problem that parallel 1724 * exchanges are implemented using parallel connections. When we create 1725 * a callback session, the framework does not know arguments for the new 1726 * connections. 1727 * 1728 * The proper solution seems to be to implement parallel exchanges using 1729 * tagging. 1730 */ 1731 void async_sess_args_set(async_sess_t *sess, sysarg_t arg1, sysarg_t arg2, 1372 1732 sysarg_t arg3) 1373 1733 { 1374 sysarg_t newphid; 1375 int rc = async_req_3_5(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, 1376 NULL, NULL, NULL, NULL, &newphid); 1377 1378 if (rc != EOK) 1379 return rc; 1380 1381 return newphid; 1734 sess->arg1 = arg1; 1735 sess->arg2 = arg2; 1736 sess->arg3 = arg3; 1382 1737 } 1383 1738 … … 1387 1742 * success. 1388 1743 * 1389 * @param phoneid Phone handle used for contacting the other side. 1390 * @param arg1 User defined argument. 1391 * @param arg2 User defined argument. 1392 * @param arg3 User defined argument. 1393 * 1394 * @return New phone handle on success or a negative error code. 1395 * 1396 */ 1397 int async_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2, 1398 sysarg_t arg3) 1399 { 1400 sysarg_t newphid; 1401 int rc = async_req_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, 1402 IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid); 1403 1404 if (rc != EOK) 1405 return rc; 1406 1407 return newphid; 1744 * @param mgmt Exchange management style. 1745 * @param exch Exchange for sending the message. 1746 * @param arg1 User defined argument. 1747 * @param arg2 User defined argument. 1748 * @param arg3 User defined argument. 1749 * 1750 * @return New session on success or NULL on error. 1751 * 1752 */ 1753 async_sess_t *async_connect_me_to_blocking(exch_mgmt_t mgmt, async_exch_t *exch, 1754 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3) 1755 { 1756 if (exch == NULL) { 1757 errno = ENOENT; 1758 return NULL; 1759 } 1760 1761 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 1762 if (sess == NULL) { 1763 errno = ENOMEM; 1764 return NULL; 1765 } 1766 1767 int phone = async_connect_me_to_internal(exch->phone, arg1, arg2, arg3, 1768 IPC_FLAG_BLOCKING); 1769 1770 if (phone < 0) { 1771 errno = phone; 1772 free(sess); 1773 return NULL; 1774 } 1775 1776 sess->mgmt = mgmt; 1777 sess->phone = phone; 1778 sess->arg1 = arg1; 1779 sess->arg2 = arg2; 1780 sess->arg3 = arg3; 1781 1782 fibril_mutex_initialize(&sess->remote_state_mtx); 1783 sess->remote_state_data = NULL; 1784 1785 list_initialize(&sess->exch_list); 1786 fibril_mutex_initialize(&sess->mutex); 1787 atomic_set(&sess->refcnt, 0); 1788 1789 return sess; 1408 1790 } 1409 1791 … … 1411 1793 * 1412 1794 */ 1413 int async_connect_kbox(task_id_t id) 1414 { 1415 return ipc_connect_kbox(id); 1795 async_sess_t *async_connect_kbox(task_id_t id) 1796 { 1797 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 1798 if (sess == NULL) { 1799 errno = ENOMEM; 1800 return NULL; 1801 } 1802 1803 int phone = ipc_connect_kbox(id); 1804 if (phone < 0) { 1805 errno = phone; 1806 free(sess); 1807 return NULL; 1808 } 1809 1810 sess->mgmt = EXCHANGE_ATOMIC; 1811 sess->phone = phone; 1812 sess->arg1 = 0; 1813 sess->arg2 = 0; 1814 sess->arg3 = 0; 1815 1816 fibril_mutex_initialize(&sess->remote_state_mtx); 1817 sess->remote_state_data = NULL; 1818 1819 list_initialize(&sess->exch_list); 1820 fibril_mutex_initialize(&sess->mutex); 1821 atomic_set(&sess->refcnt, 0); 1822 1823 return sess; 1824 } 1825 1826 static int async_hangup_internal(int phone) 1827 { 1828 return ipc_hangup(phone); 1416 1829 } 1417 1830 1418 1831 /** Wrapper for ipc_hangup. 1419 1832 * 1420 * @param phone Phone handleto hung up.1833 * @param sess Session to hung up. 1421 1834 * 1422 1835 * @return Zero on success or a negative error code. 1423 1836 * 1424 1837 */ 1425 int async_hangup(int phone) 1426 { 1427 return ipc_hangup(phone); 1838 int async_hangup(async_sess_t *sess) 1839 { 1840 async_exch_t *exch; 1841 1842 assert(sess); 1843 1844 if (atomic_get(&sess->refcnt) > 0) 1845 return EBUSY; 1846 1847 fibril_mutex_lock(&async_sess_mutex); 1848 1849 int rc = async_hangup_internal(sess->phone); 1850 1851 while (!list_empty(&sess->exch_list)) { 1852 exch = (async_exch_t *) 1853 list_get_instance(list_first(&sess->exch_list), 1854 async_exch_t, sess_link); 1855 1856 list_remove(&exch->sess_link); 1857 list_remove(&exch->global_link); 1858 async_hangup_internal(exch->phone); 1859 free(exch); 1860 } 1861 1862 free(sess); 1863 1864 fibril_mutex_unlock(&async_sess_mutex); 1865 1866 return rc; 1428 1867 } 1429 1868 … … 1434 1873 } 1435 1874 1875 /** Start new exchange in a session. 1876 * 1877 * @param session Session. 1878 * 1879 * @return New exchange or NULL on error. 1880 * 1881 */ 1882 async_exch_t *async_exchange_begin(async_sess_t *sess) 1883 { 1884 if (sess == NULL) 1885 return NULL; 1886 1887 async_exch_t *exch; 1888 1889 fibril_mutex_lock(&async_sess_mutex); 1890 1891 if (!list_empty(&sess->exch_list)) { 1892 /* 1893 * There are inactive exchanges in the session. 1894 */ 1895 exch = (async_exch_t *) 1896 list_get_instance(list_first(&sess->exch_list), 1897 async_exch_t, sess_link); 1898 1899 list_remove(&exch->sess_link); 1900 list_remove(&exch->global_link); 1901 } else { 1902 /* 1903 * There are no available exchanges in the session. 1904 */ 1905 1906 if ((sess->mgmt == EXCHANGE_ATOMIC) || 1907 (sess->mgmt == EXCHANGE_SERIALIZE)) { 1908 exch = (async_exch_t *) malloc(sizeof(async_exch_t)); 1909 if (exch != NULL) { 1910 link_initialize(&exch->sess_link); 1911 link_initialize(&exch->global_link); 1912 exch->sess = sess; 1913 exch->phone = sess->phone; 1914 } 1915 } else { /* EXCHANGE_PARALLEL */ 1916 /* 1917 * Make a one-time attempt to connect a new data phone. 1918 */ 1919 1920 int phone; 1921 1922 retry: 1923 phone = async_connect_me_to_internal(sess->phone, sess->arg1, 1924 sess->arg2, sess->arg3, 0); 1925 if (phone >= 0) { 1926 exch = (async_exch_t *) malloc(sizeof(async_exch_t)); 1927 if (exch != NULL) { 1928 link_initialize(&exch->sess_link); 1929 link_initialize(&exch->global_link); 1930 exch->sess = sess; 1931 exch->phone = phone; 1932 } else 1933 async_hangup_internal(phone); 1934 } else if (!list_empty(&inactive_exch_list)) { 1935 /* 1936 * We did not manage to connect a new phone. But we 1937 * can try to close some of the currently inactive 1938 * connections in other sessions and try again. 1939 */ 1940 exch = (async_exch_t *) 1941 list_get_instance(list_first(&inactive_exch_list), 1942 async_exch_t, global_link); 1943 1944 list_remove(&exch->sess_link); 1945 list_remove(&exch->global_link); 1946 async_hangup_internal(exch->phone); 1947 free(exch); 1948 goto retry; 1949 } else { 1950 /* 1951 * Wait for a phone to become available. 1952 */ 1953 fibril_condvar_wait(&avail_phone_cv, &async_sess_mutex); 1954 goto retry; 1955 } 1956 } 1957 } 1958 1959 fibril_mutex_unlock(&async_sess_mutex); 1960 1961 if (exch != NULL) { 1962 atomic_inc(&sess->refcnt); 1963 1964 if (sess->mgmt == EXCHANGE_SERIALIZE) 1965 fibril_mutex_lock(&sess->mutex); 1966 } 1967 1968 return exch; 1969 } 1970 1971 /** Finish an exchange. 1972 * 1973 * @param exch Exchange to finish. 1974 * 1975 */ 1976 void async_exchange_end(async_exch_t *exch) 1977 { 1978 if (exch == NULL) 1979 return; 1980 1981 async_sess_t *sess = exch->sess; 1982 1983 atomic_dec(&sess->refcnt); 1984 1985 if (sess->mgmt == EXCHANGE_SERIALIZE) 1986 fibril_mutex_unlock(&sess->mutex); 1987 1988 fibril_mutex_lock(&async_sess_mutex); 1989 1990 list_append(&exch->sess_link, &sess->exch_list); 1991 list_append(&exch->global_link, &inactive_exch_list); 1992 fibril_condvar_signal(&avail_phone_cv); 1993 1994 fibril_mutex_unlock(&async_sess_mutex); 1995 } 1996 1436 1997 /** Wrapper for IPC_M_SHARE_IN calls using the async framework. 1437 1998 * 1438 * @param phoneid Phone that will be used to contact the receiving side.1439 * @param dst Destination address space area base.1440 * @param size Size of the destination address space area.1441 * @param arg User defined argument.1442 * @param flags Storage for the received flags. Can be NULL.1999 * @param exch Exchange for sending the message. 2000 * @param dst Destination address space area base. 2001 * @param size Size of the destination address space area. 2002 * @param arg User defined argument. 2003 * @param flags Storage for the received flags. Can be NULL. 1443 2004 * 1444 2005 * @return Zero on success or a negative error code from errno.h. 1445 2006 * 1446 2007 */ 1447 int async_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg, 1448 unsigned int *flags) 1449 { 2008 int async_share_in_start(async_exch_t *exch, void *dst, size_t size, 2009 sysarg_t arg, unsigned int *flags) 2010 { 2011 if (exch == NULL) 2012 return ENOENT; 2013 1450 2014 sysarg_t tmp_flags; 1451 int res = async_req_3_2( phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,2015 int res = async_req_3_2(exch, IPC_M_SHARE_IN, (sysarg_t) dst, 1452 2016 (sysarg_t) size, arg, NULL, &tmp_flags); 1453 2017 … … 1507 2071 /** Wrapper for IPC_M_SHARE_OUT calls using the async framework. 1508 2072 * 1509 * @param phoneid Phone that will be used to contact the receiving side.1510 * @param src Source address space area base address.1511 * @param flags Flags to be used for sharing. Bits can be only cleared.2073 * @param exch Exchange for sending the message. 2074 * @param src Source address space area base address. 2075 * @param flags Flags to be used for sharing. Bits can be only cleared. 1512 2076 * 1513 2077 * @return Zero on success or a negative error code from errno.h. 1514 2078 * 1515 2079 */ 1516 int async_share_out_start(int phoneid, void *src, unsigned int flags) 1517 { 1518 return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0, 2080 int async_share_out_start(async_exch_t *exch, void *src, unsigned int flags) 2081 { 2082 if (exch == NULL) 2083 return ENOENT; 2084 2085 return async_req_3_0(exch, IPC_M_SHARE_OUT, (sysarg_t) src, 0, 1519 2086 (sysarg_t) flags); 1520 2087 } … … 1569 2136 } 1570 2137 2138 /** Start IPC_M_DATA_READ using the async framework. 2139 * 2140 * @param exch Exchange for sending the message. 2141 * @param dst Address of the beginning of the destination buffer. 2142 * @param size Size of the destination buffer (in bytes). 2143 * @param dataptr Storage of call data (arg 2 holds actual data size). 2144 * 2145 * @return Hash of the sent message or 0 on error. 2146 * 2147 */ 2148 aid_t async_data_read(async_exch_t *exch, void *dst, size_t size, 2149 ipc_call_t *dataptr) 2150 { 2151 return async_send_2(exch, IPC_M_DATA_READ, (sysarg_t) dst, 2152 (sysarg_t) size, dataptr); 2153 } 2154 1571 2155 /** Wrapper for IPC_M_DATA_READ calls using the async framework. 1572 2156 * 1573 * @param phoneid Phone that will be used to contact the receiving side. 1574 * @param dst Address of the beginning of the destination buffer. 1575 * @param size Size of the destination buffer. 1576 * @param flags Flags to control the data transfer. 2157 * @param exch Exchange for sending the message. 2158 * @param dst Address of the beginning of the destination buffer. 2159 * @param size Size of the destination buffer. 1577 2160 * 1578 2161 * @return Zero on success or a negative error code from errno.h. 1579 2162 * 1580 2163 */ 1581 int 1582 async_data_read_start_generic(int phoneid, void *dst, size_t size, int flags) 1583 { 1584 return async_req_3_0(phoneid, IPC_M_DATA_READ, (sysarg_t) dst, 1585 (sysarg_t) size, (sysarg_t) flags); 2164 int async_data_read_start(async_exch_t *exch, void *dst, size_t size) 2165 { 2166 if (exch == NULL) 2167 return ENOENT; 2168 2169 return async_req_2_0(exch, IPC_M_DATA_READ, (sysarg_t) dst, 2170 (sysarg_t) size); 1586 2171 } 1587 2172 … … 1638 2223 * 1639 2224 */ 1640 int async_data_read_forward_fast(int phoneid, sysarg_t method, sysarg_t arg1, 1641 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr) 1642 { 2225 int async_data_read_forward_fast(async_exch_t *exch, sysarg_t imethod, 2226 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, 2227 ipc_call_t *dataptr) 2228 { 2229 if (exch == NULL) 2230 return ENOENT; 2231 1643 2232 ipc_callid_t callid; 1644 2233 if (!async_data_read_receive(&callid, NULL)) { … … 1647 2236 } 1648 2237 1649 aid_t msg = async_send_fast( phoneid,method, arg1, arg2, arg3, arg4,2238 aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4, 1650 2239 dataptr); 1651 2240 if (msg == 0) { … … 1654 2243 } 1655 2244 1656 int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,2245 int retval = ipc_forward_fast(callid, exch->phone, 0, 0, 0, 1657 2246 IPC_FF_ROUTE_FROM_ME); 1658 2247 if (retval != EOK) { … … 1670 2259 /** Wrapper for IPC_M_DATA_WRITE calls using the async framework. 1671 2260 * 1672 * @param phoneid Phone that will be used to contact the receiving side. 1673 * @param src Address of the beginning of the source buffer. 1674 * @param size Size of the source buffer. 1675 * @param flags Flags to control the data transfer. 2261 * @param exch Exchange for sending the message. 2262 * @param src Address of the beginning of the source buffer. 2263 * @param size Size of the source buffer. 1676 2264 * 1677 2265 * @return Zero on success or a negative error code from errno.h. 1678 2266 * 1679 2267 */ 1680 int 1681 async_data_write_start_generic(int phoneid, const void *src, size_t size, 1682 int flags) 1683 { 1684 return async_req_3_0(phoneid, IPC_M_DATA_WRITE, (sysarg_t) src, 1685 (sysarg_t) size, (sysarg_t) flags); 2268 int async_data_write_start(async_exch_t *exch, const void *src, size_t size) 2269 { 2270 if (exch == NULL) 2271 return ENOENT; 2272 2273 return async_req_2_0(exch, IPC_M_DATA_WRITE, (sysarg_t) src, 2274 (sysarg_t) size); 1686 2275 } 1687 2276 … … 1759 2348 size_t *received) 1760 2349 { 2350 assert(data); 2351 1761 2352 ipc_callid_t callid; 1762 2353 size_t size; … … 1826 2417 * 1827 2418 */ 1828 int async_data_write_forward_fast(int phoneid, sysarg_t method, sysarg_t arg1, 1829 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr) 1830 { 2419 int async_data_write_forward_fast(async_exch_t *exch, sysarg_t imethod, 2420 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, 2421 ipc_call_t *dataptr) 2422 { 2423 if (exch == NULL) 2424 return ENOENT; 2425 1831 2426 ipc_callid_t callid; 1832 2427 if (!async_data_write_receive(&callid, NULL)) { … … 1835 2430 } 1836 2431 1837 aid_t msg = async_send_fast( phoneid,method, arg1, arg2, arg3, arg4,2432 aid_t msg = async_send_fast(exch, imethod, arg1, arg2, arg3, arg4, 1838 2433 dataptr); 1839 2434 if (msg == 0) { … … 1842 2437 } 1843 2438 1844 int retval = ipc_forward_fast(callid, phoneid, 0, 0, 0,2439 int retval = ipc_forward_fast(callid, exch->phone, 0, 0, 0, 1845 2440 IPC_FF_ROUTE_FROM_ME); 1846 2441 if (retval != EOK) { … … 1856 2451 } 1857 2452 2453 /** Wrapper for sending an exchange over different exchange for cloning 2454 * 2455 * @param exch Exchange to be used for sending. 2456 * @param clone_exch Exchange to be cloned. 2457 * 2458 */ 2459 int async_exchange_clone(async_exch_t *exch, async_exch_t *clone_exch) 2460 { 2461 return async_req_1_0(exch, IPC_M_CONNECTION_CLONE, clone_exch->phone); 2462 } 2463 2464 /** Wrapper for receiving the IPC_M_CONNECTION_CLONE calls. 2465 * 2466 * If the current call is IPC_M_CONNECTION_CLONE then a new 2467 * async session is created for the accepted phone. 2468 * 2469 * @param mgmt Exchange management style. 2470 * 2471 * @return New async session or NULL on failure. 2472 * 2473 */ 2474 async_sess_t *async_clone_receive(exch_mgmt_t mgmt) 2475 { 2476 /* Accept the phone */ 2477 ipc_call_t call; 2478 ipc_callid_t callid = async_get_call(&call); 2479 int phone = (int) IPC_GET_ARG1(call); 2480 2481 if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECTION_CLONE) || 2482 (phone < 0)) { 2483 async_answer_0(callid, EINVAL); 2484 return NULL; 2485 } 2486 2487 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 2488 if (sess == NULL) { 2489 async_answer_0(callid, ENOMEM); 2490 return NULL; 2491 } 2492 2493 sess->mgmt = mgmt; 2494 sess->phone = phone; 2495 sess->arg1 = 0; 2496 sess->arg2 = 0; 2497 sess->arg3 = 0; 2498 2499 fibril_mutex_initialize(&sess->remote_state_mtx); 2500 sess->remote_state_data = NULL; 2501 2502 list_initialize(&sess->exch_list); 2503 fibril_mutex_initialize(&sess->mutex); 2504 atomic_set(&sess->refcnt, 0); 2505 2506 /* Acknowledge the cloned phone */ 2507 async_answer_0(callid, EOK); 2508 2509 return sess; 2510 } 2511 2512 /** Wrapper for receiving the IPC_M_CONNECT_TO_ME calls. 2513 * 2514 * If the current call is IPC_M_CONNECT_TO_ME then a new 2515 * async session is created for the accepted phone. 2516 * 2517 * @param mgmt Exchange management style. 2518 * 2519 * @return New async session. 2520 * @return NULL on failure. 2521 * 2522 */ 2523 async_sess_t *async_callback_receive(exch_mgmt_t mgmt) 2524 { 2525 /* Accept the phone */ 2526 ipc_call_t call; 2527 ipc_callid_t callid = async_get_call(&call); 2528 int phone = (int) IPC_GET_ARG5(call); 2529 2530 if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECT_TO_ME) || 2531 (phone < 0)) { 2532 async_answer_0(callid, EINVAL); 2533 return NULL; 2534 } 2535 2536 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 2537 if (sess == NULL) { 2538 async_answer_0(callid, ENOMEM); 2539 return NULL; 2540 } 2541 2542 sess->mgmt = mgmt; 2543 sess->phone = phone; 2544 sess->arg1 = 0; 2545 sess->arg2 = 0; 2546 sess->arg3 = 0; 2547 2548 fibril_mutex_initialize(&sess->remote_state_mtx); 2549 sess->remote_state_data = NULL; 2550 2551 list_initialize(&sess->exch_list); 2552 fibril_mutex_initialize(&sess->mutex); 2553 atomic_set(&sess->refcnt, 0); 2554 2555 /* Acknowledge the connected phone */ 2556 async_answer_0(callid, EOK); 2557 2558 return sess; 2559 } 2560 2561 /** Wrapper for receiving the IPC_M_CONNECT_TO_ME calls. 2562 * 2563 * If the call is IPC_M_CONNECT_TO_ME then a new 2564 * async session is created. However, the phone is 2565 * not accepted automatically. 2566 * 2567 * @param mgmt Exchange management style. 2568 * @param call Call data. 2569 * 2570 * @return New async session. 2571 * @return NULL on failure. 2572 * @return NULL if the call is not IPC_M_CONNECT_TO_ME. 2573 * 2574 */ 2575 async_sess_t *async_callback_receive_start(exch_mgmt_t mgmt, ipc_call_t *call) 2576 { 2577 int phone = (int) IPC_GET_ARG5(*call); 2578 2579 if ((IPC_GET_IMETHOD(*call) != IPC_M_CONNECT_TO_ME) || 2580 (phone < 0)) 2581 return NULL; 2582 2583 async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t)); 2584 if (sess == NULL) 2585 return NULL; 2586 2587 sess->mgmt = mgmt; 2588 sess->phone = phone; 2589 sess->arg1 = 0; 2590 sess->arg2 = 0; 2591 sess->arg3 = 0; 2592 2593 fibril_mutex_initialize(&sess->remote_state_mtx); 2594 sess->remote_state_data = NULL; 2595 2596 list_initialize(&sess->exch_list); 2597 fibril_mutex_initialize(&sess->mutex); 2598 atomic_set(&sess->refcnt, 0); 2599 2600 return sess; 2601 } 2602 2603 int async_state_change_start(async_exch_t *exch, sysarg_t arg1, sysarg_t arg2, 2604 sysarg_t arg3, async_exch_t *other_exch) 2605 { 2606 return async_req_5_0(exch, IPC_M_STATE_CHANGE_AUTHORIZE, 2607 arg1, arg2, arg3, 0, other_exch->phone); 2608 } 2609 2610 bool async_state_change_receive(ipc_callid_t *callid, sysarg_t *arg1, 2611 sysarg_t *arg2, sysarg_t *arg3) 2612 { 2613 assert(callid); 2614 2615 ipc_call_t call; 2616 *callid = async_get_call(&call); 2617 2618 if (IPC_GET_IMETHOD(call) != IPC_M_STATE_CHANGE_AUTHORIZE) 2619 return false; 2620 2621 if (arg1) 2622 *arg1 = IPC_GET_ARG1(call); 2623 if (arg2) 2624 *arg2 = IPC_GET_ARG2(call); 2625 if (arg3) 2626 *arg3 = IPC_GET_ARG3(call); 2627 2628 return true; 2629 } 2630 2631 int async_state_change_finalize(ipc_callid_t callid, async_exch_t *other_exch) 2632 { 2633 return ipc_answer_1(callid, EOK, other_exch->phone); 2634 } 2635 2636 /** Lock and get session remote state 2637 * 2638 * Lock and get the local replica of the remote state 2639 * in stateful sessions. The call should be paired 2640 * with async_remote_state_release*(). 2641 * 2642 * @param[in] sess Stateful session. 2643 * 2644 * @return Local replica of the remote state. 2645 * 2646 */ 2647 void *async_remote_state_acquire(async_sess_t *sess) 2648 { 2649 fibril_mutex_lock(&sess->remote_state_mtx); 2650 return sess->remote_state_data; 2651 } 2652 2653 /** Update the session remote state 2654 * 2655 * Update the local replica of the remote state 2656 * in stateful sessions. The remote state must 2657 * be already locked. 2658 * 2659 * @param[in] sess Stateful session. 2660 * @param[in] state New local replica of the remote state. 2661 * 2662 */ 2663 void async_remote_state_update(async_sess_t *sess, void *state) 2664 { 2665 assert(fibril_mutex_is_locked(&sess->remote_state_mtx)); 2666 sess->remote_state_data = state; 2667 } 2668 2669 /** Release the session remote state 2670 * 2671 * Unlock the local replica of the remote state 2672 * in stateful sessions. 2673 * 2674 * @param[in] sess Stateful session. 2675 * 2676 */ 2677 void async_remote_state_release(async_sess_t *sess) 2678 { 2679 assert(fibril_mutex_is_locked(&sess->remote_state_mtx)); 2680 2681 fibril_mutex_unlock(&sess->remote_state_mtx); 2682 } 2683 2684 /** Release the session remote state and end an exchange 2685 * 2686 * Unlock the local replica of the remote state 2687 * in stateful sessions. This is convenience function 2688 * which gets the session pointer from the exchange 2689 * and also ends the exchange. 2690 * 2691 * @param[in] exch Stateful session's exchange. 2692 * 2693 */ 2694 void async_remote_state_release_exchange(async_exch_t *exch) 2695 { 2696 if (exch == NULL) 2697 return; 2698 2699 async_sess_t *sess = exch->sess; 2700 assert(fibril_mutex_is_locked(&sess->remote_state_mtx)); 2701 2702 async_exchange_end(exch); 2703 fibril_mutex_unlock(&sess->remote_state_mtx); 2704 } 2705 1858 2706 /** @} 1859 2707 */ -
uspace/lib/c/generic/clipboard.c
r2bdf8313 rb0f00a9 39 39 40 40 #include <clipboard.h> 41 #include < ipc/ns.h>41 #include <ns.h> 42 42 #include <ipc/services.h> 43 43 #include <ipc/clipboard.h> 44 #include <fibril_synch.h> 44 45 #include <async.h> 45 46 #include <str.h> … … 47 48 #include <malloc.h> 48 49 49 static int clip_phone = -1; 50 51 /** Connect to clipboard server 52 * 53 */ 54 static void clip_connect(void) 55 { 56 while (clip_phone < 0) 57 clip_phone = service_connect_blocking(SERVICE_CLIPBOARD, 0, 0); 50 static FIBRIL_MUTEX_INITIALIZE(clip_mutex); 51 static async_sess_t *clip_sess = NULL; 52 53 /** Start an async exchange on the clipboard session. 54 * 55 * @return New exchange. 56 * 57 */ 58 static async_exch_t *clip_exchange_begin(void) 59 { 60 fibril_mutex_lock(&clip_mutex); 61 62 while (clip_sess == NULL) 63 clip_sess = service_connect_blocking(EXCHANGE_SERIALIZE, 64 SERVICE_CLIPBOARD, 0, 0); 65 66 fibril_mutex_unlock(&clip_mutex); 67 68 return async_exchange_begin(clip_sess); 69 } 70 71 /** Finish an async exchange on the clipboard session. 72 * 73 * @param exch Exchange to be finished. 74 * 75 */ 76 static void clip_exchange_end(async_exch_t *exch) 77 { 78 async_exchange_end(exch); 58 79 } 59 80 … … 73 94 74 95 if (size == 0) { 75 async_serialize_start(); 76 clip_connect(); 77 78 sysarg_t rc = async_req_1_0(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_NONE); 79 80 async_serialize_end(); 96 async_exch_t *exch = clip_exchange_begin(); 97 sysarg_t rc = async_req_1_0(exch, CLIPBOARD_PUT_DATA, 98 CLIPBOARD_TAG_NONE); 99 clip_exchange_end(exch); 81 100 82 101 return (int) rc; 83 102 } else { 84 async_serialize_start(); 85 clip_connect(); 86 87 aid_t req = async_send_1(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA, NULL); 88 sysarg_t rc = async_data_write_start(clip_phone, (void *) str, size); 103 async_exch_t *exch = clip_exchange_begin(); 104 aid_t req = async_send_1(exch, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA, 105 NULL); 106 sysarg_t rc = async_data_write_start(exch, (void *) str, size); 107 clip_exchange_end(exch); 108 89 109 if (rc != EOK) { 90 110 sysarg_t rc_orig; 91 111 async_wait_for(req, &rc_orig); 92 async_serialize_end();93 112 if (rc_orig == EOK) 94 113 return (int) rc; … … 98 117 99 118 async_wait_for(req, &rc); 100 async_serialize_end();101 119 102 120 return (int) rc; … … 117 135 /* Loop until clipboard read succesful */ 118 136 while (true) { 119 async_serialize_start(); 120 clip_connect(); 137 async_exch_t *exch = clip_exchange_begin(); 121 138 122 139 sysarg_t size; 123 140 sysarg_t tag; 124 sysarg_t rc = async_req_0_2( clip_phone, CLIPBOARD_CONTENT, &size, &tag);125 126 async_serialize_end();141 sysarg_t rc = async_req_0_2(exch, CLIPBOARD_CONTENT, &size, &tag); 142 143 clip_exchange_end(exch); 127 144 128 145 if (rc != EOK) … … 145 162 return ENOMEM; 146 163 147 async_serialize_start(); 148 149 aid_t req = async_send_1(clip_phone, CLIPBOARD_GET_DATA, tag, NULL); 150 rc = async_data_read_start(clip_phone, (void *) sbuf, size); 164 exch = clip_exchange_begin(); 165 aid_t req = async_send_1(exch, CLIPBOARD_GET_DATA, tag, NULL); 166 rc = async_data_read_start(exch, (void *) sbuf, size); 167 clip_exchange_end(exch); 168 151 169 if ((int) rc == EOVERFLOW) { 152 170 /* … … 154 172 * the last call of CLIPBOARD_CONTENT 155 173 */ 156 async_serialize_end();157 174 break; 158 175 } … … 161 178 sysarg_t rc_orig; 162 179 async_wait_for(req, &rc_orig); 163 async_serialize_end();164 180 if (rc_orig == EOK) 165 181 return (int) rc; … … 169 185 170 186 async_wait_for(req, &rc); 171 async_serialize_end();172 187 173 188 if (rc == EOK) { -
uspace/lib/c/generic/ddi.c
r2bdf8313 rb0f00a9 31 31 */ 32 32 /** @file 33 */ 33 */ 34 34 35 #include <sys/types.h> 36 #include <abi/ddi/arg.h> 35 37 #include <ddi.h> 36 38 #include <libarch/ddi.h> … … 40 42 #include <align.h> 41 43 #include <libarch/config.h> 42 #include <kernel/ddi/ddi_arg.h>43 44 44 45 /** Return unique device number. -
uspace/lib/c/generic/device/char_dev.c
r2bdf8313 rb0f00a9 45 45 * using its character interface. 46 46 * 47 * @param dev_phone Phoneto the device.48 * @param buf Buffer for the data read from or written to the device.49 * @param size Maximum size of data (in bytes) to be read or written.50 * @param read Read from the device if true, write to it otherwise.47 * @param sess Session to the device. 48 * @param buf Buffer for the data read from or written to the device. 49 * @param size Maximum size of data (in bytes) to be read or written. 50 * @param read Read from the device if true, write to it otherwise. 51 51 * 52 * @return Non-negative number of bytes actually read from or 53 * written to the device on success, negative error number 54 * otherwise. 52 * @return Non-negative number of bytes actually read from or 53 * written to the device on success, negative error number 54 * otherwise. 55 * 55 56 */ 56 static ssize_t char_dev_rw( int dev_phone, void *buf, size_t size, bool read)57 static ssize_t char_dev_rw(async_sess_t *sess, void *buf, size_t size, bool read) 57 58 { 58 async_serialize_start();59 60 59 ipc_call_t answer; 61 60 aid_t req; 62 61 int ret; 63 62 63 async_exch_t *exch = async_exchange_begin(sess); 64 64 65 if (read) { 65 req = async_send_1( dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE),66 req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE), 66 67 CHAR_DEV_READ, &answer); 67 ret = async_data_read_start( dev_phone, buf, size);68 ret = async_data_read_start(exch, buf, size); 68 69 } else { 69 req = async_send_1( dev_phone, DEV_IFACE_ID(CHAR_DEV_IFACE),70 req = async_send_1(exch, DEV_IFACE_ID(CHAR_DEV_IFACE), 70 71 CHAR_DEV_WRITE, &answer); 71 ret = async_data_write_start( dev_phone, buf, size);72 ret = async_data_write_start(exch, buf, size); 72 73 } 74 75 async_exchange_end(exch); 73 76 74 77 sysarg_t rc; 75 78 if (ret != EOK) { 76 79 async_wait_for(req, &rc); 77 async_serialize_end();78 80 if (rc == EOK) 79 81 return (ssize_t) ret; … … 83 85 84 86 async_wait_for(req, &rc); 85 async_serialize_end();86 87 87 88 ret = (int) rc; … … 94 95 /** Read from character device. 95 96 * 96 * @param dev_phone Phoneto the device.97 * @param buf Output buffer for the data read from the device.98 * @param size Maximum size (in bytes) of the data to be read.97 * @param sess Session to the device. 98 * @param buf Output buffer for the data read from the device. 99 * @param size Maximum size (in bytes) of the data to be read. 99 100 * 100 * @return Non-negative number of bytes actually read from the 101 * device on success, negative error number otherwise. 101 * @return Non-negative number of bytes actually read from the 102 * device on success, negative error number otherwise. 103 * 102 104 */ 103 ssize_t char_dev_read( int dev_phone, void *buf, size_t size)105 ssize_t char_dev_read(async_sess_t *sess, void *buf, size_t size) 104 106 { 105 return char_dev_rw( dev_phone, buf, size, true);107 return char_dev_rw(sess, buf, size, true); 106 108 } 107 109 108 110 /** Write to character device. 109 111 * 110 * @param dev_phone Phoneto the device.111 * @param buf Input buffer containg the data to be written to the112 * device.113 * @param size Maximum size (in bytes) of the data to be written.112 * @param sess Session to the device. 113 * @param buf Input buffer containg the data to be written to the 114 * device. 115 * @param size Maximum size (in bytes) of the data to be written. 114 116 * 115 * @return Non-negative number of bytes actually written to the 116 * device on success, negative error number otherwise. 117 * @return Non-negative number of bytes actually written to the 118 * device on success, negative error number otherwise. 119 * 117 120 */ 118 ssize_t char_dev_write( int dev_phone, void *buf, size_t size)121 ssize_t char_dev_write(async_sess_t *sess, void *buf, size_t size) 119 122 { 120 return char_dev_rw( dev_phone, buf, size, false);123 return char_dev_rw(sess, buf, size, false); 121 124 } 122 125 -
uspace/lib/c/generic/device/hw_res.c
r2bdf8313 rb0f00a9 38 38 #include <malloc.h> 39 39 40 int hw_res_get_resource_list(int dev_phone, hw_resource_list_t *hw_resources) 40 int hw_res_get_resource_list(async_sess_t *sess, 41 hw_resource_list_t *hw_resources) 41 42 { 42 43 sysarg_t count = 0; 43 44 int rc = async_req_1_1(dev_phone, DEV_IFACE_ID(HW_RES_DEV_IFACE), 44 45 async_exch_t *exch = async_exchange_begin(sess); 46 int rc = async_req_1_1(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE), 45 47 HW_RES_GET_RESOURCE_LIST, &count); 46 47 hw_resources->count = count;48 if (rc != EOK)48 49 if (rc != EOK) { 50 async_exchange_end(exch); 49 51 return rc; 52 } 50 53 51 54 size_t size = count * sizeof(hw_resource_t); 52 hw_resources->resources = (hw_resource_t *)malloc(size); 53 if (!hw_resources->resources) 55 hw_resource_t *resources = (hw_resource_t *) malloc(size); 56 if (resources == NULL) { 57 // FIXME: This is protocol violation 58 async_exchange_end(exch); 54 59 return ENOMEM; 60 } 55 61 56 rc = async_data_read_start(dev_phone, hw_resources->resources, size); 62 rc = async_data_read_start(exch, resources, size); 63 async_exchange_end(exch); 64 57 65 if (rc != EOK) { 58 free(hw_resources->resources); 59 hw_resources->resources = NULL; 66 free(resources); 60 67 return rc; 61 68 } 69 70 hw_resources->resources = resources; 71 hw_resources->count = count; 62 72 63 73 return EOK; 64 74 } 65 75 66 bool hw_res_enable_interrupt( int dev_phone)76 bool hw_res_enable_interrupt(async_sess_t *sess) 67 77 { 68 int rc = async_req_1_0(dev_phone, DEV_IFACE_ID(HW_RES_DEV_IFACE), 78 async_exch_t *exch = async_exchange_begin(sess); 79 int rc = async_req_1_0(exch, DEV_IFACE_ID(HW_RES_DEV_IFACE), 69 80 HW_RES_ENABLE_INTERRUPT); 70 71 return rc == EOK; 81 async_exchange_end(exch); 82 83 return (rc == EOK); 72 84 } 73 85 -
uspace/lib/c/generic/devman.c
r2bdf8313 rb0f00a9 1 1 /* 2 2 * Copyright (c) 2007 Josef Cejka 3 * Copyright (c) 20 09Jiri Svoboda3 * Copyright (c) 2011 Jiri Svoboda 4 4 * Copyright (c) 2010 Lenka Trochtova 5 5 * All rights reserved. … … 35 35 */ 36 36 37 #include <adt/list.h> 37 38 #include <str.h> 38 #include <stdio.h>39 39 #include <ipc/services.h> 40 #include <ns.h> 40 41 #include <ipc/devman.h> 41 42 #include <devman.h> 43 #include <fibril_synch.h> 42 44 #include <async.h> 43 #include <fibril_synch.h>44 45 #include <errno.h> 45 46 #include <malloc.h> 46 47 #include <bool.h> 47 #include <adt/list.h> 48 49 static int devman_phone_driver = -1; 50 static int devman_phone_client = -1; 51 52 static FIBRIL_MUTEX_INITIALIZE(devman_phone_mutex); 53 54 int devman_get_phone(devman_interface_t iface, unsigned int flags) 48 49 static FIBRIL_MUTEX_INITIALIZE(devman_driver_block_mutex); 50 static FIBRIL_MUTEX_INITIALIZE(devman_client_block_mutex); 51 52 static FIBRIL_MUTEX_INITIALIZE(devman_driver_mutex); 53 static FIBRIL_MUTEX_INITIALIZE(devman_client_mutex); 54 55 static async_sess_t *devman_driver_block_sess = NULL; 56 static async_sess_t *devman_client_block_sess = NULL; 57 58 static async_sess_t *devman_driver_sess = NULL; 59 static async_sess_t *devman_client_sess = NULL; 60 61 static void clone_session(fibril_mutex_t *mtx, async_sess_t *src, 62 async_sess_t **dst) 63 { 64 fibril_mutex_lock(mtx); 65 66 if ((*dst == NULL) && (src != NULL)) 67 *dst = src; 68 69 fibril_mutex_unlock(mtx); 70 } 71 72 /** Start an async exchange on the devman session (blocking). 73 * 74 * @param iface Device manager interface to choose 75 * 76 * @return New exchange. 77 * 78 */ 79 async_exch_t *devman_exchange_begin_blocking(devman_interface_t iface) 55 80 { 56 81 switch (iface) { 57 82 case DEVMAN_DRIVER: 58 fibril_mutex_lock(&devman_phone_mutex); 59 if (devman_phone_driver >= 0) { 60 fibril_mutex_unlock(&devman_phone_mutex); 61 return devman_phone_driver; 83 fibril_mutex_lock(&devman_driver_block_mutex); 84 85 while (devman_driver_block_sess == NULL) { 86 clone_session(&devman_driver_mutex, devman_driver_sess, 87 &devman_driver_block_sess); 88 89 if (devman_driver_block_sess == NULL) 90 devman_driver_block_sess = 91 service_connect_blocking(EXCHANGE_PARALLEL, 92 SERVICE_DEVMAN, DEVMAN_DRIVER, 0); 62 93 } 63 94 64 if (flags & IPC_FLAG_BLOCKING) 65 devman_phone_driver = async_connect_me_to_blocking( 66 PHONE_NS, SERVICE_DEVMAN, DEVMAN_DRIVER, 0); 67 else 68 devman_phone_driver = async_connect_me_to(PHONE_NS, 69 SERVICE_DEVMAN, DEVMAN_DRIVER, 0); 70 71 fibril_mutex_unlock(&devman_phone_mutex); 72 return devman_phone_driver; 95 fibril_mutex_unlock(&devman_driver_block_mutex); 96 97 clone_session(&devman_driver_mutex, devman_driver_block_sess, 98 &devman_driver_sess); 99 100 return async_exchange_begin(devman_driver_block_sess); 73 101 case DEVMAN_CLIENT: 74 fibril_mutex_lock(&devman_phone_mutex); 75 if (devman_phone_client >= 0) { 76 fibril_mutex_unlock(&devman_phone_mutex); 77 return devman_phone_client; 102 fibril_mutex_lock(&devman_client_block_mutex); 103 104 while (devman_client_block_sess == NULL) { 105 clone_session(&devman_client_mutex, devman_client_sess, 106 &devman_client_block_sess); 107 108 if (devman_client_block_sess == NULL) 109 devman_client_block_sess = 110 service_connect_blocking(EXCHANGE_SERIALIZE, 111 SERVICE_DEVMAN, DEVMAN_CLIENT, 0); 78 112 } 79 113 80 if (flags & IPC_FLAG_BLOCKING) { 81 devman_phone_client = async_connect_me_to_blocking( 82 PHONE_NS, SERVICE_DEVMAN, DEVMAN_CLIENT, 0); 83 } else { 84 devman_phone_client = async_connect_me_to(PHONE_NS, 85 SERVICE_DEVMAN, DEVMAN_CLIENT, 0); 86 } 87 88 fibril_mutex_unlock(&devman_phone_mutex); 89 return devman_phone_client; 114 fibril_mutex_unlock(&devman_client_block_mutex); 115 116 clone_session(&devman_client_mutex, devman_client_block_sess, 117 &devman_client_sess); 118 119 return async_exchange_begin(devman_client_block_sess); 90 120 default: 91 return -1; 92 } 121 return NULL; 122 } 123 } 124 125 /** Start an async exchange on the devman session. 126 * 127 * @param iface Device manager interface to choose 128 * 129 * @return New exchange. 130 * 131 */ 132 async_exch_t *devman_exchange_begin(devman_interface_t iface) 133 { 134 switch (iface) { 135 case DEVMAN_DRIVER: 136 fibril_mutex_lock(&devman_driver_mutex); 137 138 if (devman_driver_sess == NULL) 139 devman_driver_sess = 140 service_connect(EXCHANGE_PARALLEL, SERVICE_DEVMAN, 141 DEVMAN_DRIVER, 0); 142 143 fibril_mutex_unlock(&devman_driver_mutex); 144 145 if (devman_driver_sess == NULL) 146 return NULL; 147 148 return async_exchange_begin(devman_driver_sess); 149 case DEVMAN_CLIENT: 150 fibril_mutex_lock(&devman_client_mutex); 151 152 if (devman_client_sess == NULL) 153 devman_client_sess = 154 service_connect(EXCHANGE_SERIALIZE, SERVICE_DEVMAN, 155 DEVMAN_CLIENT, 0); 156 157 fibril_mutex_unlock(&devman_client_mutex); 158 159 if (devman_client_sess == NULL) 160 return NULL; 161 162 return async_exchange_begin(devman_client_sess); 163 default: 164 return NULL; 165 } 166 } 167 168 /** Finish an async exchange on the devman session. 169 * 170 * @param exch Exchange to be finished. 171 * 172 */ 173 void devman_exchange_end(async_exch_t *exch) 174 { 175 async_exchange_end(exch); 93 176 } 94 177 … … 96 179 int devman_driver_register(const char *name, async_client_conn_t conn) 97 180 { 98 int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING); 99 100 if (phone < 0) 101 return phone; 102 103 async_serialize_start(); 181 async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER); 104 182 105 183 ipc_call_t answer; 106 aid_t req = async_send_2(phone, DEVMAN_DRIVER_REGISTER, 0, 0, &answer); 107 108 sysarg_t retval = async_data_write_start(phone, name, str_size(name)); 184 aid_t req = async_send_2(exch, DEVMAN_DRIVER_REGISTER, 0, 0, &answer); 185 sysarg_t retval = async_data_write_start(exch, name, str_size(name)); 186 187 devman_exchange_end(exch); 188 109 189 if (retval != EOK) { 110 190 async_wait_for(req, NULL); 111 async_serialize_end(); 112 return -1; 191 return retval; 113 192 } 114 193 115 194 async_set_client_connection(conn); 116 195 117 async_connect_to_me(phone, 0, 0, 0, NULL); 196 exch = devman_exchange_begin(DEVMAN_DRIVER); 197 async_connect_to_me(exch, 0, 0, 0, conn, NULL); 198 devman_exchange_end(exch); 199 118 200 async_wait_for(req, &retval); 119 120 async_serialize_end();121 122 201 return retval; 123 }124 125 static int devman_send_match_id(int phone, match_id_t *match_id)126 {127 ipc_call_t answer;128 129 aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score,130 &answer);131 int retval = async_data_write_start(phone, match_id->id,132 str_size(match_id->id));133 134 async_wait_for(req, NULL);135 return retval;136 }137 138 139 static int devman_send_match_ids(int phone, match_id_list_t *match_ids)140 {141 link_t *link = match_ids->ids.next;142 match_id_t *match_id = NULL;143 int ret = EOK;144 145 while (link != &match_ids->ids) {146 match_id = list_get_instance(link, match_id_t, link);147 ret = devman_send_match_id(phone, match_id);148 if (ret != EOK) {149 return ret;150 }151 152 link = link->next;153 }154 155 return ret;156 202 } 157 203 … … 161 207 * this driver task. 162 208 * 163 * @param name Name of the new function 164 * @param ftype Function type, fun_inner or fun_exposed 165 * @param match_ids Match IDs (should be empty for fun_exposed) 166 * @param devh Devman handle of the device 167 * @param funh Place to store handle of the new function 168 * 169 * @return EOK on success or negative error code. 209 * @param name Name of the new function 210 * @param ftype Function type, fun_inner or fun_exposed 211 * @param match_ids Match IDs (should be empty for fun_exposed) 212 * @param devh Devman handle of the device 213 * @param funh Place to store handle of the new function 214 * 215 * @return EOK on success or negative error code. 216 * 170 217 */ 171 218 int devman_add_function(const char *name, fun_type_t ftype, 172 219 match_id_list_t *match_ids, devman_handle_t devh, devman_handle_t *funh) 173 220 { 174 int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);175 int fun_handle;176 177 if (phone < 0)178 return phone;179 180 async_serialize_start();181 182 221 int match_count = list_count(&match_ids->ids); 222 async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER); 223 183 224 ipc_call_t answer; 184 185 aid_t req = async_send_3(phone, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype, 225 aid_t req = async_send_3(exch, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype, 186 226 devh, match_count, &answer); 187 188 sysarg_t retval = async_data_write_start(phone, name, str_size(name)); 227 sysarg_t retval = async_data_write_start(exch, name, str_size(name)); 228 if (retval != EOK) { 229 devman_exchange_end(exch); 230 async_wait_for(req, NULL); 231 return retval; 232 } 233 234 match_id_t *match_id = NULL; 235 236 list_foreach(match_ids->ids, link) { 237 match_id = list_get_instance(link, match_id_t, link); 238 239 ipc_call_t answer2; 240 aid_t req2 = async_send_1(exch, DEVMAN_ADD_MATCH_ID, 241 match_id->score, &answer2); 242 retval = async_data_write_start(exch, match_id->id, 243 str_size(match_id->id)); 244 if (retval != EOK) { 245 devman_exchange_end(exch); 246 async_wait_for(req2, NULL); 247 async_wait_for(req, NULL); 248 return retval; 249 } 250 251 async_wait_for(req2, &retval); 252 if (retval != EOK) { 253 devman_exchange_end(exch); 254 async_wait_for(req, NULL); 255 return retval; 256 } 257 } 258 259 devman_exchange_end(exch); 260 261 async_wait_for(req, &retval); 262 if (retval == EOK) { 263 if (funh != NULL) 264 *funh = (int) IPC_GET_ARG1(answer); 265 } else { 266 if (funh != NULL) 267 *funh = -1; 268 } 269 270 return retval; 271 } 272 273 int devman_add_device_to_category(devman_handle_t devman_handle, 274 const char *cat_name) 275 { 276 async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_DRIVER); 277 278 ipc_call_t answer; 279 aid_t req = async_send_1(exch, DEVMAN_ADD_DEVICE_TO_CATEGORY, 280 devman_handle, &answer); 281 sysarg_t retval = async_data_write_start(exch, cat_name, 282 str_size(cat_name)); 283 284 devman_exchange_end(exch); 285 189 286 if (retval != EOK) { 190 287 async_wait_for(req, NULL); 191 async_serialize_end(); 192 return retval; 193 } 194 195 int match_ids_rc = devman_send_match_ids(phone, match_ids); 288 return retval; 289 } 196 290 197 291 async_wait_for(req, &retval); 198 199 async_serialize_end(); 200 201 /* Prefer the answer to DEVMAN_ADD_FUNCTION in case of errors. */ 202 if ((match_ids_rc != EOK) && (retval == EOK)) { 203 retval = match_ids_rc; 204 } 205 206 if (retval == EOK) 207 fun_handle = (int) IPC_GET_ARG1(answer); 292 return retval; 293 } 294 295 async_sess_t *devman_device_connect(exch_mgmt_t mgmt, devman_handle_t handle, 296 unsigned int flags) 297 { 298 async_sess_t *sess; 299 300 if (flags & IPC_FLAG_BLOCKING) 301 sess = service_connect_blocking(mgmt, SERVICE_DEVMAN, 302 DEVMAN_CONNECT_TO_DEVICE, handle); 208 303 else 209 fun_handle = -1; 210 211 *funh = fun_handle; 212 213 return retval; 214 } 215 216 int devman_add_device_to_class(devman_handle_t devman_handle, 217 const char *class_name) 218 { 219 int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING); 220 221 if (phone < 0) 222 return phone; 223 224 async_serialize_start(); 304 sess = service_connect(mgmt, SERVICE_DEVMAN, 305 DEVMAN_CONNECT_TO_DEVICE, handle); 306 307 return sess; 308 } 309 310 /** Remove function from device. 311 * 312 * Request devman to remove function owned by this driver task. 313 * @param funh Devman handle of the function 314 * 315 * @return EOK on success or negative error code. 316 */ 317 int devman_remove_function(devman_handle_t funh) 318 { 319 async_exch_t *exch; 320 sysarg_t retval; 321 322 exch = devman_exchange_begin_blocking(DEVMAN_DRIVER); 323 retval = async_req_1_0(exch, DEVMAN_REMOVE_FUNCTION, (sysarg_t) funh); 324 devman_exchange_end(exch); 325 326 return (int) retval; 327 } 328 329 int devman_drv_fun_online(devman_handle_t funh) 330 { 331 async_exch_t *exch = devman_exchange_begin(DEVMAN_DRIVER); 332 if (exch == NULL) 333 return ENOMEM; 334 335 sysarg_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_ONLINE, funh); 336 337 devman_exchange_end(exch); 338 return (int) retval; 339 } 340 341 int devman_drv_fun_offline(devman_handle_t funh) 342 { 343 async_exch_t *exch = devman_exchange_begin(DEVMAN_DRIVER); 344 if (exch == NULL) 345 return ENOMEM; 346 347 sysarg_t retval = async_req_1_0(exch, DEVMAN_DRV_FUN_OFFLINE, funh); 348 349 devman_exchange_end(exch); 350 return (int) retval; 351 } 352 353 async_sess_t *devman_parent_device_connect(exch_mgmt_t mgmt, 354 devman_handle_t handle, unsigned int flags) 355 { 356 async_sess_t *sess; 357 358 if (flags & IPC_FLAG_BLOCKING) 359 sess = service_connect_blocking(mgmt, SERVICE_DEVMAN, 360 DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle); 361 else 362 sess = service_connect(mgmt, SERVICE_DEVMAN, 363 DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle); 364 365 return sess; 366 } 367 368 int devman_fun_get_handle(const char *pathname, devman_handle_t *handle, 369 unsigned int flags) 370 { 371 async_exch_t *exch; 372 373 if (flags & IPC_FLAG_BLOCKING) 374 exch = devman_exchange_begin_blocking(DEVMAN_CLIENT); 375 else { 376 exch = devman_exchange_begin(DEVMAN_CLIENT); 377 if (exch == NULL) 378 return ENOMEM; 379 } 380 225 381 ipc_call_t answer; 226 aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS, 227 devman_handle, &answer); 228 229 sysarg_t retval = async_data_write_start(phone, class_name, 230 str_size(class_name)); 382 aid_t req = async_send_2(exch, DEVMAN_DEVICE_GET_HANDLE, flags, 0, 383 &answer); 384 sysarg_t retval = async_data_write_start(exch, pathname, 385 str_size(pathname)); 386 387 devman_exchange_end(exch); 388 231 389 if (retval != EOK) { 232 390 async_wait_for(req, NULL); 233 async_serialize_end();234 391 return retval; 235 392 } 236 393 237 394 async_wait_for(req, &retval); 238 async_serialize_end();239 240 return retval;241 }242 243 void devman_hangup_phone(devman_interface_t iface)244 {245 switch (iface) {246 case DEVMAN_DRIVER:247 if (devman_phone_driver >= 0) {248 async_hangup(devman_phone_driver);249 devman_phone_driver = -1;250 }251 break;252 case DEVMAN_CLIENT:253 if (devman_phone_client >= 0) {254 async_hangup(devman_phone_client);255 devman_phone_client = -1;256 }257 break;258 default:259 break;260 }261 }262 263 int devman_device_connect(devman_handle_t handle, unsigned int flags)264 {265 int phone;266 267 if (flags & IPC_FLAG_BLOCKING) {268 phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,269 DEVMAN_CONNECT_TO_DEVICE, handle);270 } else {271 phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN,272 DEVMAN_CONNECT_TO_DEVICE, handle);273 }274 275 return phone;276 }277 278 int devman_parent_device_connect(devman_handle_t handle, unsigned int flags)279 {280 int phone;281 282 if (flags & IPC_FLAG_BLOCKING) {283 phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAN,284 DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);285 } else {286 phone = async_connect_me_to(PHONE_NS, SERVICE_DEVMAN,287 DEVMAN_CONNECT_TO_PARENTS_DEVICE, handle);288 }289 290 return phone;291 }292 293 int devman_device_get_handle(const char *pathname, devman_handle_t *handle,294 unsigned int flags)295 {296 int phone = devman_get_phone(DEVMAN_CLIENT, flags);297 298 if (phone < 0)299 return phone;300 301 async_serialize_start();302 303 ipc_call_t answer;304 aid_t req = async_send_2(phone, DEVMAN_DEVICE_GET_HANDLE, flags, 0,305 &answer);306 307 sysarg_t retval = async_data_write_start(phone, pathname,308 str_size(pathname));309 if (retval != EOK) {310 async_wait_for(req, NULL);311 async_serialize_end();312 return retval;313 }314 315 async_wait_for(req, &retval);316 317 async_serialize_end();318 395 319 396 if (retval != EOK) { 320 397 if (handle != NULL) 321 398 *handle = (devman_handle_t) -1; 399 322 400 return retval; 323 401 } … … 329 407 } 330 408 331 int devman_device_get_handle_by_class(const char *classname,332 const char *devname, devman_handle_t *handle, unsigned int flags)333 { 334 int phone = devman_get_phone(DEVMAN_CLIENT, flags);335 336 if (phone < 0)337 return phone;338 339 async_serialize_start();340 409 static int devman_get_str_internal(sysarg_t method, sysarg_t arg1, char *buf, 410 size_t buf_size) 411 { 412 async_exch_t *exch; 413 ipc_call_t dreply; 414 size_t act_size; 415 sysarg_t dretval; 416 417 exch = devman_exchange_begin_blocking(LOC_PORT_CONSUMER); 418 341 419 ipc_call_t answer; 342 aid_t req = async_send_1(phone, DEVMAN_DEVICE_GET_HANDLE_BY_CLASS, 343 flags, &answer); 344 345 sysarg_t retval = async_data_write_start(phone, classname, 346 str_size(classname)); 420 aid_t req = async_send_1(exch, method, arg1, &answer); 421 aid_t dreq = async_data_read(exch, buf, buf_size - 1, &dreply); 422 async_wait_for(dreq, &dretval); 423 424 devman_exchange_end(exch); 425 426 if (dretval != EOK) { 427 async_wait_for(req, NULL); 428 return dretval; 429 } 430 431 sysarg_t retval; 432 async_wait_for(req, &retval); 433 434 if (retval != EOK) 435 return retval; 436 437 act_size = IPC_GET_ARG2(dreply); 438 assert(act_size <= buf_size - 1); 439 buf[act_size] = '\0'; 440 441 return EOK; 442 } 443 444 int devman_fun_get_path(devman_handle_t handle, char *buf, size_t buf_size) 445 { 446 return devman_get_str_internal(DEVMAN_FUN_GET_PATH, handle, buf, 447 buf_size); 448 } 449 450 int devman_fun_get_name(devman_handle_t handle, char *buf, size_t buf_size) 451 { 452 return devman_get_str_internal(DEVMAN_FUN_GET_NAME, handle, buf, 453 buf_size); 454 } 455 456 int devman_fun_online(devman_handle_t funh) 457 { 458 async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT); 459 if (exch == NULL) 460 return ENOMEM; 461 462 sysarg_t retval = async_req_1_0(exch, DEVMAN_FUN_ONLINE, funh); 463 464 devman_exchange_end(exch); 465 return (int) retval; 466 } 467 468 int devman_fun_offline(devman_handle_t funh) 469 { 470 async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT); 471 if (exch == NULL) 472 return ENOMEM; 473 474 sysarg_t retval = async_req_1_0(exch, DEVMAN_FUN_OFFLINE, funh); 475 476 devman_exchange_end(exch); 477 return (int) retval; 478 } 479 480 static int devman_get_handles_once(sysarg_t method, sysarg_t arg1, 481 devman_handle_t *handle_buf, size_t buf_size, size_t *act_size) 482 { 483 async_exch_t *exch = devman_exchange_begin_blocking(DEVMAN_CLIENT); 484 485 ipc_call_t answer; 486 aid_t req = async_send_1(exch, method, arg1, &answer); 487 int rc = async_data_read_start(exch, handle_buf, buf_size); 488 489 devman_exchange_end(exch); 490 491 if (rc != EOK) { 492 async_wait_for(req, NULL); 493 return rc; 494 } 495 496 sysarg_t retval; 497 async_wait_for(req, &retval); 498 347 499 if (retval != EOK) { 348 async_wait_for(req, NULL); 349 async_serialize_end(); 350 return retval; 351 } 352 retval = async_data_write_start(phone, devname, 353 str_size(devname)); 354 if (retval != EOK) { 355 async_wait_for(req, NULL); 356 async_serialize_end(); 357 return retval; 358 } 359 360 async_wait_for(req, &retval); 361 362 async_serialize_end(); 363 364 if (retval != EOK) { 365 if (handle != NULL) 366 *handle = (devman_handle_t) -1; 367 return retval; 368 } 369 370 if (handle != NULL) 371 *handle = (devman_handle_t) IPC_GET_ARG1(answer); 372 373 return retval; 374 } 375 500 return retval; 501 } 502 503 *act_size = IPC_GET_ARG1(answer); 504 return EOK; 505 } 506 507 /** Get list of handles. 508 * 509 * Returns an allocated array of handles. 510 * 511 * @param method IPC method 512 * @param arg1 IPC argument 1 513 * @param data Place to store pointer to array of handles 514 * @param count Place to store number of handles 515 * @return EOK on success or negative error code 516 */ 517 static int devman_get_handles_internal(sysarg_t method, sysarg_t arg1, 518 devman_handle_t **data, size_t *count) 519 { 520 devman_handle_t *handles; 521 size_t act_size; 522 size_t alloc_size; 523 int rc; 524 525 *data = NULL; 526 act_size = 0; /* silence warning */ 527 528 rc = devman_get_handles_once(method, arg1, NULL, 0, 529 &act_size); 530 if (rc != EOK) 531 return rc; 532 533 alloc_size = act_size; 534 handles = malloc(alloc_size); 535 if (handles == NULL) 536 return ENOMEM; 537 538 while (true) { 539 rc = devman_get_handles_once(method, arg1, handles, alloc_size, 540 &act_size); 541 if (rc != EOK) 542 return rc; 543 544 if (act_size <= alloc_size) 545 break; 546 547 alloc_size *= 2; 548 free(handles); 549 550 handles = malloc(alloc_size); 551 if (handles == NULL) 552 return ENOMEM; 553 } 554 555 *count = act_size / sizeof(devman_handle_t); 556 *data = handles; 557 return EOK; 558 } 559 560 int devman_fun_get_child(devman_handle_t funh, devman_handle_t *devh) 561 { 562 async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT); 563 if (exch == NULL) 564 return ENOMEM; 565 566 sysarg_t retval = async_req_1_1(exch, DEVMAN_FUN_GET_CHILD, 567 funh, devh); 568 569 devman_exchange_end(exch); 570 return (int) retval; 571 } 572 573 int devman_dev_get_functions(devman_handle_t devh, devman_handle_t **funcs, 574 size_t *count) 575 { 576 return devman_get_handles_internal(DEVMAN_DEV_GET_FUNCTIONS, 577 devh, funcs, count); 578 } 579 580 int devman_fun_sid_to_handle(service_id_t sid, devman_handle_t *handle) 581 { 582 async_exch_t *exch = devman_exchange_begin(DEVMAN_CLIENT); 583 if (exch == NULL) 584 return ENOMEM; 585 586 sysarg_t retval = async_req_1_1(exch, DEVMAN_FUN_SID_TO_HANDLE, 587 sid, handle); 588 589 devman_exchange_end(exch); 590 return (int) retval; 591 } 376 592 377 593 /** @} -
uspace/lib/c/generic/elf/elf_load.c
r2bdf8313 rb0f00a9 29 29 */ 30 30 31 /** @addtogroup generic 31 /** @addtogroup generic 32 32 * @{ 33 33 */ … … 49 49 #include <assert.h> 50 50 #include <as.h> 51 #include <elf/elf.h> 51 52 #include <unistd.h> 52 53 #include <fcntl.h> … … 55 56 #include <entry_point.h> 56 57 57 #include "elf.h" 58 #include "elf_load.h" 58 #include <elf/elf_load.h> 59 59 60 60 #define DPRINTF(...) … … 74 74 static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry); 75 75 76 /** Read until the buffer is read in its entirety. */77 static int my_read(int fd, void *buf, size_t len)78 {79 int cnt = 0;80 do {81 buf += cnt;82 len -= cnt;83 cnt = read(fd, buf, len);84 } while ((cnt > 0) && ((len - cnt) > 0));85 86 return cnt;87 }88 89 76 /** Load ELF binary from a file. 90 77 * … … 160 147 int i, rc; 161 148 162 rc = my_read(elf->fd, header, sizeof(elf_header_t));163 if (rc < 0) {149 rc = read_all(elf->fd, header, sizeof(elf_header_t)); 150 if (rc != sizeof(elf_header_t)) { 164 151 DPRINTF("Read error.\n"); 165 152 return EE_INVALID; … … 222 209 + i * sizeof(elf_segment_header_t), SEEK_SET); 223 210 224 rc = my_read(elf->fd, &segment_hdr,211 rc = read_all(elf->fd, &segment_hdr, 225 212 sizeof(elf_segment_header_t)); 226 if (rc < 0) {213 if (rc != sizeof(elf_segment_header_t)) { 227 214 DPRINTF("Read error.\n"); 228 215 return EE_INVALID; … … 244 231 + i * sizeof(elf_section_header_t), SEEK_SET); 245 232 246 rc = my_read(elf->fd, §ion_hdr,233 rc = read_all(elf->fd, §ion_hdr, 247 234 sizeof(elf_section_header_t)); 248 if (rc < 0) {235 if (rc != sizeof(elf_section_header_t)) { 249 236 DPRINTF("Read error.\n"); 250 237 return EE_INVALID; … … 334 321 uintptr_t seg_addr; 335 322 size_t mem_sz; 336 int rc;323 ssize_t rc; 337 324 338 325 bias = elf->bias; … … 412 399 if (now > left) now = left; 413 400 414 rc = my_read(elf->fd, dp, now);415 416 if (rc < 0) {401 rc = read_all(elf->fd, dp, now); 402 403 if (rc != (ssize_t) now) { 417 404 DPRINTF("Read error.\n"); 418 405 return EE_INVALID; -
uspace/lib/c/generic/event.c
r2bdf8313 rb0f00a9 39 39 #include <libc.h> 40 40 #include <event.h> 41 #include <kernel/ipc/event_types.h>42 41 43 42 /** Subscribe event notifications. … … 50 49 */ 51 50 int event_subscribe(event_type_t evno, sysarg_t imethod) 51 { 52 return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) evno, 53 (sysarg_t) imethod); 54 } 55 56 int event_task_subscribe(event_task_type_t evno, sysarg_t imethod) 52 57 { 53 58 return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) evno, … … 67 72 } 68 73 74 int event_task_unmask(event_task_type_t evno) 75 { 76 return __SYSCALL1(SYS_EVENT_UNMASK, (sysarg_t) evno); 77 } 78 69 79 /** @} 70 80 */ -
uspace/lib/c/generic/fibril.c
r2bdf8313 rb0f00a9 41 41 #include <unistd.h> 42 42 #include <stdio.h> 43 #include < arch/barrier.h>43 #include <libarch/barrier.h> 44 44 #include <libarch/faddr.h> 45 45 #include <futex.h> … … 222 222 fibril_t *dstf; 223 223 if ((stype == FIBRIL_TO_MANAGER) || (stype == FIBRIL_FROM_DEAD)) { 224 dstf = list_get_instance(manager_list.next, fibril_t, link); 224 dstf = list_get_instance(list_first(&manager_list), fibril_t, 225 link); 225 226 if (serialization_count && stype == FIBRIL_TO_MANAGER) { 226 227 serialized_threads++; … … 233 234 } else { 234 235 if (!list_empty(&serialized_list)) { 235 dstf = list_get_instance( serialized_list.next, fibril_t,236 link);236 dstf = list_get_instance(list_first(&serialized_list), 237 fibril_t, link); 237 238 serialized_threads--; 238 239 } else { 239 dstf = list_get_instance( ready_list.next, fibril_t,240 link);240 dstf = list_get_instance(list_first(&ready_list), 241 fibril_t, link); 241 242 } 242 243 } … … 326 327 327 328 if (!list_empty(&manager_list)) 328 list_remove( manager_list.next);329 list_remove(list_first(&manager_list)); 329 330 330 331 futex_up(&fibril_futex); -
uspace/lib/c/generic/fibril_synch.c
r2bdf8313 rb0f00a9 148 148 fibril_t *f; 149 149 150 assert(!list_empty(&fm->waiters));151 tmp = fm->waiters.next;150 tmp = list_first(&fm->waiters); 151 assert(tmp != NULL); 152 152 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 153 153 wdp->active = true; … … 279 279 280 280 while (!list_empty(&frw->waiters)) { 281 link_t *tmp = frw->waiters.next;281 link_t *tmp = list_first(&frw->waiters); 282 282 awaiter_t *wdp; 283 283 fibril_t *f; … … 422 422 futex_down(&async_futex); 423 423 while (!list_empty(&fcv->waiters)) { 424 tmp = fcv->waiters.next;424 tmp = list_first(&fcv->waiters); 425 425 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 426 426 list_remove(&wdp->wu_event.link); -
uspace/lib/c/generic/io/console.c
r2bdf8313 rb0f00a9 37 37 #include <libc.h> 38 38 #include <async.h> 39 #include <errno.h> 40 #include <stdio.h> 41 #include <malloc.h> 42 #include <vfs/vfs_sess.h> 39 43 #include <io/console.h> 40 44 #include <ipc/console.h> 41 45 42 void console_clear(int phone) 43 { 44 async_msg_0(phone, CONSOLE_CLEAR); 45 } 46 47 int console_get_size(int phone, sysarg_t *cols, sysarg_t *rows) 48 { 49 return async_req_0_2(phone, CONSOLE_GET_SIZE, cols, rows); 50 } 51 52 void console_set_style(int phone, uint8_t style) 53 { 54 async_msg_1(phone, CONSOLE_SET_STYLE, style); 55 } 56 57 void console_set_color(int phone, uint8_t fg_color, uint8_t bg_color, 46 console_ctrl_t *console_init(FILE *ifile, FILE *ofile) 47 { 48 console_ctrl_t *ctrl = malloc(sizeof(console_ctrl_t)); 49 if (!ctrl) 50 return NULL; 51 52 ctrl->input_sess = fsession(EXCHANGE_SERIALIZE, ifile); 53 if (!ctrl->input_sess) { 54 free(ctrl); 55 return NULL; 56 } 57 58 ctrl->output_sess = fsession(EXCHANGE_SERIALIZE, ofile); 59 if (!ctrl->output_sess) { 60 free(ctrl); 61 return NULL; 62 } 63 64 ctrl->input = ifile; 65 ctrl->output = ofile; 66 ctrl->input_aid = 0; 67 68 return ctrl; 69 } 70 71 void console_done(console_ctrl_t *ctrl) 72 { 73 free(ctrl); 74 } 75 76 bool console_kcon(void) 77 { 78 return __SYSCALL0(SYS_DEBUG_ACTIVATE_CONSOLE); 79 } 80 81 void console_flush(console_ctrl_t *ctrl) 82 { 83 fflush(ctrl->output); 84 } 85 86 void console_clear(console_ctrl_t *ctrl) 87 { 88 async_exch_t *exch = async_exchange_begin(ctrl->output_sess); 89 async_req_0_0(exch, CONSOLE_CLEAR); 90 async_exchange_end(exch); 91 } 92 93 int console_get_size(console_ctrl_t *ctrl, sysarg_t *cols, sysarg_t *rows) 94 { 95 async_exch_t *exch = async_exchange_begin(ctrl->output_sess); 96 int rc = async_req_0_2(exch, CONSOLE_GET_SIZE, cols, rows); 97 async_exchange_end(exch); 98 99 return rc; 100 } 101 102 void console_set_style(console_ctrl_t *ctrl, uint8_t style) 103 { 104 async_exch_t *exch = async_exchange_begin(ctrl->output_sess); 105 async_req_1_0(exch, CONSOLE_SET_STYLE, style); 106 async_exchange_end(exch); 107 } 108 109 void console_set_color(console_ctrl_t *ctrl, uint8_t bgcolor, uint8_t fgcolor, 58 110 uint8_t flags) 59 111 { 60 async_msg_3(phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags); 61 } 62 63 void console_set_rgb_color(int phone, uint32_t fg_color, uint32_t bg_color) 64 { 65 async_msg_2(phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color); 66 } 67 68 void console_cursor_visibility(int phone, bool show) 69 { 70 async_msg_1(phone, CONSOLE_CURSOR_VISIBILITY, (show != false)); 71 } 72 73 int console_get_color_cap(int phone, sysarg_t *ccap) 74 { 75 return async_req_0_1(phone, CONSOLE_GET_COLOR_CAP, ccap); 76 } 77 78 void console_kcon_enable(int phone) 79 { 80 async_msg_0(phone, CONSOLE_KCON_ENABLE); 81 } 82 83 int console_get_pos(int phone, sysarg_t *col, sysarg_t *row) 84 { 85 return async_req_0_2(phone, CONSOLE_GET_POS, col, row); 86 } 87 88 void console_set_pos(int phone, sysarg_t col, sysarg_t row) 89 { 90 async_msg_2(phone, CONSOLE_GOTO, col, row); 91 } 92 93 bool console_get_event(int phone, console_event_t *event) 94 { 95 sysarg_t type; 96 sysarg_t key; 97 sysarg_t mods; 98 sysarg_t c; 99 100 int rc = async_req_0_4(phone, CONSOLE_GET_EVENT, &type, &key, &mods, &c); 101 if (rc < 0) 112 async_exch_t *exch = async_exchange_begin(ctrl->output_sess); 113 async_req_3_0(exch, CONSOLE_SET_COLOR, bgcolor, fgcolor, flags); 114 async_exchange_end(exch); 115 } 116 117 void console_set_rgb_color(console_ctrl_t *ctrl, uint32_t bgcolor, 118 uint32_t fgcolor) 119 { 120 async_exch_t *exch = async_exchange_begin(ctrl->output_sess); 121 async_req_2_0(exch, CONSOLE_SET_RGB_COLOR, bgcolor, fgcolor); 122 async_exchange_end(exch); 123 } 124 125 void console_cursor_visibility(console_ctrl_t *ctrl, bool show) 126 { 127 async_exch_t *exch = async_exchange_begin(ctrl->output_sess); 128 async_req_1_0(exch, CONSOLE_CURSOR_VISIBILITY, (show != false)); 129 async_exchange_end(exch); 130 } 131 132 int console_get_color_cap(console_ctrl_t *ctrl, sysarg_t *ccap) 133 { 134 async_exch_t *exch = async_exchange_begin(ctrl->output_sess); 135 int rc = async_req_0_1(exch, CONSOLE_GET_COLOR_CAP, ccap); 136 async_exchange_end(exch); 137 138 return rc; 139 } 140 141 int console_get_pos(console_ctrl_t *ctrl, sysarg_t *col, sysarg_t *row) 142 { 143 async_exch_t *exch = async_exchange_begin(ctrl->output_sess); 144 int rc = async_req_0_2(exch, CONSOLE_GET_POS, col, row); 145 async_exchange_end(exch); 146 147 return rc; 148 } 149 150 void console_set_pos(console_ctrl_t *ctrl, sysarg_t col, sysarg_t row) 151 { 152 async_exch_t *exch = async_exchange_begin(ctrl->output_sess); 153 async_req_2_0(exch, CONSOLE_GOTO, col, row); 154 async_exchange_end(exch); 155 } 156 157 bool console_get_kbd_event(console_ctrl_t *ctrl, kbd_event_t *event) 158 { 159 if (ctrl->input_aid == 0) { 160 sysarg_t type; 161 sysarg_t key; 162 sysarg_t mods; 163 sysarg_t c; 164 165 async_exch_t *exch = async_exchange_begin(ctrl->input_sess); 166 int rc = async_req_0_4(exch, CONSOLE_GET_EVENT, &type, &key, &mods, &c); 167 async_exchange_end(exch); 168 169 if (rc != EOK) { 170 errno = rc; 171 return false; 172 } 173 174 event->type = type; 175 event->key = key; 176 event->mods = mods; 177 event->c = c; 178 } else { 179 sysarg_t retval; 180 async_wait_for(ctrl->input_aid, &retval); 181 182 ctrl->input_aid = 0; 183 184 if (retval != EOK) { 185 errno = (int) retval; 186 return false; 187 } 188 189 event->type = IPC_GET_ARG1(ctrl->input_call); 190 event->key = IPC_GET_ARG2(ctrl->input_call); 191 event->mods = IPC_GET_ARG3(ctrl->input_call); 192 event->c = IPC_GET_ARG4(ctrl->input_call); 193 } 194 195 return true; 196 } 197 198 bool console_get_kbd_event_timeout(console_ctrl_t *ctrl, kbd_event_t *event, 199 suseconds_t *timeout) 200 { 201 struct timeval t0; 202 gettimeofday(&t0, NULL); 203 204 if (ctrl->input_aid == 0) { 205 async_exch_t *exch = async_exchange_begin(ctrl->input_sess); 206 ctrl->input_aid = async_send_0(exch, CONSOLE_GET_EVENT, 207 &ctrl->input_call); 208 async_exchange_end(exch); 209 } 210 211 sysarg_t retval; 212 int rc = async_wait_timeout(ctrl->input_aid, &retval, *timeout); 213 if (rc != EOK) { 214 *timeout = 0; 215 errno = rc; 102 216 return false; 103 104 event->type = type; 105 event->key = key; 106 event->mods = mods; 107 event->c = c; 217 } 218 219 ctrl->input_aid = 0; 220 221 if (retval != EOK) { 222 errno = (int) retval; 223 return false; 224 } 225 226 event->type = IPC_GET_ARG1(ctrl->input_call); 227 event->key = IPC_GET_ARG2(ctrl->input_call); 228 event->mods = IPC_GET_ARG3(ctrl->input_call); 229 event->c = IPC_GET_ARG4(ctrl->input_call); 230 231 /* Update timeout */ 232 struct timeval t1; 233 gettimeofday(&t1, NULL); 234 *timeout -= tv_sub(&t1, &t0); 108 235 109 236 return true; -
uspace/lib/c/generic/io/io.c
r2bdf8313 rb0f00a9 44 44 #include <io/klog.h> 45 45 #include <vfs/vfs.h> 46 #include <ipc/devmap.h> 46 #include <vfs/vfs_sess.h> 47 #include <ipc/loc.h> 47 48 #include <adt/list.h> 48 49 #include "../private/io.h" 50 #include "../private/stdio.h" 49 51 50 52 static void _ffillbuf(FILE *stream); … … 56 58 .eof = true, 57 59 .klog = false, 58 . phone = -1,60 .sess = NULL, 59 61 .btype = _IONBF, 60 62 .buf = NULL, … … 70 72 .eof = false, 71 73 .klog = true, 72 . phone = -1,74 .sess = NULL, 73 75 .btype = _IOLBF, 74 76 .buf = NULL, … … 84 86 .eof = false, 85 87 .klog = true, 86 . phone = -1,88 .sess = NULL, 87 89 .btype = _IONBF, 88 90 .buf = NULL, … … 99 101 static LIST_INITIALIZE(files); 100 102 101 void __stdio_init(int filc , fdi_node_t *filv[])103 void __stdio_init(int filc) 102 104 { 103 105 if (filc > 0) { 104 stdin = f open_node(filv[0], "r");106 stdin = fdopen(0, "r"); 105 107 } else { 106 108 stdin = &stdin_null; … … 109 111 110 112 if (filc > 1) { 111 stdout = f open_node(filv[1], "w");113 stdout = fdopen(1, "w"); 112 114 } else { 113 115 stdout = &stdout_klog; … … 116 118 117 119 if (filc > 2) { 118 stderr = f open_node(filv[2], "w");120 stderr = fdopen(2, "w"); 119 121 } else { 120 122 stderr = &stderr_klog; … … 125 127 void __stdio_done(void) 126 128 { 127 link_t *link = files.next; 128 129 while (link != &files) { 130 FILE *file = list_get_instance(link, FILE, link); 129 while (!list_empty(&files)) { 130 FILE *file = list_get_instance(list_first(&files), FILE, link); 131 131 fclose(file); 132 link = files.next;133 132 } 134 133 } … … 255 254 stream->eof = false; 256 255 stream->klog = false; 257 stream-> phone = -1;256 stream->sess = NULL; 258 257 stream->need_sync = false; 259 258 _setvbuf(stream); … … 277 276 stream->eof = false; 278 277 stream->klog = false; 279 stream-> phone = -1;278 stream->sess = NULL; 280 279 stream->need_sync = false; 281 280 _setvbuf(stream); … … 286 285 } 287 286 288 FILE *fopen_node(fdi_node_t *node, const char *mode)289 {290 int flags;291 if (!parse_mode(mode, &flags))292 return NULL;293 294 /* Open file. */295 FILE *stream = malloc(sizeof(FILE));296 if (stream == NULL) {297 errno = ENOMEM;298 return NULL;299 }300 301 stream->fd = open_node(node, flags);302 if (stream->fd < 0) {303 /* errno was set by open_node() */304 free(stream);305 return NULL;306 }307 308 stream->error = false;309 stream->eof = false;310 stream->klog = false;311 stream->phone = -1;312 stream->need_sync = false;313 _setvbuf(stream);314 315 list_append(&stream->link, &files);316 317 return stream;318 }319 320 287 int fclose(FILE *stream) 321 288 { … … 324 291 fflush(stream); 325 292 326 if (stream-> phone >= 0)327 async_hangup(stream-> phone);293 if (stream->sess != NULL) 294 async_hangup(stream->sess); 328 295 329 296 if (stream->fd >= 0) … … 451 418 452 419 bytes_used = stream->buf_head - stream->buf_tail; 453 if (bytes_used == 0)454 return;455 420 456 421 /* If buffer has prefetched read data, we need to seek back. */ 457 if ( stream->buf_state == _bs_read)422 if (bytes_used > 0 && stream->buf_state == _bs_read) 458 423 lseek(stream->fd, - (ssize_t) bytes_used, SEEK_CUR); 459 424 460 425 /* If buffer has unwritten data, we need to write them out. */ 461 if ( stream->buf_state == _bs_write)426 if (bytes_used > 0 && stream->buf_state == _bs_write) 462 427 (void) _fwrite(stream->buf_tail, 1, bytes_used, stream); 463 428 … … 595 560 } 596 561 597 buf+= now;562 data += now; 598 563 stream->buf_head += now; 599 564 buf_free -= now; 600 565 bytes_left -= now; 601 566 total_written += now; 567 stream->buf_state = _bs_write; 602 568 603 569 if (buf_free == 0) { … … 607 573 } 608 574 } 609 610 if (total_written > 0)611 stream->buf_state = _bs_write;612 575 613 576 if (need_flush) … … 715 678 off64_t ftell(FILE *stream) 716 679 { 680 _fflushbuf(stream); 717 681 return lseek(stream->fd, 0, SEEK_CUR); 718 682 } … … 732 696 } 733 697 734 if ( stream->fd >= 0 && stream->need_sync) {698 if ((stream->fd >= 0) && (stream->need_sync)) { 735 699 /** 736 700 * Better than syncing always, but probably still not the … … 770 734 } 771 735 772 int fphone(FILE *stream)736 async_sess_t *fsession(exch_mgmt_t mgmt, FILE *stream) 773 737 { 774 738 if (stream->fd >= 0) { 775 if (stream->phone < 0) 776 stream->phone = fd_phone(stream->fd); 777 778 return stream->phone; 779 } 780 781 return -1; 782 } 783 784 int fnode(FILE *stream, fdi_node_t *node) 785 { 786 if (stream->fd >= 0) 787 return fd_node(stream->fd, node); 739 if (stream->sess == NULL) 740 stream->sess = fd_session(mgmt, stream->fd); 741 742 return stream->sess; 743 } 744 745 return NULL; 746 } 747 748 int fhandle(FILE *stream, int *handle) 749 { 750 if (stream->fd >= 0) { 751 *handle = stream->fd; 752 return EOK; 753 } 788 754 789 755 return ENOENT; -
uspace/lib/c/generic/io/klog.c
r2bdf8313 rb0f00a9 38 38 #include <sys/types.h> 39 39 #include <unistd.h> 40 #include <errno.h> 40 41 #include <io/klog.h> 42 #include <io/printf_core.h> 41 43 42 44 size_t klog_write(const void *buf, size_t size) … … 55 57 } 56 58 59 /** Print formatted text to klog. 60 * 61 * @param fmt Format string 62 * 63 * \see For more details about format string see printf_core. 64 * 65 */ 66 int klog_printf(const char *fmt, ...) 67 { 68 va_list args; 69 va_start(args, fmt); 70 71 int ret = klog_vprintf(fmt, args); 72 73 va_end(args); 74 75 return ret; 76 } 77 78 static int klog_vprintf_str_write(const char *str, size_t size, void *data) 79 { 80 size_t wr = klog_write(str, size); 81 return str_nlength(str, wr); 82 } 83 84 static int klog_vprintf_wstr_write(const wchar_t *str, size_t size, void *data) 85 { 86 size_t offset = 0; 87 size_t chars = 0; 88 89 while (offset < size) { 90 char buf[STR_BOUNDS(1)]; 91 size_t sz = 0; 92 93 if (chr_encode(str[chars], buf, &sz, STR_BOUNDS(1)) == EOK) 94 klog_write(buf, sz); 95 96 chars++; 97 offset += sizeof(wchar_t); 98 } 99 100 return chars; 101 } 102 103 /** Print formatted text to klog. 104 * 105 * @param fmt Format string 106 * @param ap Format parameters 107 * 108 * \see For more details about format string see printf_core. 109 * 110 */ 111 int klog_vprintf(const char *fmt, va_list ap) 112 { 113 printf_spec_t ps = { 114 klog_vprintf_str_write, 115 klog_vprintf_wstr_write, 116 NULL 117 }; 118 119 return printf_core(fmt, &ps, ap); 120 } 121 57 122 /** @} 58 123 */ -
uspace/lib/c/generic/io/printf_core.c
r2bdf8313 rb0f00a9 74 74 #define PRINT_NUMBER_BUFFER_SIZE (64 + 5) 75 75 76 /** Get signed or unsigned integer argument */ 77 #define PRINTF_GET_INT_ARGUMENT(type, ap, flags) \ 78 ({ \ 79 unsigned type res; \ 80 \ 81 if ((flags) & __PRINTF_FLAG_SIGNED) { \ 82 signed type arg = va_arg((ap), signed type); \ 83 \ 84 if (arg < 0) { \ 85 res = -arg; \ 86 (flags) |= __PRINTF_FLAG_NEGATIVE; \ 87 } else \ 88 res = arg; \ 89 } else \ 90 res = va_arg((ap), unsigned type); \ 91 \ 92 res; \ 93 }) 94 76 95 /** Enumeration of possible arguments types. 77 96 */ … … 206 225 } 207 226 208 return (int) (counter + 1);227 return (int) (counter); 209 228 } 210 229 … … 244 263 } 245 264 246 return (int) (counter + 1);265 return (int) (counter); 247 266 } 248 267 … … 831 850 size_t size; 832 851 uint64_t number; 852 833 853 switch (qualifier) { 834 854 case PrintfQualifierByte: 835 855 size = sizeof(unsigned char); 836 number = (uint64_t) va_arg(ap, unsigned int);856 number = PRINTF_GET_INT_ARGUMENT(int, ap, flags); 837 857 break; 838 858 case PrintfQualifierShort: 839 859 size = sizeof(unsigned short); 840 number = (uint64_t) va_arg(ap, unsigned int);860 number = PRINTF_GET_INT_ARGUMENT(int, ap, flags); 841 861 break; 842 862 case PrintfQualifierInt: 843 863 size = sizeof(unsigned int); 844 number = (uint64_t) va_arg(ap, unsigned int);864 number = PRINTF_GET_INT_ARGUMENT(int, ap, flags); 845 865 break; 846 866 case PrintfQualifierLong: 847 867 size = sizeof(unsigned long); 848 number = (uint64_t) va_arg(ap, unsigned long);868 number = PRINTF_GET_INT_ARGUMENT(long, ap, flags); 849 869 break; 850 870 case PrintfQualifierLongLong: 851 871 size = sizeof(unsigned long long); 852 number = (uint64_t) va_arg(ap, unsigned long long);872 number = PRINTF_GET_INT_ARGUMENT(long long, ap, flags); 853 873 break; 854 874 case PrintfQualifierPointer: … … 865 885 counter = -counter; 866 886 goto out; 867 }868 869 if (flags & __PRINTF_FLAG_SIGNED) {870 if (number & (0x1 << (size * 8 - 1))) {871 flags |= __PRINTF_FLAG_NEGATIVE;872 873 if (size == sizeof(uint64_t)) {874 number = -((int64_t) number);875 } else {876 number = ~number;877 number &=878 ~(0xFFFFFFFFFFFFFFFFll <<879 (size * 8));880 number++;881 }882 }883 887 } 884 888 -
uspace/lib/c/generic/io/vprintf.c
r2bdf8313 rb0f00a9 96 96 /** Print formatted text to stdout. 97 97 * 98 * @param file Output stream 99 * @param fmt Format string 100 * @param ap Format parameters 98 * @param fmt Format string 99 * @param ap Format parameters 101 100 * 102 101 * \see For more details about format string see printf_core. -
uspace/lib/c/generic/ipc.c
r2bdf8313 rb0f00a9 47 47 #include <futex.h> 48 48 #include <fibril.h> 49 #include <macros.h> 49 50 50 51 /** … … 458 459 while (!list_empty(&queued_calls)) { 459 460 async_call_t *call = 460 list_get_instance( queued_calls.next, async_call_t, list);461 list_get_instance(list_first(&queued_calls), async_call_t, list); 461 462 ipc_callid_t callid = 462 463 ipc_call_async_internal(call->u.msg.phoneid, &call->u.msg.data); … … 511 512 512 513 link_t *item; 513 for (item = dispatched_calls. next; item != &dispatched_calls;514 for (item = dispatched_calls.head.next; item != &dispatched_calls.head; 514 515 item = item->next) { 515 516 async_call_t *call = … … 611 612 /** Request callback connection. 612 613 * 613 * The @a task hashand @a phonehash identifiers returned614 * The @a task_id and @a phonehash identifiers returned 614 615 * by the kernel can be used for connection tracking. 615 616 * … … 618 619 * @param arg2 User defined argument. 619 620 * @param arg3 User defined argument. 620 * @param task hash Opaque identifier of the client task.621 * @param task_id Identifier of the client task. 621 622 * @param phonehash Opaque identifier of the phone that will 622 623 * be used for incoming calls. … … 626 627 */ 627 628 int ipc_connect_to_me(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, 628 sysarg_t *taskhash, sysarg_t *phonehash) 629 { 630 return ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_TO_ME, arg1, arg2, 631 arg3, NULL, NULL, NULL, taskhash, phonehash); 629 task_id_t *task_id, sysarg_t *phonehash) 630 { 631 ipc_call_t data; 632 int rc = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, 633 IPC_M_CONNECT_TO_ME, arg1, arg2, arg3, (sysarg_t) &data); 634 if (rc == EOK) { 635 *task_id = data.in_task_id; 636 *phonehash = IPC_GET_ARG5(data); 637 } 638 return rc; 639 } 640 641 /** Request cloned connection. 642 * 643 * @param phoneid Phone handle used for contacting the other side. 644 * 645 * @return Cloned phone handle on success or a negative error code. 646 * 647 */ 648 int ipc_connect_me(int phoneid) 649 { 650 sysarg_t newphid; 651 int res = ipc_call_sync_0_5(phoneid, IPC_M_CONNECT_ME, NULL, NULL, 652 NULL, NULL, &newphid); 653 if (res) 654 return res; 655 656 return newphid; 632 657 } 633 658 -
uspace/lib/c/generic/libc.c
r2bdf8313 rb0f00a9 49 49 #include "private/libc.h" 50 50 #include "private/async.h" 51 #include "private/async_sess.h"52 51 #include "private/malloc.h" 53 52 #include "private/io.h" … … 64 63 __malloc_init(); 65 64 __async_init(); 66 __async_sess_init();67 65 68 66 fibril_t *fibril = fibril_setup(); … … 93 91 argc = 0; 94 92 argv = NULL; 95 __stdio_init(0 , NULL);93 __stdio_init(0); 96 94 } else { 97 95 argc = __pcb->argc; 98 96 argv = __pcb->argv; 99 __stdio_init(__pcb->filc , __pcb->filv);97 __stdio_init(__pcb->filc); 100 98 (void) chdir(__pcb->cwd); 101 99 } -
uspace/lib/c/generic/loader.c
r2bdf8313 rb0f00a9 35 35 #include <ipc/loader.h> 36 36 #include <ipc/services.h> 37 #include < ipc/ns.h>37 #include <ns.h> 38 38 #include <libc.h> 39 39 #include <task.h> … … 44 44 #include <vfs/vfs.h> 45 45 #include <loader/loader.h> 46 #include "private/loader.h" 46 47 47 48 /** Connect to a new program loader. … … 63 64 loader_t *loader_connect(void) 64 65 { 65 int phone_id = service_connect_blocking(SERVICE_LOAD, 0, 0);66 if (phone_id < 0)67 return NULL;68 69 66 loader_t *ldr = malloc(sizeof(loader_t)); 70 67 if (ldr == NULL) 71 68 return NULL; 72 69 73 ldr->phone_id = phone_id; 70 async_sess_t *sess = 71 service_connect_blocking(EXCHANGE_SERIALIZE, SERVICE_LOAD, 0, 0); 72 if (sess == NULL) { 73 free(ldr); 74 return NULL; 75 } 76 77 ldr->sess = sess; 74 78 return ldr; 75 79 } … … 88 92 { 89 93 /* Get task ID. */ 90 ipc_call_t answer; 91 aid_t req = async_send_0(ldr->phone_id, LOADER_GET_TASKID, &answer); 92 int rc = async_data_read_start(ldr->phone_id, task_id, sizeof(task_id_t)); 93 if (rc != EOK) { 94 async_wait_for(req, NULL); 95 return rc; 96 } 97 98 sysarg_t retval; 99 async_wait_for(req, &retval); 100 return (int) retval; 94 async_exch_t *exch = async_exchange_begin(ldr->sess); 95 96 ipc_call_t answer; 97 aid_t req = async_send_0(exch, LOADER_GET_TASKID, &answer); 98 sysarg_t rc = async_data_read_start(exch, task_id, sizeof(task_id_t)); 99 100 async_exchange_end(exch); 101 102 if (rc != EOK) { 103 async_wait_for(req, NULL); 104 return (int) rc; 105 } 106 107 async_wait_for(req, &rc); 108 return (int) rc; 101 109 } 102 110 … … 112 120 int loader_set_cwd(loader_t *ldr) 113 121 { 114 char *cwd; 115 size_t len; 116 117 cwd = (char *) malloc(MAX_PATH_LEN + 1); 122 char *cwd = (char *) malloc(MAX_PATH_LEN + 1); 118 123 if (!cwd) 119 124 return ENOMEM; 125 120 126 if (!getcwd(cwd, MAX_PATH_LEN + 1)) 121 str_cpy(cwd, MAX_PATH_LEN + 1, "/"); 122 len = str_length(cwd); 123 124 ipc_call_t answer; 125 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_CWD, &answer); 126 int rc = async_data_write_start(ldr->phone_id, cwd, len); 127 str_cpy(cwd, MAX_PATH_LEN + 1, "/"); 128 129 size_t len = str_length(cwd); 130 131 async_exch_t *exch = async_exchange_begin(ldr->sess); 132 133 ipc_call_t answer; 134 aid_t req = async_send_0(exch, LOADER_SET_CWD, &answer); 135 sysarg_t rc = async_data_write_start(exch, cwd, len); 136 137 async_exchange_end(exch); 127 138 free(cwd); 128 if (rc != EOK) {129 async_wait_for(req, NULL);130 return rc;131 }132 133 sysarg_t retval;134 async_wait_for(req, &r etval);135 return (int) r etval;139 140 if (rc != EOK) { 141 async_wait_for(req, NULL); 142 return (int) rc; 143 } 144 145 async_wait_for(req, &rc); 146 return (int) rc; 136 147 } 137 148 … … 153 164 char *pa = absolutize(path, &pa_len); 154 165 if (!pa) 155 return 0;166 return ENOMEM; 156 167 157 168 /* Send program pathname */ 158 ipc_call_t answer; 159 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_PATHNAME, &answer); 160 int rc = async_data_write_start(ldr->phone_id, (void *) pa, pa_len); 161 if (rc != EOK) { 162 free(pa); 163 async_wait_for(req, NULL); 164 return rc; 165 } 166 169 async_exch_t *exch = async_exchange_begin(ldr->sess); 170 171 ipc_call_t answer; 172 aid_t req = async_send_0(exch, LOADER_SET_PATHNAME, &answer); 173 sysarg_t rc = async_data_write_start(exch, (void *) pa, pa_len); 174 175 async_exchange_end(exch); 167 176 free(pa); 168 177 169 sysarg_t retval; 170 async_wait_for(req, &retval); 171 return (int) retval; 178 if (rc != EOK) { 179 async_wait_for(req, NULL); 180 return (int) rc; 181 } 182 183 async_wait_for(req, &rc); 184 return (int) rc; 172 185 } 173 186 … … 212 225 213 226 /* Send serialized arguments to the loader */ 214 ipc_call_t answer; 215 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_ARGS, &answer); 216 sysarg_t rc = async_data_write_start(ldr->phone_id, (void *) arg_buf, buffer_size); 217 if (rc != EOK) { 218 async_wait_for(req, NULL); 219 return rc; 220 } 221 222 async_wait_for(req, &rc); 223 if (rc != EOK) 224 return rc; 225 226 /* Free temporary buffer */ 227 async_exch_t *exch = async_exchange_begin(ldr->sess); 228 229 ipc_call_t answer; 230 aid_t req = async_send_0(exch, LOADER_SET_ARGS, &answer); 231 sysarg_t rc = async_data_write_start(exch, (void *) arg_buf, 232 buffer_size); 233 234 async_exchange_end(exch); 227 235 free(arg_buf); 228 236 229 return EOK; 237 if (rc != EOK) { 238 async_wait_for(req, NULL); 239 return (int) rc; 240 } 241 242 async_wait_for(req, &rc); 243 return (int) rc; 230 244 } 231 245 … … 242 256 * 243 257 */ 244 int loader_set_files(loader_t *ldr, fdi_node_t *const files[]) 245 { 246 /* 247 * Serialize the arguments into a single array. First 248 * compute size of the buffer needed. 249 */ 250 fdi_node_t *const *ap = files; 251 size_t count = 0; 252 while (*ap != NULL) { 253 count++; 254 ap++; 255 } 256 257 fdi_node_t *files_buf; 258 files_buf = (fdi_node_t *) malloc(count * sizeof(fdi_node_t)); 259 if (files_buf == NULL) 260 return ENOMEM; 261 262 /* Fill the buffer */ 263 size_t i; 264 for (i = 0; i < count; i++) 265 files_buf[i] = *files[i]; 266 258 int loader_set_files(loader_t *ldr, int * const files[]) 259 { 267 260 /* Send serialized files to the loader */ 268 ipc_call_t answer; 269 aid_t req = async_send_0(ldr->phone_id, LOADER_SET_FILES, &answer); 270 sysarg_t rc = async_data_write_start(ldr->phone_id, (void *) files_buf, 271 count * sizeof(fdi_node_t)); 272 if (rc != EOK) { 273 async_wait_for(req, NULL); 274 return rc; 275 } 276 277 async_wait_for(req, &rc); 278 if (rc != EOK) 279 return rc; 280 281 /* Free temporary buffer */ 282 free(files_buf); 283 284 return EOK; 261 async_exch_t *exch = async_exchange_begin(ldr->sess); 262 async_exch_t *vfs_exch = vfs_exchange_begin(); 263 264 int i; 265 for (i = 0; files[i]; i++); 266 267 ipc_call_t answer; 268 aid_t req = async_send_1(exch, LOADER_SET_FILES, i, &answer); 269 270 sysarg_t rc = EOK; 271 272 for (i = 0; files[i]; i++) { 273 rc = async_state_change_start(exch, VFS_PASS_HANDLE, *files[i], 274 0, vfs_exch); 275 if (rc != EOK) 276 break; 277 } 278 279 vfs_exchange_end(vfs_exch); 280 async_exchange_end(exch); 281 282 if (rc != EOK) { 283 async_wait_for(req, NULL); 284 return (int) rc; 285 } 286 287 async_wait_for(req, &rc); 288 return (int) rc; 285 289 } 286 290 … … 297 301 int loader_load_program(loader_t *ldr) 298 302 { 299 return (int) async_req_0_0(ldr->phone_id, LOADER_LOAD); 303 async_exch_t *exch = async_exchange_begin(ldr->sess); 304 int rc = async_req_0_0(exch, LOADER_LOAD); 305 async_exchange_end(exch); 306 307 return rc; 300 308 } 301 309 … … 306 314 * the task and its thread is stopped. 307 315 * 308 * After using this function, no further operations mustbe performed309 * on the loader structure . It should be de-allocated using free().316 * After using this function, no further operations can be performed 317 * on the loader structure and it is deallocated. 310 318 * 311 319 * @param ldr Loader connection structure. … … 316 324 int loader_run(loader_t *ldr) 317 325 { 318 int rc = async_req_0_0(ldr->phone_id, LOADER_RUN); 326 async_exch_t *exch = async_exchange_begin(ldr->sess); 327 int rc = async_req_0_0(exch, LOADER_RUN); 328 async_exchange_end(exch); 329 319 330 if (rc != EOK) 320 331 return rc; 321 332 322 async_hangup(ldr->phone_id); 323 ldr->phone_id = 0; 333 async_hangup(ldr->sess); 334 free(ldr); 335 324 336 return EOK; 325 337 } … … 327 339 /** Cancel the loader session. 328 340 * 329 * Tell sthe loader not to load any program and terminate.330 * After using this function, no further operations mustbe performed331 * on the loader structure . It should be de-allocated using free().341 * Tell the loader not to load any program and terminate. 342 * After using this function, no further operations can be performed 343 * on the loader structure and it is deallocated. 332 344 * 333 345 * @param ldr Loader connection structure. … … 338 350 void loader_abort(loader_t *ldr) 339 351 { 340 async_hangup(ldr-> phone_id);341 ldr->phone_id = 0;352 async_hangup(ldr->sess); 353 free(ldr); 342 354 } 343 355 -
uspace/lib/c/generic/malloc.c
r2bdf8313 rb0f00a9 79 79 (sizeof(heap_block_head_t) + sizeof(heap_block_foot_t)) 80 80 81 /** Overhead of each area. */ 82 #define AREA_OVERHEAD(size) \ 83 (ALIGN_UP(size + sizeof(heap_area_t), BASE_ALIGN)) 84 81 85 /** Calculate real size of a heap block. 82 86 * … … 183 187 184 188 /** Next heap block to examine (next fit algorithm) */ 185 static heap_block_head_t *next = NULL;189 static heap_block_head_t *next_fit = NULL; 186 190 187 191 /** Futex for thread-safe heap manipulation */ … … 194 198 if (!(expr)) {\ 195 199 futex_up(&malloc_futex); \ 196 assert_abort(#expr, __FILE__, STR2(__LINE__)); \200 assert_abort(#expr, __FILE__, __LINE__); \ 197 201 } \ 198 202 } while (0) … … 378 382 379 383 /* Eventually try to create a new area */ 380 return area_create(AREA_ FIRST_BLOCK_HEAD(size));384 return area_create(AREA_OVERHEAD(size)); 381 385 } 382 386 … … 455 459 /* Update heap area parameters */ 456 460 area->end = end; 457 458 /* Update block layout */ 459 void *last = (void *) last_head; 460 size_t excess = (size_t) (area->end - last); 461 size_t excess = ((size_t) area->end) - ((size_t) last_head); 461 462 462 463 if (excess > 0) { … … 467 468 * create a new free block. 468 469 */ 469 block_init( last, excess, true, area);470 block_init((void *) last_head, excess, true, area); 470 471 } else { 471 472 /* … … 486 487 } 487 488 488 next = NULL;489 next_fit = NULL; 489 490 } 490 491 … … 575 576 split_mark(cur, real_size); 576 577 577 next = cur;578 next_fit = cur; 578 579 return addr; 579 580 } else { … … 627 628 split_mark(next_head, real_size); 628 629 629 next = next_head;630 next_fit = next_head; 630 631 return aligned; 631 632 } else { … … 653 654 split_mark(cur, real_size); 654 655 655 next = cur;656 next_fit = cur; 656 657 return aligned; 657 658 } … … 691 692 692 693 /* Try the next fit approach */ 693 split = next ;694 split = next_fit; 694 695 695 696 if (split != NULL) { … … 847 848 848 849 ptr = ((void *) head) + sizeof(heap_block_head_t); 849 next = NULL;850 next_fit = NULL; 850 851 } else 851 852 reloc = true; … … 872 873 void free(const void *addr) 873 874 { 875 if (addr == NULL) 876 return; 877 874 878 futex_down(&malloc_futex); 875 879 -
uspace/lib/c/generic/net/icmp_api.c
r2bdf8313 rb0f00a9 54 54 * timeout occurs. 55 55 * 56 * @param[in] icmp_phone The ICMP module phone used for (semi)remote calls.56 * @param[in] sess The ICMP session. 57 57 * @param[in] size The message data length in bytes. 58 58 * @param[in] timeout The timeout in milliseconds. … … 73 73 */ 74 74 int 75 icmp_echo_msg( int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl,75 icmp_echo_msg(async_sess_t *sess, size_t size, mseconds_t timeout, ip_ttl_t ttl, 76 76 ip_tos_t tos, int dont_fragment, const struct sockaddr *addr, 77 77 socklen_t addrlen) … … 82 82 if (addrlen <= 0) 83 83 return EINVAL; 84 85 message_id = async_send_5(icmp_phone, NET_ICMP_ECHO, size, timeout, ttl, 84 85 async_exch_t *exch = async_exchange_begin(sess); 86 87 message_id = async_send_5(exch, NET_ICMP_ECHO, size, timeout, ttl, 86 88 tos, (sysarg_t) dont_fragment, NULL); 87 89 88 90 /* Send the address */ 89 async_data_write_start(icmp_phone, addr, (size_t) addrlen); 91 async_data_write_start(exch, addr, (size_t) addrlen); 92 93 async_exchange_end(exch); 90 94 91 95 async_wait_for(message_id, &result); -
uspace/lib/c/generic/net/icmp_common.c
r2bdf8313 rb0f00a9 45 45 /** Connect to the ICMP module. 46 46 * 47 * @param[in] timeout Connection timeout in microseconds, zero 48 * for no timeout. 49 * 50 * @return ICMP module phone on success. 51 * @return ETIMEOUT if the connection timeouted. 47 * @return ICMP module session. 52 48 * 53 49 */ 54 int icmp_connect_module(suseconds_t timeout)50 async_sess_t *icmp_connect_module(void) 55 51 { 56 return connect_to_service _timeout(SERVICE_ICMP, timeout);52 return connect_to_service(SERVICE_ICMP); 57 53 } 58 54 -
uspace/lib/c/generic/net/modules.c
r2bdf8313 rb0f00a9 45 45 #include <ipc/services.h> 46 46 #include <net/modules.h> 47 48 /** The time between connect requests in microseconds. */ 49 #define MODULE_WAIT_TIME (10 * 1000) 47 #include <ns.h> 50 48 51 49 /** Answer a call. … … 95 93 } 96 94 97 /** Create bidirectional connection with the needed module service and register s95 /** Create bidirectional connection with the needed module service and register 98 96 * the message receiver. 99 97 * 100 * @param[in] need The needed module service. 101 * @param[in] arg1 The first parameter. 102 * @param[in] arg2 The second parameter. 103 * @param[in] arg3 The third parameter. 104 * @param[in] client_receiver The message receiver. 105 * 106 * @return The phone of the needed service. 107 * @return Other error codes as defined for the ipc_connect_to_me() 108 * function. 109 */ 110 int bind_service(services_t need, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, 111 async_client_conn_t client_receiver) 112 { 113 return bind_service_timeout(need, arg1, arg2, arg3, client_receiver, 0); 114 } 115 116 /** Create bidirectional connection with the needed module service and registers 117 * the message receiver. 118 * 119 * @param[in] need The needed module service. 120 * @param[in] arg1 The first parameter. 121 * @param[in] arg2 The second parameter. 122 * @param[in] arg3 The third parameter. 123 * @param[in] client_receiver The message receiver. 124 * @param[in] timeout The connection timeout in microseconds. No timeout if 125 * set to zero (0). 126 * 127 * @return The phone of the needed service. 128 * @return ETIMEOUT if the connection timeouted. 129 * @return Other error codes as defined for the ipc_connect_to_me() 130 * function. 131 * 132 */ 133 int bind_service_timeout(services_t need, sysarg_t arg1, sysarg_t arg2, 134 sysarg_t arg3, async_client_conn_t client_receiver, suseconds_t timeout) 98 * @param[in] need Needed module service. 99 * @param[in] arg1 First parameter. 100 * @param[in] arg2 Second parameter. 101 * @param[in] arg3 Third parameter. 102 * @param[in] client_receiver Message receiver. 103 * 104 * @return Session to the needed service. 105 * @return Other error codes as defined for the async_connect_to_me() 106 * function. 107 * 108 */ 109 async_sess_t *bind_service(services_t need, sysarg_t arg1, sysarg_t arg2, 110 sysarg_t arg3, async_client_conn_t client_receiver) 135 111 { 136 112 /* Connect to the needed service */ 137 int phone = connect_to_service_timeout(need, timeout);138 if ( phone >= 0) {113 async_sess_t *sess = connect_to_service(need); 114 if (sess != NULL) { 139 115 /* Request the bidirectional connection */ 140 int rc = async_connect_to_me(phone, arg1, arg2, arg3, client_receiver); 116 async_exch_t *exch = async_exchange_begin(sess); 117 int rc = async_connect_to_me(exch, arg1, arg2, arg3, 118 client_receiver, NULL); 119 async_exchange_end(exch); 120 141 121 if (rc != EOK) { 142 async_hangup(phone); 143 return rc; 122 async_hangup(sess); 123 errno = rc; 124 return NULL; 144 125 } 145 126 } 146 127 147 return phone; 148 } 149 150 /** Connects to the needed module. 151 * 152 * @param[in] need The needed module service. 153 * @return The phone of the needed service. 154 */ 155 int connect_to_service(services_t need) 156 { 157 return connect_to_service_timeout(need, 0); 158 } 159 160 /** Connects to the needed module. 161 * 162 * @param[in] need The needed module service. 163 * @param[in] timeout The connection timeout in microseconds. No timeout if 164 * set to zero (0). 165 * @return The phone of the needed service. 166 * @return ETIMEOUT if the connection timeouted. 167 */ 168 int connect_to_service_timeout(services_t need, suseconds_t timeout) 169 { 170 int phone; 171 172 /* If no timeout is set */ 173 if (timeout <= 0) 174 return async_connect_me_to_blocking(PHONE_NS, need, 0, 0); 175 176 while (true) { 177 phone = async_connect_me_to(PHONE_NS, need, 0, 0); 178 if ((phone >= 0) || (phone != ENOENT)) 179 return phone; 180 181 /* Abort if no time is left */ 182 if (timeout <= 0) 183 return ETIMEOUT; 184 185 /* Wait the minimum of the module wait time and the timeout */ 186 usleep((timeout <= MODULE_WAIT_TIME) ? 187 timeout : MODULE_WAIT_TIME); 188 timeout -= MODULE_WAIT_TIME; 189 } 190 } 191 192 /** Replies the data to the other party. 193 * 194 * @param[in] data The data buffer to be sent. 128 return sess; 129 } 130 131 /** Connect to the needed module. 132 * 133 * @param[in] need Needed module service. 134 * 135 * @return Session to the needed service. 136 * @return NULL if the connection timeouted. 137 * 138 */ 139 async_sess_t *connect_to_service(services_t need) 140 { 141 return service_connect_blocking(EXCHANGE_SERIALIZE, need, 0, 0); 142 } 143 144 /** Reply the data to the other party. 145 * 146 * @param[in] data The data buffer to be sent. 195 147 * @param[in] data_length The buffer length. 196 * @return EOK on success. 197 * @return EINVAL if the client does not expect the data. 198 * @return EOVERFLOW if the client does not expect all the data. 199 * Only partial data are transfered. 200 * @return Other error codes as defined for the 201 * async_data_read_finalize() function. 148 * 149 * @return EOK on success. 150 * @return EINVAL if the client does not expect the data. 151 * @return EOVERFLOW if the client does not expect all the data. 152 * Only partial data are transfered. 153 * @return Other error codes as defined for the 154 * async_data_read_finalize() function. 155 * 202 156 */ 203 157 int data_reply(void *data, size_t data_length) … … 205 159 size_t length; 206 160 ipc_callid_t callid; 207 161 208 162 /* Fetch the request */ 209 163 if (!async_data_read_receive(&callid, &length)) 210 164 return EINVAL; 211 165 212 166 /* Check the requested data size */ 213 167 if (length < data_length) { … … 215 169 return EOVERFLOW; 216 170 } 217 171 218 172 /* Send the data */ 219 173 return async_data_read_finalize(callid, data, data_length); -
uspace/lib/c/generic/net/packet.c
r2bdf8313 rb0f00a9 36 36 */ 37 37 38 #include <assert.h> 38 39 #include <malloc.h> 39 40 #include <mem.h> … … 44 45 #include <sys/mman.h> 45 46 46 #include <adt/ generic_field.h>47 #include <adt/hash_table.h> 47 48 #include <net/packet.h> 48 49 #include <net/packet_header.h> 49 50 50 /** Packet map page size. */ 51 #define PACKET_MAP_SIZE 100 52 53 /** Returns the packet map page index. 54 * @param[in] packet_id The packet identifier. 55 */ 56 #define PACKET_MAP_PAGE(packet_id) (((packet_id) - 1) / PACKET_MAP_SIZE) 57 58 /** Returns the packet index in the corresponding packet map page. 59 * @param[in] packet_id The packet identifier. 60 */ 61 #define PACKET_MAP_INDEX(packet_id) (((packet_id) - 1) % PACKET_MAP_SIZE) 62 63 /** Type definition of the packet map page. */ 64 typedef packet_t *packet_map_t[PACKET_MAP_SIZE]; 65 66 /** Packet map. 67 * Maps packet identifiers to the packet references. 68 * @see generic_field.h 69 */ 70 GENERIC_FIELD_DECLARE(gpm, packet_map_t); 51 /** Packet hash table size. */ 52 #define PACKET_HASH_TABLE_SIZE 128 71 53 72 54 /** Packet map global data. */ … … 75 57 fibril_rwlock_t lock; 76 58 /** Packet map. */ 77 gpm_t packet_map; 59 hash_table_t packet_map; 60 /** Packet map operations */ 61 hash_table_operations_t operations; 78 62 } pm_globals; 79 63 80 GENERIC_FIELD_IMPLEMENT(gpm, packet_map_t); 64 typedef struct { 65 link_t link; 66 packet_t *packet; 67 } pm_entry_t; 68 69 /** 70 * Hash function for the packet mapping hash table 71 */ 72 static hash_index_t pm_hash(unsigned long key[]) 73 { 74 return (hash_index_t) key[0] % PACKET_HASH_TABLE_SIZE; 75 } 76 77 /** 78 * Key compare function for the packet mapping hash table 79 */ 80 static int pm_compare(unsigned long key[], hash_count_t keys, link_t *link) 81 { 82 pm_entry_t *entry = list_get_instance(link, pm_entry_t, link); 83 return entry->packet->packet_id == key[0]; 84 } 85 86 /** 87 * Remove callback for the packet mapping hash table 88 */ 89 static void pm_remove_callback(link_t *link) 90 { 91 pm_entry_t *entry = list_get_instance(link, pm_entry_t, link); 92 free(entry); 93 } 94 95 /** 96 * Wrapper used when destroying the whole table 97 */ 98 static void pm_free_wrapper(link_t *link, void *ignored) 99 { 100 pm_entry_t *entry = list_get_instance(link, pm_entry_t, link); 101 free(entry); 102 } 103 81 104 82 105 /** Initializes the packet map. … … 87 110 int pm_init(void) 88 111 { 89 int rc ;112 int rc = EOK; 90 113 91 114 fibril_rwlock_initialize(&pm_globals.lock); 92 115 93 116 fibril_rwlock_write_lock(&pm_globals.lock); 94 rc = gpm_initialize(&pm_globals.packet_map); 117 118 pm_globals.operations.hash = pm_hash; 119 pm_globals.operations.compare = pm_compare; 120 pm_globals.operations.remove_callback = pm_remove_callback; 121 122 if (!hash_table_create(&pm_globals.packet_map, PACKET_HASH_TABLE_SIZE, 1, 123 &pm_globals.operations)) 124 rc = ENOMEM; 125 95 126 fibril_rwlock_write_unlock(&pm_globals.lock); 96 127 … … 100 131 /** Finds the packet mapping. 101 132 * 102 * @param[in] packet_id The packet identifier to be found. 103 * @return The found packet reference. 104 * @return NULL if the mapping does not exist. 133 * @param[in] packet_id Packet identifier to be found. 134 * 135 * @return The found packet reference. 136 * @return NULL if the mapping does not exist. 137 * 105 138 */ 106 139 packet_t *pm_find(packet_id_t packet_id) 107 140 { 108 packet_map_t *map;109 packet_t *packet;110 111 141 if (!packet_id) 112 142 return NULL; 113 143 114 144 fibril_rwlock_read_lock(&pm_globals.lock); 115 if (packet_id > PACKET_MAP_SIZE * gpm_count(&pm_globals.packet_map)) { 116 fibril_rwlock_read_unlock(&pm_globals.lock); 117 return NULL; 118 } 119 map = gpm_get_index(&pm_globals.packet_map, PACKET_MAP_PAGE(packet_id)); 120 if (!map) { 121 fibril_rwlock_read_unlock(&pm_globals.lock); 122 return NULL; 123 } 124 packet = (*map) [PACKET_MAP_INDEX(packet_id)]; 145 146 unsigned long key = packet_id; 147 link_t *link = hash_table_find(&pm_globals.packet_map, &key); 148 149 packet_t *packet; 150 if (link != NULL) { 151 pm_entry_t *entry = 152 hash_table_get_instance(link, pm_entry_t, link); 153 packet = entry->packet; 154 } else 155 packet = NULL; 156 125 157 fibril_rwlock_read_unlock(&pm_globals.lock); 126 158 return packet; … … 129 161 /** Adds the packet mapping. 130 162 * 131 * @param[in] packet The packet to be remembered. 132 * @return EOK on success. 133 * @return EINVAL if the packet is not valid. 134 * @return EINVAL if the packet map is not initialized. 135 * @return ENOMEM if there is not enough memory left. 163 * @param[in] packet Packet to be remembered. 164 * 165 * @return EOK on success. 166 * @return EINVAL if the packet is not valid. 167 * @return ENOMEM if there is not enough memory left. 168 * 136 169 */ 137 170 int pm_add(packet_t *packet) 138 171 { 139 packet_map_t *map;140 int rc;141 142 172 if (!packet_is_valid(packet)) 143 173 return EINVAL; 144 174 145 175 fibril_rwlock_write_lock(&pm_globals.lock); 146 147 if (PACKET_MAP_PAGE(packet->packet_id) < 148 gpm_count(&pm_globals.packet_map)) { 149 map = gpm_get_index(&pm_globals.packet_map, 150 PACKET_MAP_PAGE(packet->packet_id)); 151 } else { 152 do { 153 map = (packet_map_t *) malloc(sizeof(packet_map_t)); 154 if (!map) { 155 fibril_rwlock_write_unlock(&pm_globals.lock); 156 return ENOMEM; 157 } 158 bzero(map, sizeof(packet_map_t)); 159 rc = gpm_add(&pm_globals.packet_map, map); 160 if (rc < 0) { 161 fibril_rwlock_write_unlock(&pm_globals.lock); 162 free(map); 163 return rc; 164 } 165 } while (PACKET_MAP_PAGE(packet->packet_id) >= 166 gpm_count(&pm_globals.packet_map)); 176 177 pm_entry_t *entry = malloc(sizeof(pm_entry_t)); 178 if (entry == NULL) { 179 fibril_rwlock_write_unlock(&pm_globals.lock); 180 return ENOMEM; 167 181 } 168 169 (*map) [PACKET_MAP_INDEX(packet->packet_id)] = packet; 182 183 entry->packet = packet; 184 185 unsigned long key = packet->packet_id; 186 hash_table_insert(&pm_globals.packet_map, &key, &entry->link); 187 170 188 fibril_rwlock_write_unlock(&pm_globals.lock); 189 171 190 return EOK; 172 191 } 173 192 174 /** Releases the packet map. */ 193 /** Remove the packet mapping 194 * 195 * @param[in] packet The packet to be removed 196 * 197 */ 198 void pm_remove(packet_t *packet) 199 { 200 assert(packet_is_valid(packet)); 201 202 fibril_rwlock_write_lock(&pm_globals.lock); 203 204 unsigned long key = packet->packet_id; 205 hash_table_remove(&pm_globals.packet_map, &key, 1); 206 207 fibril_rwlock_write_unlock(&pm_globals.lock); 208 } 209 210 /** Release the packet map. */ 175 211 void pm_destroy(void) 176 212 { 177 int count;178 int index;179 packet_map_t *map;180 packet_t *packet;181 182 213 fibril_rwlock_write_lock(&pm_globals.lock); 183 count = gpm_count(&pm_globals.packet_map); 184 while (count > 0) { 185 map = gpm_get_index(&pm_globals.packet_map, count - 1); 186 for (index = PACKET_MAP_SIZE - 1; index >= 0; --index) { 187 packet = (*map)[index]; 188 if (packet_is_valid(packet)) 189 munmap(packet, packet->length); 190 } 191 } 192 gpm_destroy(&pm_globals.packet_map, free); 193 /* leave locked */ 214 hash_table_apply(&pm_globals.packet_map, pm_free_wrapper, NULL); 215 hash_table_destroy(&pm_globals.packet_map); 216 /* Leave locked */ 194 217 } 195 218 … … 199 222 * The packet is inserted right before the packets of the same order value. 200 223 * 201 * @param[in,out] first The first packet of the queue. Sets the first packet of 202 * the queue. The original first packet may be shifted by 203 * the new packet. 204 * @param[in] packet The packet to be added. 205 * @param[in] order The packet order value. 206 * @param[in] metric The metric value of the packet. 207 * @return EOK on success. 208 * @return EINVAL if the first parameter is NULL. 209 * @return EINVAL if the packet is not valid. 224 * @param[in,out] first First packet of the queue. Sets the first 225 * packet of the queue. The original first packet 226 * may be shifted by the new packet. 227 * @param[in] packet Packet to be added. 228 * @param[in] order Packet order value. 229 * @param[in] metric Metric value of the packet. 230 * 231 * @return EOK on success. 232 * @return EINVAL if the first parameter is NULL. 233 * @return EINVAL if the packet is not valid. 234 * 210 235 */ 211 236 int pq_add(packet_t **first, packet_t *packet, size_t order, size_t metric) 212 237 { 213 packet_t *item; 214 215 if (!first || !packet_is_valid(packet)) 238 if ((!first) || (!packet_is_valid(packet))) 216 239 return EINVAL; 217 240 218 241 pq_set_order(packet, order, metric); 219 242 if (packet_is_valid(*first)) { 220 item = * first; 243 packet_t *cur = *first; 244 221 245 do { 222 if (item->order < order) { 223 if (item->next) { 224 item = pm_find(item->next); 225 } else { 226 item->next = packet->packet_id; 227 packet->previous = item->packet_id; 246 if (cur->order < order) { 247 if (cur->next) 248 cur = pm_find(cur->next); 249 else { 250 cur->next = packet->packet_id; 251 packet->previous = cur->packet_id; 252 228 253 return EOK; 229 254 } 230 255 } else { 231 packet->previous = item->previous; 232 packet->next = item->packet_id; 233 item->previous = packet->packet_id; 234 item = pm_find(packet->previous); 235 if (item) 236 item->next = packet->packet_id; 256 packet->previous = cur->previous; 257 packet->next = cur->packet_id; 258 259 cur->previous = packet->packet_id; 260 cur = pm_find(packet->previous); 261 262 if (cur) 263 cur->next = packet->packet_id; 237 264 else 238 265 *first = packet; 266 239 267 return EOK; 240 268 } 241 } while (packet_is_valid( item));269 } while (packet_is_valid(cur)); 242 270 } 271 243 272 *first = packet; 244 273 return EOK; … … 312 341 313 342 next = pm_find(packet->next); 314 if (next) {343 if (next) 315 344 next->previous = packet->previous; 316 previous = pm_find(next->previous); 317 if (previous) 318 previous->next = next->packet_id; 319 } 345 346 previous = pm_find(packet->previous); 347 if (previous) 348 previous->next = packet->next ; 349 320 350 packet->previous = 0; 321 351 packet->next = 0; -
uspace/lib/c/generic/net/socket_client.c
r2bdf8313 rb0f00a9 64 64 #define SOCKET_MAX_ACCEPTED_SIZE 0 65 65 66 /** Default timeout for connections in microseconds. */67 #define SOCKET_CONNECT_TIMEOUT (1 * 1000 * 1000)68 69 66 /** 70 67 * Maximum number of random attempts to find a new socket identifier before … … 86 83 /** Socket identifier. */ 87 84 int socket_id; 88 /** Parent module phone. */89 int phone;85 /** Parent module session. */ 86 async_sess_t *sess; 90 87 /** Parent module service. */ 91 88 services_t service; … … 146 143 /** Socket client library global data. */ 147 144 static struct socket_client_globals { 148 /** TCP module phone. */ 149 int tcp_phone; 150 /** UDP module phone. */ 151 int udp_phone; 152 153 // /** The last socket identifier. 154 // */ 155 // int last_id; 145 /** TCP module session. */ 146 async_sess_t *tcp_sess; 147 /** UDP module session. */ 148 async_sess_t *udp_sess; 156 149 157 150 /** Active sockets. */ … … 166 159 fibril_rwlock_t lock; 167 160 } socket_globals = { 168 .tcp_phone = -1, 169 .udp_phone = -1, 170 // .last_id = 0, 161 .tcp_sess = NULL, 162 .udp_sess = NULL, 171 163 .sockets = NULL, 172 164 .lock = FIBRIL_RWLOCK_INITIALIZER(socket_globals.lock) … … 202 194 * @param[in] iid The initial message identifier. 203 195 * @param[in] icall The initial message call structure. 204 */ 205 static void socket_connection(ipc_callid_t iid, ipc_call_t * icall) 196 * @param[in] arg Local argument. 197 */ 198 static void socket_connection(ipc_callid_t iid, ipc_call_t * icall, void *arg) 206 199 { 207 200 ipc_callid_t callid; … … 281 274 } 282 275 283 /** Returns the TCP module phone. 284 * 285 * Connects to the TCP module if necessary. 286 * 287 * @return The TCP module phone. 288 * @return Other error codes as defined for the 289 * bind_service_timeout() function. 290 */ 291 static int socket_get_tcp_phone(void) 292 { 293 if (socket_globals.tcp_phone < 0) { 294 socket_globals.tcp_phone = bind_service_timeout(SERVICE_TCP, 295 0, 0, SERVICE_TCP, socket_connection, 296 SOCKET_CONNECT_TIMEOUT); 297 } 298 299 return socket_globals.tcp_phone; 300 } 301 302 /** Returns the UDP module phone. 303 * 304 * Connects to the UDP module if necessary. 305 * 306 * @return The UDP module phone. 307 * @return Other error codes as defined for the 308 * bind_service_timeout() function. 309 */ 310 static int socket_get_udp_phone(void) 311 { 312 if (socket_globals.udp_phone < 0) { 313 socket_globals.udp_phone = bind_service_timeout(SERVICE_UDP, 314 0, 0, SERVICE_UDP, socket_connection, 315 SOCKET_CONNECT_TIMEOUT); 316 } 317 318 return socket_globals.udp_phone; 276 /** Return the TCP module session. 277 * 278 * Connect to the TCP module if necessary. 279 * 280 * @return The TCP module session. 281 * 282 */ 283 static async_sess_t *socket_get_tcp_sess(void) 284 { 285 if (socket_globals.tcp_sess == NULL) { 286 socket_globals.tcp_sess = bind_service(SERVICE_TCP, 287 0, 0, SERVICE_TCP, socket_connection); 288 } 289 290 return socket_globals.tcp_sess; 291 } 292 293 /** Return the UDP module session. 294 * 295 * Connect to the UDP module if necessary. 296 * 297 * @return The UDP module session. 298 * 299 */ 300 static async_sess_t *socket_get_udp_sess(void) 301 { 302 if (socket_globals.udp_sess == NULL) { 303 socket_globals.udp_sess = bind_service(SERVICE_UDP, 304 0, 0, SERVICE_UDP, socket_connection); 305 } 306 307 return socket_globals.udp_sess; 319 308 } 320 309 … … 332 321 sockets = socket_get_sockets(); 333 322 count = 0; 334 // socket_id = socket_globals.last_id;335 323 336 324 do { … … 345 333 if (socket_id < INT_MAX) { 346 334 ++socket_id; 347 /* } else if(socket_globals.last_id) { 348 * socket_globals.last_id = 0; 349 * socket_id = 1; 350 */ } else { 335 } else { 351 336 return ELIMIT; 352 337 } 353 338 } 354 339 } while (sockets_find(sockets, socket_id)); 355 356 // last_id = socket_id 340 357 341 return socket_id; 358 342 } … … 361 345 * 362 346 * @param[in,out] socket The socket to be initialized. 363 * @param[in] socket_id The new socket identifier. 364 * @param[in] phone The parent module phone. 365 * @param[in] service The parent module service. 366 */ 367 static void 368 socket_initialize(socket_t *socket, int socket_id, int phone, 369 services_t service) 347 * @param[in] socket_id The new socket identifier. 348 * @param[in] sess The parent module session. 349 * @param[in] service The parent module service. 350 */ 351 static void socket_initialize(socket_t *socket, int socket_id, 352 async_sess_t *sess, services_t service) 370 353 { 371 354 socket->socket_id = socket_id; 372 socket-> phone = phone;355 socket->sess = sess; 373 356 socket->service = service; 374 357 dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE); … … 395 378 * @return Other error codes as defined for the NET_SOCKET message. 396 379 * @return Other error codes as defined for the 397 * bind_service _timeout() function.380 * bind_service() function. 398 381 */ 399 382 int socket(int domain, int type, int protocol) 400 383 { 401 384 socket_t *socket; 402 int phone;385 async_sess_t *sess; 403 386 int socket_id; 404 387 services_t service; … … 417 400 switch (protocol) { 418 401 case IPPROTO_TCP: 419 phone = socket_get_tcp_phone();402 sess = socket_get_tcp_sess(); 420 403 service = SERVICE_TCP; 421 404 break; … … 432 415 switch (protocol) { 433 416 case IPPROTO_UDP: 434 phone = socket_get_udp_phone();417 sess = socket_get_udp_sess(); 435 418 service = SERVICE_UDP; 436 419 break; … … 453 436 } 454 437 455 if ( phone < 0)456 return phone;438 if (sess == NULL) 439 return ENOENT; 457 440 458 441 /* Create a new socket structure */ … … 471 454 return socket_id; 472 455 } 473 474 rc = (int) async_req_3_3(phone, NET_SOCKET, socket_id, 0, service, NULL, 456 457 async_exch_t *exch = async_exchange_begin(sess); 458 rc = (int) async_req_3_3(exch, NET_SOCKET, socket_id, 0, service, NULL, 475 459 &fragment_size, &header_size); 460 async_exchange_end(exch); 461 476 462 if (rc != EOK) { 477 463 fibril_rwlock_write_unlock(&socket_globals.lock); … … 484 470 485 471 /* Finish the new socket initialization */ 486 socket_initialize(socket, socket_id, phone, service);472 socket_initialize(socket, socket_id, sess, service); 487 473 /* Store the new socket */ 488 474 rc = sockets_add(socket_get_sockets(), socket_id, socket); … … 493 479 dyn_fifo_destroy(&socket->accepted); 494 480 free(socket); 495 async_msg_3(phone, NET_SOCKET_CLOSE, (sysarg_t) socket_id, 0, 481 482 exch = async_exchange_begin(sess); 483 async_msg_3(exch, NET_SOCKET_CLOSE, (sysarg_t) socket_id, 0, 496 484 service); 485 async_exchange_end(exch); 486 497 487 return rc; 498 488 } … … 538 528 539 529 /* Request the message */ 540 message_id = async_send_3(socket->phone, message, 530 async_exch_t *exch = async_exchange_begin(socket->sess); 531 message_id = async_send_3(exch, message, 541 532 (sysarg_t) socket->socket_id, arg2, socket->service, NULL); 542 533 /* Send the address */ 543 async_data_write_start(socket->phone, data, datalength); 534 async_data_write_start(exch, data, datalength); 535 async_exchange_end(exch); 544 536 545 537 fibril_rwlock_read_unlock(&socket_globals.lock); … … 598 590 599 591 /* Request listen backlog change */ 600 result = (int) async_req_3_0(socket->phone, NET_SOCKET_LISTEN, 592 async_exch_t *exch = async_exchange_begin(socket->sess); 593 result = (int) async_req_3_0(exch, NET_SOCKET_LISTEN, 601 594 (sysarg_t) socket->socket_id, (sysarg_t) backlog, socket->service); 595 async_exchange_end(exch); 602 596 603 597 fibril_rwlock_read_unlock(&socket_globals.lock); … … 669 663 return socket_id; 670 664 } 671 socket_initialize(new_socket, socket_id, socket-> phone,665 socket_initialize(new_socket, socket_id, socket->sess, 672 666 socket->service); 673 667 result = sockets_add(socket_get_sockets(), new_socket->socket_id, … … 681 675 682 676 /* Request accept */ 683 message_id = async_send_5(socket->phone, NET_SOCKET_ACCEPT, 677 async_exch_t *exch = async_exchange_begin(socket->sess); 678 message_id = async_send_5(exch, NET_SOCKET_ACCEPT, 684 679 (sysarg_t) socket->socket_id, 0, socket->service, 0, 685 680 new_socket->socket_id, &answer); 686 681 687 682 /* Read address */ 688 async_data_read_start(socket->phone, cliaddr, *addrlen); 683 async_data_read_start(exch, cliaddr, *addrlen); 684 async_exchange_end(exch); 685 689 686 fibril_rwlock_write_unlock(&socket_globals.lock); 690 687 async_wait_for(message_id, &ipc_result); … … 780 777 781 778 /* Request close */ 782 rc = (int) async_req_3_0(socket->phone, NET_SOCKET_CLOSE, 779 async_exch_t *exch = async_exchange_begin(socket->sess); 780 rc = (int) async_req_3_0(exch, NET_SOCKET_CLOSE, 783 781 (sysarg_t) socket->socket_id, 0, socket->service); 782 async_exchange_end(exch); 783 784 784 if (rc != EOK) { 785 785 fibril_rwlock_write_unlock(&socket_globals.lock); … … 853 853 854 854 /* Request send */ 855 message_id = async_send_5(socket->phone, message, 855 async_exch_t *exch = async_exchange_begin(socket->sess); 856 857 message_id = async_send_5(exch, message, 856 858 (sysarg_t) socket->socket_id, 857 859 (fragments == 1 ? datalength : socket->data_fragment_size), … … 860 862 /* Send the address if given */ 861 863 if (!toaddr || 862 (async_data_write_start( socket->phone, toaddr, addrlen) == EOK)) {864 (async_data_write_start(exch, toaddr, addrlen) == EOK)) { 863 865 if (fragments == 1) { 864 866 /* Send all if only one fragment */ 865 async_data_write_start( socket->phone, data, datalength);867 async_data_write_start(exch, data, datalength); 866 868 } else { 867 869 /* Send the first fragment */ 868 async_data_write_start( socket->phone, data,870 async_data_write_start(exch, data, 869 871 socket->data_fragment_size - socket->header_size); 870 872 data = ((const uint8_t *) data) + … … 873 875 /* Send the middle fragments */ 874 876 while (--fragments > 1) { 875 async_data_write_start( socket->phone, data,877 async_data_write_start(exch, data, 876 878 socket->data_fragment_size); 877 879 data = ((const uint8_t *) data) + … … 880 882 881 883 /* Send the last fragment */ 882 async_data_write_start( socket->phone, data,884 async_data_write_start(exch, data, 883 885 (datalength + socket->header_size) % 884 886 socket->data_fragment_size); 885 887 } 886 888 } 889 890 async_exchange_end(exch); 887 891 888 892 async_wait_for(message_id, &result); … … 1026 1030 return 0; 1027 1031 } 1032 1033 async_exch_t *exch = async_exchange_begin(socket->sess); 1028 1034 1029 1035 /* Prepare lengths if more fragments */ … … 1038 1044 1039 1045 /* Request packet data */ 1040 message_id = async_send_4( socket->phone, message,1046 message_id = async_send_4(exch, message, 1041 1047 (sysarg_t) socket->socket_id, 0, socket->service, 1042 1048 (sysarg_t) flags, &answer); … … 1044 1050 /* Read the address if desired */ 1045 1051 if(!fromaddr || 1046 (async_data_read_start( socket->phone, fromaddr,1052 (async_data_read_start(exch, fromaddr, 1047 1053 *addrlen) == EOK)) { 1048 1054 /* Read the fragment lengths */ 1049 if (async_data_read_start( socket->phone, lengths,1055 if (async_data_read_start(exch, lengths, 1050 1056 sizeof(int) * (fragments + 1)) == EOK) { 1051 1057 if (lengths[fragments] <= datalength) { … … 1054 1060 for (index = 0; index < fragments; 1055 1061 ++index) { 1056 async_data_read_start( 1057 socket->phone, data, 1062 async_data_read_start(exch, data, 1058 1063 lengths[index]); 1059 1064 data = ((uint8_t *) data) + … … 1067 1072 } else { /* fragments == 1 */ 1068 1073 /* Request packet data */ 1069 message_id = async_send_4( socket->phone, message,1074 message_id = async_send_4(exch, message, 1070 1075 (sysarg_t) socket->socket_id, 0, socket->service, 1071 1076 (sysarg_t) flags, &answer); … … 1073 1078 /* Read the address if desired */ 1074 1079 if (!fromaddr || 1075 (async_data_read_start(socket->phone, fromaddr, 1076 *addrlen) == EOK)) { 1080 (async_data_read_start(exch, fromaddr, *addrlen) == EOK)) { 1077 1081 /* Read all if only one fragment */ 1078 async_data_read_start( socket->phone, data, datalength);1082 async_data_read_start(exch, data, datalength); 1079 1083 } 1080 1084 } 1085 1086 async_exchange_end(exch); 1081 1087 1082 1088 async_wait_for(message_id, &ipc_result); … … 1190 1196 1191 1197 /* Request option value */ 1192 message_id = async_send_3(socket->phone, NET_SOCKET_GETSOCKOPT, 1198 async_exch_t *exch = async_exchange_begin(socket->sess); 1199 1200 message_id = async_send_3(exch, NET_SOCKET_GETSOCKOPT, 1193 1201 (sysarg_t) socket->socket_id, (sysarg_t) optname, socket->service, 1194 1202 NULL); 1195 1203 1196 1204 /* Read the length */ 1197 if (async_data_read_start( socket->phone, optlen,1205 if (async_data_read_start(exch, optlen, 1198 1206 sizeof(*optlen)) == EOK) { 1199 1207 /* Read the value */ 1200 async_data_read_start(socket->phone, value, *optlen); 1201 } 1208 async_data_read_start(exch, value, *optlen); 1209 } 1210 1211 async_exchange_end(exch); 1202 1212 1203 1213 fibril_rwlock_read_unlock(&socket_globals.lock); -
uspace/lib/c/generic/private/async.h
r2bdf8313 rb0f00a9 36 36 #define LIBC_PRIVATE_ASYNC_H_ 37 37 38 #include <async.h> 38 39 #include <adt/list.h> 39 40 #include <fibril.h> 41 #include <fibril_synch.h> 40 42 #include <sys/time.h> 41 43 #include <bool.h> … … 81 83 extern void __async_init(void); 82 84 extern void async_insert_timeout(awaiter_t *); 85 extern void reply_received(void *, int, ipc_call_t *); 83 86 84 87 #endif -
uspace/lib/c/generic/private/io.h
r2bdf8313 rb0f00a9 36 36 #define LIBC_PRIVATE_IO_H_ 37 37 38 #include <vfs/vfs.h> 39 40 extern void __stdio_init(int filc, fdi_node_t *filv[]); 38 extern void __stdio_init(int); 41 39 extern void __stdio_done(void); 42 40 -
uspace/lib/c/generic/private/ns.h
r2bdf8313 rb0f00a9 33 33 */ 34 34 35 #ifndef LIBC_PRIVATE_ ASYNC_SESS_H_36 #define LIBC_PRIVATE_ ASYNC_SESS_H_35 #ifndef LIBC_PRIVATE_NS_H_ 36 #define LIBC_PRIVATE_NS_H_ 37 37 38 extern void __async_sess_init(void); 38 #include <async.h> 39 40 extern async_sess_t *session_ns; 39 41 40 42 #endif -
uspace/lib/c/generic/private/stdio.h
r2bdf8313 rb0f00a9 1 1 /* 2 * Copyright (c) 2006 Ondrej Palkovsky 3 * Copyright (c) 2008 Martin Decky 2 * Copyright (c) 2011 Martin Decky 4 3 * All rights reserved. 5 4 * … … 28 27 */ 29 28 30 /** @defgroup msimfb MSIM text console 31 * @brief HelenOS MSIM text console. 32 * @ingroup fbs 29 /** @addtogroup libc 33 30 * @{ 34 31 */ … … 36 33 */ 37 34 35 #ifndef LIBC_PRIVATE_STDIO_H_ 36 #define LIBC_PRIVATE_STDIO_H_ 37 38 #include <adt/list.h> 39 #include <stdio.h> 38 40 #include <async.h> 39 #include <libc.h>40 #include <sysinfo.h>41 #include <as.h>42 #include <ddi.h>43 #include <errno.h>44 41 45 #include "serial_console.h" 46 #include "msim.h" 42 struct _IO_FILE { 43 /** Linked list pointer. */ 44 link_t link; 45 46 /** Underlying file descriptor. */ 47 int fd; 48 49 /** Error indicator. */ 50 int error; 51 52 /** End-of-file indicator. */ 53 int eof; 54 55 /** Klog indicator */ 56 int klog; 57 58 /** Session to the file provider */ 59 async_sess_t *sess; 60 61 /** 62 * Non-zero if the stream needs sync on fflush(). XXX change 63 * console semantics so that sync is not needed. 64 */ 65 int need_sync; 66 67 /** Buffering type */ 68 enum _buffer_type btype; 69 70 /** Buffer */ 71 uint8_t *buf; 72 73 /** Buffer size */ 74 size_t buf_size; 75 76 /** Buffer state */ 77 enum _buffer_state buf_state; 78 79 /** Buffer I/O pointer */ 80 uint8_t *buf_head; 81 82 /** Points to end of occupied space when in read mode. */ 83 uint8_t *buf_tail; 84 }; 47 85 48 #define WIDTH 80 49 #define HEIGHT 24 50 51 static char *virt_addr; 52 53 static void msim_putc(const char c) 54 { 55 *virt_addr = c; 56 } 57 58 int msim_init(void) 59 { 60 sysarg_t phys_addr; 61 if (sysinfo_get_value("fb.address.physical", &phys_addr) != EOK) 62 return -1; 63 64 virt_addr = (char *) as_get_mappable_page(1); 65 66 if (physmem_map((void *) phys_addr, virt_addr, 1, 67 AS_AREA_READ | AS_AREA_WRITE) != 0) 68 return -1; 69 70 serial_console_init(msim_putc, WIDTH, HEIGHT); 71 72 async_set_client_connection(serial_client_connection); 73 return 0; 74 } 86 #endif 75 87 76 88 /** @} -
uspace/lib/c/generic/private/thread.h
r2bdf8313 rb0f00a9 36 36 #define LIBC_PRIVATE_THREAD_H_ 37 37 38 #include < kernel/proc/uarg.h>38 #include <abi/proc/uarg.h> 39 39 40 40 extern void __thread_entry(void); -
uspace/lib/c/generic/rtld/module.c
r2bdf8313 rb0f00a9 35 35 */ 36 36 37 #include <adt/list.h> 38 #include <elf/elf_load.h> 39 #include <fcntl.h> 40 #include <loader/pcb.h> 37 41 #include <stdio.h> 38 42 #include <stdlib.h> 39 43 #include <unistd.h> 40 #include <fcntl.h>41 #include <adt/list.h>42 #include <loader/pcb.h>43 44 44 45 #include <rtld/rtld.h> … … 47 48 #include <rtld/rtld_arch.h> 48 49 #include <rtld/module.h> 49 #include <elf_load.h>50 50 51 51 /** (Eagerly) process all relocation tables in a module. … … 93 93 module_t *module_find(const char *name) 94 94 { 95 link_t *head = &runtime_env->modules_head;96 97 link_t *cur;98 95 module_t *m; 99 96 const char *p, *soname; … … 110 107 111 108 /* Traverse list of all modules. Not extremely fast, but simple */ 112 DPRINTF("head = %p\n", head); 113 for (cur = head->next; cur != head; cur = cur->next) { 109 list_foreach(runtime_env->modules, cur) { 114 110 DPRINTF("cur = %p\n", cur); 115 111 m = list_get_instance(cur, module_t, modules_link); … … 177 173 178 174 /* Insert into the list of loaded modules */ 179 list_append(&m->modules_link, &runtime_env->modules _head);175 list_append(&m->modules_link, &runtime_env->modules); 180 176 181 177 return m; … … 249 245 void modules_process_relocs(module_t *start) 250 246 { 251 link_t *head = &runtime_env->modules_head; 252 253 link_t *cur; 254 module_t *m; 255 256 for (cur = head->next; cur != head; cur = cur->next) { 247 module_t *m; 248 249 list_foreach(runtime_env->modules, cur) { 257 250 m = list_get_instance(cur, module_t, modules_link); 258 251 … … 268 261 void modules_untag(void) 269 262 { 270 link_t *head = &runtime_env->modules_head; 271 272 link_t *cur; 273 module_t *m; 274 275 for (cur = head->next; cur != head; cur = cur->next) { 263 module_t *m; 264 265 list_foreach(runtime_env->modules, cur) { 276 266 m = list_get_instance(cur, module_t, modules_link); 277 267 m->bfs_tag = false; -
uspace/lib/c/generic/rtld/rtld.c
r2bdf8313 rb0f00a9 44 44 { 45 45 runtime_env = &rt_env_static; 46 list_initialize(&runtime_env->modules _head);46 list_initialize(&runtime_env->modules); 47 47 runtime_env->next_bias = 0x2000000; 48 48 runtime_env->program = NULL; -
uspace/lib/c/generic/rtld/symbol.c
r2bdf8313 rb0f00a9 38 38 #include <stdlib.h> 39 39 40 #include <elf/elf.h> 40 41 #include <rtld/rtld.h> 41 42 #include <rtld/rtld_debug.h> 42 43 #include <rtld/symbol.h> 43 #include <elf.h>44 44 45 45 /* … … 118 118 module_t *m, *dm; 119 119 elf_symbol_t *sym, *s; 120 li nk_t queue_head;120 list_t queue; 121 121 size_t i; 122 122 … … 132 132 133 133 /* Insert root (the program) into the queue and tag it */ 134 list_initialize(&queue _head);134 list_initialize(&queue); 135 135 start->bfs_tag = true; 136 list_append(&start->queue_link, &queue _head);136 list_append(&start->queue_link, &queue); 137 137 138 138 /* If the symbol is found, it will be stored in 'sym' */ … … 140 140 141 141 /* While queue is not empty */ 142 while (!list_empty(&queue _head)) {142 while (!list_empty(&queue)) { 143 143 /* Pop first element from the queue */ 144 m = list_get_instance( queue_head.next, module_t, queue_link);144 m = list_get_instance(list_first(&queue), module_t, queue_link); 145 145 list_remove(&m->queue_link); 146 146 … … 162 162 if (dm->bfs_tag == false) { 163 163 dm->bfs_tag = true; 164 list_append(&dm->queue_link, &queue _head);164 list_append(&dm->queue_link, &queue); 165 165 } 166 166 } … … 168 168 169 169 /* Empty the queue so that we leave it in a clean state */ 170 while (!list_empty(&queue _head))171 list_remove( queue_head.next);170 while (!list_empty(&queue)) 171 list_remove(list_first(&queue)); 172 172 173 173 if (!sym) { -
uspace/lib/c/generic/str.c
r2bdf8313 rb0f00a9 2 2 * Copyright (c) 2005 Martin Decky 3 3 * Copyright (c) 2008 Jiri Svoboda 4 * Copyright (c) 2011 Martin Sucha 5 * Copyright (c) 2011 Oleg Romanenko 4 6 * All rights reserved. 5 7 * … … 540 542 541 543 dstr_size = str_size(dest); 544 if (dstr_size >= size) 545 return; 546 542 547 str_cpy(dest + dstr_size, size - dstr_size, src); 548 } 549 550 /** Convert space-padded ASCII to string. 551 * 552 * Common legacy text encoding in hardware is 7-bit ASCII fitted into 553 * a fixed-width byte buffer (bit 7 always zero), right-padded with spaces 554 * (ASCII 0x20). Convert space-padded ascii to string representation. 555 * 556 * If the text does not fit into the destination buffer, the function converts 557 * as many characters as possible and returns EOVERFLOW. 558 * 559 * If the text contains non-ASCII bytes (with bit 7 set), the whole string is 560 * converted anyway and invalid characters are replaced with question marks 561 * (U_SPECIAL) and the function returns EIO. 562 * 563 * Regardless of return value upon return @a dest will always be well-formed. 564 * 565 * @param dest Destination buffer 566 * @param size Size of destination buffer 567 * @param src Space-padded ASCII. 568 * @param n Size of the source buffer in bytes. 569 * 570 * @return EOK on success, EOVERFLOW if the text does not fit 571 * destination buffer, EIO if the text contains 572 * non-ASCII bytes. 573 */ 574 int spascii_to_str(char *dest, size_t size, const uint8_t *src, size_t n) 575 { 576 size_t sidx; 577 size_t didx; 578 size_t dlast; 579 uint8_t byte; 580 int rc; 581 int result; 582 583 /* There must be space for a null terminator in the buffer. */ 584 assert(size > 0); 585 result = EOK; 586 587 didx = 0; 588 dlast = 0; 589 for (sidx = 0; sidx < n; ++sidx) { 590 byte = src[sidx]; 591 if (!ascii_check(byte)) { 592 byte = U_SPECIAL; 593 result = EIO; 594 } 595 596 rc = chr_encode(byte, dest, &didx, size - 1); 597 if (rc != EOK) { 598 assert(rc == EOVERFLOW); 599 dest[didx] = '\0'; 600 return rc; 601 } 602 603 /* Remember dest index after last non-empty character */ 604 if (byte != 0x20) 605 dlast = didx; 606 } 607 608 /* Terminate string after last non-empty character */ 609 dest[dlast] = '\0'; 610 return result; 543 611 } 544 612 … … 572 640 dest[dest_off] = '\0'; 573 641 } 642 643 /** Convert UTF16 string to string. 644 * 645 * Convert utf16 string @a src to string. The output is written to the buffer 646 * specified by @a dest and @a size. @a size must be non-zero and the string 647 * written will always be well-formed. Surrogate pairs also supported. 648 * 649 * @param dest Destination buffer. 650 * @param size Size of the destination buffer. 651 * @param src Source utf16 string. 652 * 653 * @return EOK, if success, negative otherwise. 654 */ 655 int utf16_to_str(char *dest, size_t size, const uint16_t *src) 656 { 657 size_t idx = 0, dest_off = 0; 658 wchar_t ch; 659 int rc = EOK; 660 661 /* There must be space for a null terminator in the buffer. */ 662 assert(size > 0); 663 664 while (src[idx]) { 665 if ((src[idx] & 0xfc00) == 0xd800) { 666 if (src[idx + 1] && (src[idx + 1] & 0xfc00) == 0xdc00) { 667 ch = 0x10000; 668 ch += (src[idx] & 0x03FF) << 10; 669 ch += (src[idx + 1] & 0x03FF); 670 idx += 2; 671 } 672 else 673 break; 674 } else { 675 ch = src[idx]; 676 idx++; 677 } 678 rc = chr_encode(ch, dest, &dest_off, size - 1); 679 if (rc != EOK) 680 break; 681 } 682 dest[dest_off] = '\0'; 683 return rc; 684 } 685 686 int str_to_utf16(uint16_t *dest, size_t size, const char *src) 687 { 688 int rc = EOK; 689 size_t offset = 0; 690 size_t idx = 0; 691 wchar_t c; 692 693 assert(size > 0); 694 695 while ((c = str_decode(src, &offset, STR_NO_LIMIT)) != 0) { 696 if (c > 0x10000) { 697 if (idx + 2 >= size - 1) { 698 rc = EOVERFLOW; 699 break; 700 } 701 c = (c - 0x10000); 702 dest[idx] = 0xD800 | (c >> 10); 703 dest[idx + 1] = 0xDC00 | (c & 0x3FF); 704 idx++; 705 } else { 706 dest[idx] = c; 707 } 708 709 idx++; 710 if (idx >= size - 1) { 711 rc = EOVERFLOW; 712 break; 713 } 714 } 715 716 dest[idx] = '\0'; 717 return rc; 718 } 719 574 720 575 721 /** Convert wide string to new string. … … 654 800 } 655 801 802 /** Convert string to wide string. 803 * 804 * Convert string @a src to wide string. A new wide NULL-terminated 805 * string will be allocated on the heap. 806 * 807 * @param src Source string. 808 */ 809 wchar_t *str_to_awstr(const char *str) 810 { 811 size_t len = str_length(str); 812 813 wchar_t *wstr = calloc(len+1, sizeof(wchar_t)); 814 if (wstr == NULL) 815 return NULL; 816 817 str_to_wstr(wstr, len + 1, str); 818 return wstr; 819 } 820 656 821 /** Find first occurence of character in string. 657 822 * … … 674 839 675 840 return NULL; 841 } 842 843 /** Removes specified trailing characters from a string. 844 * 845 * @param str String to remove from. 846 * @param ch Character to remove. 847 */ 848 void str_rtrim(char *str, wchar_t ch) 849 { 850 size_t off = 0; 851 size_t pos = 0; 852 wchar_t c; 853 bool update_last_chunk = true; 854 char *last_chunk = NULL; 855 856 while ((c = str_decode(str, &off, STR_NO_LIMIT))) { 857 if (c != ch) { 858 update_last_chunk = true; 859 last_chunk = NULL; 860 } else if (update_last_chunk) { 861 update_last_chunk = false; 862 last_chunk = (str + pos); 863 } 864 pos = off; 865 } 866 867 if (last_chunk) 868 *last_chunk = '\0'; 869 } 870 871 /** Removes specified leading characters from a string. 872 * 873 * @param str String to remove from. 874 * @param ch Character to remove. 875 */ 876 void str_ltrim(char *str, wchar_t ch) 877 { 878 wchar_t acc; 879 size_t off = 0; 880 size_t pos = 0; 881 size_t str_sz = str_size(str); 882 883 while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) { 884 if (acc != ch) 885 break; 886 else 887 pos = off; 888 } 889 890 if (pos > 0) { 891 memmove(str, &str[pos], str_sz - pos); 892 pos = str_sz - pos; 893 str[str_sz - pos] = '\0'; 894 } 676 895 } 677 896 … … 950 1169 return dest; 951 1170 } 952 953 1171 954 1172 /** Convert initial part of string to unsigned long according to given base. … … 1127 1345 } 1128 1346 1347 /** Convert string to uint8_t. 1348 * 1349 * @param nptr Pointer to string. 1350 * @param endptr If not NULL, pointer to the first invalid character 1351 * is stored here. 1352 * @param base Zero or number between 2 and 36 inclusive. 1353 * @param strict Do not allow any trailing characters. 1354 * @param result Result of the conversion. 1355 * 1356 * @return EOK if conversion was successful. 1357 * 1358 */ 1359 int str_uint8_t(const char *nptr, char **endptr, unsigned int base, 1360 bool strict, uint8_t *result) 1361 { 1362 assert(result != NULL); 1363 1364 bool neg; 1365 char *lendptr; 1366 uint64_t res; 1367 int ret = str_uint(nptr, &lendptr, base, &neg, &res); 1368 1369 if (endptr != NULL) 1370 *endptr = (char *) lendptr; 1371 1372 if (ret != EOK) 1373 return ret; 1374 1375 /* Do not allow negative values */ 1376 if (neg) 1377 return EINVAL; 1378 1379 /* Check whether we are at the end of 1380 the string in strict mode */ 1381 if ((strict) && (*lendptr != 0)) 1382 return EINVAL; 1383 1384 /* Check for overflow */ 1385 uint8_t _res = (uint8_t) res; 1386 if (_res != res) 1387 return EOVERFLOW; 1388 1389 *result = _res; 1390 1391 return EOK; 1392 } 1393 1394 /** Convert string to uint16_t. 1395 * 1396 * @param nptr Pointer to string. 1397 * @param endptr If not NULL, pointer to the first invalid character 1398 * is stored here. 1399 * @param base Zero or number between 2 and 36 inclusive. 1400 * @param strict Do not allow any trailing characters. 1401 * @param result Result of the conversion. 1402 * 1403 * @return EOK if conversion was successful. 1404 * 1405 */ 1406 int str_uint16_t(const char *nptr, char **endptr, unsigned int base, 1407 bool strict, uint16_t *result) 1408 { 1409 assert(result != NULL); 1410 1411 bool neg; 1412 char *lendptr; 1413 uint64_t res; 1414 int ret = str_uint(nptr, &lendptr, base, &neg, &res); 1415 1416 if (endptr != NULL) 1417 *endptr = (char *) lendptr; 1418 1419 if (ret != EOK) 1420 return ret; 1421 1422 /* Do not allow negative values */ 1423 if (neg) 1424 return EINVAL; 1425 1426 /* Check whether we are at the end of 1427 the string in strict mode */ 1428 if ((strict) && (*lendptr != 0)) 1429 return EINVAL; 1430 1431 /* Check for overflow */ 1432 uint16_t _res = (uint16_t) res; 1433 if (_res != res) 1434 return EOVERFLOW; 1435 1436 *result = _res; 1437 1438 return EOK; 1439 } 1440 1441 /** Convert string to uint32_t. 1442 * 1443 * @param nptr Pointer to string. 1444 * @param endptr If not NULL, pointer to the first invalid character 1445 * is stored here. 1446 * @param base Zero or number between 2 and 36 inclusive. 1447 * @param strict Do not allow any trailing characters. 1448 * @param result Result of the conversion. 1449 * 1450 * @return EOK if conversion was successful. 1451 * 1452 */ 1453 int str_uint32_t(const char *nptr, char **endptr, unsigned int base, 1454 bool strict, uint32_t *result) 1455 { 1456 assert(result != NULL); 1457 1458 bool neg; 1459 char *lendptr; 1460 uint64_t res; 1461 int ret = str_uint(nptr, &lendptr, base, &neg, &res); 1462 1463 if (endptr != NULL) 1464 *endptr = (char *) lendptr; 1465 1466 if (ret != EOK) 1467 return ret; 1468 1469 /* Do not allow negative values */ 1470 if (neg) 1471 return EINVAL; 1472 1473 /* Check whether we are at the end of 1474 the string in strict mode */ 1475 if ((strict) && (*lendptr != 0)) 1476 return EINVAL; 1477 1478 /* Check for overflow */ 1479 uint32_t _res = (uint32_t) res; 1480 if (_res != res) 1481 return EOVERFLOW; 1482 1483 *result = _res; 1484 1485 return EOK; 1486 } 1487 1129 1488 /** Convert string to uint64_t. 1130 1489 * -
uspace/lib/c/generic/str_error.c
r2bdf8313 rb0f00a9 33 33 */ 34 34 35 #include <errno.h> 35 36 #include <str_error.h> 36 37 #include <stdio.h> … … 63 64 static fibril_local char noerr[NOERR_LEN]; 64 65 65 const char *str_error(const int e rrno)66 const char *str_error(const int e) 66 67 { 67 if ((e rrno <= 0) && (errno>= MIN_ERRNO))68 return err_desc[-e rrno];68 if ((e <= 0) && (e >= MIN_ERRNO)) 69 return err_desc[-e]; 69 70 70 snprintf(noerr, NOERR_LEN, "Unkown error code %d", errno); 71 /* Ad hoc descriptions of error codes interesting for USB. */ 72 // FIXME: integrate these as first-class error values 73 switch (e) { 74 case EBADCHECKSUM: 75 return "Bad checksum"; 76 case ESTALL: 77 return "Operation stalled"; 78 case EAGAIN: 79 return "Resource temporarily unavailable"; 80 case EEMPTY: 81 return "Resource is empty"; 82 default: 83 break; 84 } 85 86 snprintf(noerr, NOERR_LEN, "Unkown error code %d", e); 71 87 return noerr; 72 88 } -
uspace/lib/c/generic/sysinfo.c
r2bdf8313 rb0f00a9 47 47 * 48 48 */ 49 sysinfo_item_ tag_t sysinfo_get_tag(const char *path)49 sysinfo_item_val_type_t sysinfo_get_val_type(const char *path) 50 50 { 51 return (sysinfo_item_ tag_t) __SYSCALL2(SYS_SYSINFO_GET_TAG,51 return (sysinfo_item_val_type_t) __SYSCALL2(SYS_SYSINFO_GET_VAL_TYPE, 52 52 (sysarg_t) path, (sysarg_t) str_size(path)); 53 53 } -
uspace/lib/c/generic/task.c
r2bdf8313 rb0f00a9 35 35 36 36 #include <task.h> 37 #include <libc.h>38 #include <stdlib.h>39 #include <errno.h>40 37 #include <loader/loader.h> 41 38 #include <stdarg.h> … … 43 40 #include <ipc/ns.h> 44 41 #include <macros.h> 42 #include <assert.h> 45 43 #include <async.h> 44 #include <errno.h> 45 #include <malloc.h> 46 #include <libc.h> 47 #include "private/ns.h" 48 #include <vfs/vfs.h> 46 49 47 50 task_id_t task_get_id(void) … … 68 71 int task_set_name(const char *name) 69 72 { 73 assert(name); 74 70 75 return __SYSCALL2(SYS_TASK_SET_NAME, (sysarg_t) name, str_size(name)); 71 76 } … … 88 93 * loader API. Arguments are passed as a null-terminated array of strings. 89 94 * 90 * @param id If not NULL, the ID of the task is stored here on success. 91 * @param path Pathname of the binary to execute. 92 * @param argv Command-line arguments. 93 * 94 * @return Zero on success or negative error code. 95 * @param id If not NULL, the ID of the task is stored here on success. 96 * @param path Pathname of the binary to execute. 97 * @param argv Command-line arguments. 98 * 99 * @return Zero on success or negative error code. 100 * 95 101 */ 96 102 int task_spawnv(task_id_t *id, const char *path, const char *const args[]) 97 103 { 98 loader_t *ldr; 99 task_id_t task_id; 100 int rc; 101 104 /* Send default files */ 105 int *files[4]; 106 int fd_stdin; 107 int fd_stdout; 108 int fd_stderr; 109 110 if ((stdin != NULL) && (fhandle(stdin, &fd_stdin) == EOK)) 111 files[0] = &fd_stdin; 112 else 113 files[0] = NULL; 114 115 if ((stdout != NULL) && (fhandle(stdout, &fd_stdout) == EOK)) 116 files[1] = &fd_stdout; 117 else 118 files[1] = NULL; 119 120 if ((stderr != NULL) && (fhandle(stderr, &fd_stderr) == EOK)) 121 files[2] = &fd_stderr; 122 else 123 files[2] = NULL; 124 125 files[3] = NULL; 126 127 return task_spawnvf(id, path, args, files); 128 } 129 130 /** Create a new task by running an executable from the filesystem. 131 * 132 * This is really just a convenience wrapper over the more complicated 133 * loader API. Arguments are passed as a null-terminated array of strings. 134 * Files are passed as null-terminated array of pointers to fdi_node_t. 135 * 136 * @param id If not NULL, the ID of the task is stored here on success. 137 * @param path Pathname of the binary to execute. 138 * @param argv Command-line arguments. 139 * @param files Standard files to use. 140 * 141 * @return Zero on success or negative error code. 142 * 143 */ 144 int task_spawnvf(task_id_t *id, const char *path, const char *const args[], 145 int *const files[]) 146 { 102 147 /* Connect to a program loader. */ 103 l dr = loader_connect();148 loader_t *ldr = loader_connect(); 104 149 if (ldr == NULL) 105 150 return EREFUSED; 106 151 107 152 /* Get task ID. */ 108 rc = loader_get_task_id(ldr, &task_id); 153 task_id_t task_id; 154 int rc = loader_get_task_id(ldr, &task_id); 109 155 if (rc != EOK) 110 156 goto error; … … 125 171 goto error; 126 172 127 /* Send default files */ 128 fdi_node_t *files[4]; 129 fdi_node_t stdin_node; 130 fdi_node_t stdout_node; 131 fdi_node_t stderr_node; 132 133 if ((stdin != NULL) && (fnode(stdin, &stdin_node) == EOK)) 134 files[0] = &stdin_node; 135 else 136 files[0] = NULL; 137 138 if ((stdout != NULL) && (fnode(stdout, &stdout_node) == EOK)) 139 files[1] = &stdout_node; 140 else 141 files[1] = NULL; 142 143 if ((stderr != NULL) && (fnode(stderr, &stderr_node) == EOK)) 144 files[2] = &stderr_node; 145 else 146 files[2] = NULL; 147 148 files[3] = NULL; 149 173 /* Send files */ 150 174 rc = loader_set_files(ldr, files); 151 175 if (rc != EOK) … … 163 187 164 188 /* Success */ 165 free(ldr);166 167 189 if (id != NULL) 168 190 *id = task_id; … … 173 195 /* Error exit */ 174 196 loader_abort(ldr); 175 free(ldr);176 197 return rc; 177 198 } … … 182 203 * loader API. Arguments are passed as a null-terminated list of arguments. 183 204 * 184 * @param id If not NULL, the ID of the task is stored here on success. 185 * @param path Pathname of the binary to execute. 186 * @param ... Command-line arguments. 187 * 188 * @return Zero on success or negative error code. 205 * @param id If not NULL, the ID of the task is stored here on success. 206 * @param path Pathname of the binary to execute. 207 * @param ... Command-line arguments. 208 * 209 * @return Zero on success or negative error code. 210 * 189 211 */ 190 212 int task_spawnl(task_id_t *task_id, const char *path, ...) 191 213 { 214 /* Count the number of arguments. */ 215 192 216 va_list ap; 193 int rc, cnt;194 217 const char *arg; 195 218 const char **arglist; 196 197 /* Count the number of arguments. */ 198 cnt = 0; 219 int cnt = 0; 220 199 221 va_start(ap, path); 200 222 do { … … 203 225 } while (arg != NULL); 204 226 va_end(ap); 205 227 206 228 /* Allocate argument list. */ 207 229 arglist = malloc(cnt * sizeof(const char *)); 208 230 if (arglist == NULL) 209 231 return ENOMEM; 210 232 211 233 /* Fill in arguments. */ 212 234 cnt = 0; … … 217 239 } while (arg != NULL); 218 240 va_end(ap); 219 241 220 242 /* Spawn task. */ 221 rc = task_spawnv(task_id, path, arglist);222 243 int rc = task_spawnv(task_id, path, arglist); 244 223 245 /* Free argument list. */ 224 246 free(arglist); … … 228 250 int task_wait(task_id_t id, task_exit_t *texit, int *retval) 229 251 { 252 assert(texit); 253 assert(retval); 254 255 async_exch_t *exch = async_exchange_begin(session_ns); 230 256 sysarg_t te, rv; 231 int rc; 232 233 rc = (int) async_req_2_2(PHONE_NS, NS_TASK_WAIT, LOWER32(id), 257 int rc = (int) async_req_2_2(exch, NS_TASK_WAIT, LOWER32(id), 234 258 UPPER32(id), &te, &rv); 259 async_exchange_end(exch); 260 235 261 *texit = te; 236 262 *retval = rv; 237 263 238 264 return rc; 239 265 } … … 241 267 int task_retval(int val) 242 268 { 243 return (int) async_req_1_0(PHONE_NS, NS_RETVAL, val); 269 async_exch_t *exch = async_exchange_begin(session_ns); 270 int rc = (int) async_req_1_0(exch, NS_RETVAL, val); 271 async_exchange_end(exch); 272 273 return rc; 244 274 } 245 275 -
uspace/lib/c/generic/thread.c
r2bdf8313 rb0f00a9 37 37 #include <stdlib.h> 38 38 #include <libarch/faddr.h> 39 #include < kernel/proc/uarg.h>39 #include <abi/proc/uarg.h> 40 40 #include <fibril.h> 41 41 #include <str.h> … … 44 44 45 45 #ifndef THREAD_INITIAL_STACK_PAGES_NO 46 #define THREAD_INITIAL_STACK_PAGES_NO 146 #define THREAD_INITIAL_STACK_PAGES_NO 2 47 47 #endif 48 48 -
uspace/lib/c/generic/time.c
r2bdf8313 rb0f00a9 36 36 #include <time.h> 37 37 #include <bool.h> 38 #include < arch/barrier.h>38 #include <libarch/barrier.h> 39 39 #include <macros.h> 40 40 #include <errno.h> … … 207 207 } 208 208 209 void udelay(useconds_t time) 210 { 211 (void) __SYSCALL1(SYS_THREAD_UDELAY, (sysarg_t) time); 212 } 213 214 209 215 /** Wait unconditionally for specified number of seconds 210 216 * -
uspace/lib/c/generic/udebug.c
r2bdf8313 rb0f00a9 35 35 #include <udebug.h> 36 36 #include <sys/types.h> 37 #include <abi/ipc/methods.h> 37 38 #include <async.h> 38 39 39 int udebug_begin( int phoneid)40 int udebug_begin(async_sess_t *sess) 40 41 { 41 return async_req_1_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_BEGIN); 42 async_exch_t *exch = async_exchange_begin(sess); 43 return async_req_1_0(exch, IPC_M_DEBUG, UDEBUG_M_BEGIN); 42 44 } 43 45 44 int udebug_end( int phoneid)46 int udebug_end(async_sess_t *sess) 45 47 { 46 return async_req_1_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_END); 48 async_exch_t *exch = async_exchange_begin(sess); 49 return async_req_1_0(exch, IPC_M_DEBUG, UDEBUG_M_END); 47 50 } 48 51 49 int udebug_set_evmask( int phoneid, udebug_evmask_t mask)52 int udebug_set_evmask(async_sess_t *sess, udebug_evmask_t mask) 50 53 { 51 return async_req_2_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_SET_EVMASK,52 mask);54 async_exch_t *exch = async_exchange_begin(sess); 55 return async_req_2_0(exch, IPC_M_DEBUG, UDEBUG_M_SET_EVMASK, mask); 53 56 } 54 57 55 int udebug_thread_read( int phoneid, void *buffer, size_t n,56 size_t *copied, size_t *needed)58 int udebug_thread_read(async_sess_t *sess, void *buffer, size_t n, 59 size_t *copied, size_t *needed) 57 60 { 58 61 sysarg_t a_copied, a_needed; 59 int rc;60 61 rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_THREAD_READ,62 (sysarg_t)buffer, n, NULL, &a_copied, &a_needed);63 64 *copied = (size_t) a_copied;65 *needed = (size_t) a_needed;66 62 63 async_exch_t *exch = async_exchange_begin(sess); 64 int rc = async_req_3_3(exch, IPC_M_DEBUG, UDEBUG_M_THREAD_READ, 65 (sysarg_t) buffer, n, NULL, &a_copied, &a_needed); 66 67 *copied = (size_t) a_copied; 68 *needed = (size_t) a_needed; 69 67 70 return rc; 68 71 } 69 72 70 int udebug_name_read( int phoneid, void *buffer, size_t n,71 size_t *copied, size_t *needed)73 int udebug_name_read(async_sess_t *sess, void *buffer, size_t n, 74 size_t *copied, size_t *needed) 72 75 { 73 76 sysarg_t a_copied, a_needed; 74 int rc;75 76 rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_NAME_READ,77 (sysarg_t)buffer, n, NULL, &a_copied, &a_needed);78 79 *copied = (size_t) a_copied;80 *needed = (size_t) a_needed;81 77 78 async_exch_t *exch = async_exchange_begin(sess); 79 int rc = async_req_3_3(exch, IPC_M_DEBUG, UDEBUG_M_NAME_READ, 80 (sysarg_t) buffer, n, NULL, &a_copied, &a_needed); 81 82 *copied = (size_t) a_copied; 83 *needed = (size_t) a_needed; 84 82 85 return rc; 83 86 } 84 87 85 int udebug_areas_read( int phoneid, void *buffer, size_t n,86 size_t *copied, size_t *needed)88 int udebug_areas_read(async_sess_t *sess, void *buffer, size_t n, 89 size_t *copied, size_t *needed) 87 90 { 88 91 sysarg_t a_copied, a_needed; 89 int rc;90 91 rc = async_req_3_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_AREAS_READ,92 (sysarg_t)buffer, n, NULL, &a_copied, &a_needed);93 94 *copied = (size_t) a_copied;95 *needed = (size_t) a_needed;96 92 93 async_exch_t *exch = async_exchange_begin(sess); 94 int rc = async_req_3_3(exch, IPC_M_DEBUG, UDEBUG_M_AREAS_READ, 95 (sysarg_t) buffer, n, NULL, &a_copied, &a_needed); 96 97 *copied = (size_t) a_copied; 98 *needed = (size_t) a_needed; 99 97 100 return rc; 98 101 } 99 102 100 int udebug_mem_read( int phoneid, void *buffer, uintptr_t addr, size_t n)103 int udebug_mem_read(async_sess_t *sess, void *buffer, uintptr_t addr, size_t n) 101 104 { 102 return async_req_4_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_MEM_READ, 103 (sysarg_t)buffer, addr, n); 105 async_exch_t *exch = async_exchange_begin(sess); 106 return async_req_4_0(exch, IPC_M_DEBUG, UDEBUG_M_MEM_READ, 107 (sysarg_t) buffer, addr, n); 104 108 } 105 109 106 int udebug_args_read( int phoneid, thash_t tid, sysarg_t *buffer)110 int udebug_args_read(async_sess_t *sess, thash_t tid, sysarg_t *buffer) 107 111 { 108 return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_ARGS_READ, 109 tid, (sysarg_t)buffer); 112 async_exch_t *exch = async_exchange_begin(sess); 113 return async_req_3_0(exch, IPC_M_DEBUG, UDEBUG_M_ARGS_READ, 114 tid, (sysarg_t) buffer); 110 115 } 111 116 112 int udebug_regs_read( int phoneid, thash_t tid, void *buffer)117 int udebug_regs_read(async_sess_t *sess, thash_t tid, void *buffer) 113 118 { 114 return async_req_3_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_REGS_READ, 115 tid, (sysarg_t)buffer); 119 async_exch_t *exch = async_exchange_begin(sess); 120 return async_req_3_0(exch, IPC_M_DEBUG, UDEBUG_M_REGS_READ, 121 tid, (sysarg_t) buffer); 116 122 } 117 123 118 int udebug_go( int phoneid, thash_t tid, udebug_event_t *ev_type,124 int udebug_go(async_sess_t *sess, thash_t tid, udebug_event_t *ev_type, 119 125 sysarg_t *val0, sysarg_t *val1) 120 126 { 121 127 sysarg_t a_ev_type; 122 int rc;123 124 rc = async_req_2_3(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_GO,128 129 async_exch_t *exch = async_exchange_begin(sess); 130 int rc = async_req_2_3(exch, IPC_M_DEBUG, UDEBUG_M_GO, 125 131 tid, &a_ev_type, val0, val1); 126 132 127 133 *ev_type = a_ev_type; 128 134 return rc; 129 135 } 130 136 131 int udebug_stop( int phoneid, thash_t tid)137 int udebug_stop(async_sess_t *sess, thash_t tid) 132 138 { 133 return async_req_2_0(phoneid, IPC_M_DEBUG_ALL, UDEBUG_M_STOP,134 tid);139 async_exch_t *exch = async_exchange_begin(sess); 140 return async_req_2_0(exch, IPC_M_DEBUG, UDEBUG_M_STOP, tid); 135 141 } 136 142 -
uspace/lib/c/generic/vfs/vfs.c
r2bdf8313 rb0f00a9 33 33 */ 34 34 35 #include <vfs/canonify.h> 35 36 #include <vfs/vfs.h> 36 #include <vfs/ canonify.h>37 #include <vfs/vfs_sess.h> 37 38 #include <macros.h> 38 39 #include <stdlib.h> … … 44 45 #include <sys/types.h> 45 46 #include <ipc/services.h> 46 #include < ipc/ns.h>47 #include <ns.h> 47 48 #include <async.h> 48 49 #include <fibril_synch.h> … … 50 51 #include <assert.h> 51 52 #include <str.h> 52 #include < devmap.h>53 #include <loc.h> 53 54 #include <ipc/vfs.h> 54 #include <ipc/devmap.h> 55 56 static async_sess_t vfs_session; 57 58 static FIBRIL_MUTEX_INITIALIZE(vfs_phone_mutex); 59 static int vfs_phone = -1; 55 #include <ipc/loc.h> 56 57 static FIBRIL_MUTEX_INITIALIZE(vfs_mutex); 58 static async_sess_t *vfs_sess = NULL; 60 59 61 60 static FIBRIL_MUTEX_INITIALIZE(cwd_mutex); … … 65 64 static size_t cwd_size = 0; 66 65 66 /** Start an async exchange on the VFS session. 67 * 68 * @return New exchange. 69 * 70 */ 71 async_exch_t *vfs_exchange_begin(void) 72 { 73 fibril_mutex_lock(&vfs_mutex); 74 75 while (vfs_sess == NULL) 76 vfs_sess = service_connect_blocking(EXCHANGE_PARALLEL, SERVICE_VFS, 77 0, 0); 78 79 fibril_mutex_unlock(&vfs_mutex); 80 81 return async_exchange_begin(vfs_sess); 82 } 83 84 /** Finish an async exchange on the VFS session. 85 * 86 * @param exch Exchange to be finished. 87 * 88 */ 89 void vfs_exchange_end(async_exch_t *exch) 90 { 91 async_exchange_end(exch); 92 } 93 67 94 char *absolutize(const char *path, size_t *retlen) 68 95 { 69 96 char *ncwd_path; 70 97 char *ncwd_path_nc; 71 size_t total_size;72 98 73 99 fibril_mutex_lock(&cwd_mutex); … … 78 104 return NULL; 79 105 } 80 total_size = cwd_size + 1 + size + 1; 81 ncwd_path_nc = malloc(total_size); 106 ncwd_path_nc = malloc(cwd_size + 1 + size + 1); 82 107 if (!ncwd_path_nc) { 83 108 fibril_mutex_unlock(&cwd_mutex); 84 109 return NULL; 85 110 } 86 str_cpy(ncwd_path_nc, total_size, cwd_path);111 str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path); 87 112 ncwd_path_nc[cwd_size] = '/'; 88 113 ncwd_path_nc[cwd_size + 1] = '\0'; 89 114 } else { 90 total_size = size + 1; 91 ncwd_path_nc = malloc(total_size); 115 ncwd_path_nc = malloc(size + 1); 92 116 if (!ncwd_path_nc) { 93 117 fibril_mutex_unlock(&cwd_mutex); … … 96 120 ncwd_path_nc[0] = '\0'; 97 121 } 98 str_append(ncwd_path_nc, total_size, path);122 str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path); 99 123 ncwd_path = canonify(ncwd_path_nc, retlen); 100 124 if (!ncwd_path) { … … 118 142 } 119 143 120 /** Connect to VFS service and create session. */ 121 static void vfs_connect(void) 122 { 123 while (vfs_phone < 0) 124 vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0); 125 126 async_session_create(&vfs_session, vfs_phone, 0); 127 } 128 129 /** Start an async exchange on the VFS session. 130 * 131 * @return New phone to be used during the exchange. 132 */ 133 static int vfs_exchange_begin(void) 134 { 135 fibril_mutex_lock(&vfs_phone_mutex); 136 if (vfs_phone < 0) 137 vfs_connect(); 138 fibril_mutex_unlock(&vfs_phone_mutex); 139 140 return async_exchange_begin(&vfs_session); 141 } 142 143 /** End an async exchange on the VFS session. 144 * 145 * @param phone Phone used during the exchange. 146 */ 147 static void vfs_exchange_end(int phone) 148 { 149 async_exchange_end(&vfs_session, phone); 150 } 151 152 int mount(const char *fs_name, const char *mp, const char *fqdn, 153 const char *opts, unsigned int flags) 144 int mount(const char *fs_name, const char *mp, const char *fqsn, 145 const char *opts, unsigned int flags, unsigned int instance) 154 146 { 155 147 int null_id = -1; 156 char null[ DEVMAP_NAME_MAXLEN];157 158 if (str_cmp(fq dn, "") == 0) {148 char null[LOC_NAME_MAXLEN]; 149 150 if (str_cmp(fqsn, "") == 0) { 159 151 /* No device specified, create a fresh 160 152 null/%d device instead */ 161 null_id = devmap_null_create();153 null_id = loc_null_create(); 162 154 163 155 if (null_id == -1) 164 156 return ENOMEM; 165 157 166 snprintf(null, DEVMAP_NAME_MAXLEN, "null/%d", null_id);167 fq dn = null;168 } 169 170 devmap_handle_t devmap_handle;171 int res = devmap_device_get_handle(fqdn, &devmap_handle, flags);158 snprintf(null, LOC_NAME_MAXLEN, "null/%d", null_id); 159 fqsn = null; 160 } 161 162 service_id_t service_id; 163 int res = loc_service_get_id(fqsn, &service_id, flags); 172 164 if (res != EOK) { 173 165 if (null_id != -1) 174 devmap_null_destroy(null_id);166 loc_null_destroy(null_id); 175 167 176 168 return res; … … 181 173 if (!mpa) { 182 174 if (null_id != -1) 183 devmap_null_destroy(null_id);175 loc_null_destroy(null_id); 184 176 185 177 return ENOMEM; 186 178 } 187 179 188 int vfs_phone= vfs_exchange_begin();180 async_exch_t *exch = vfs_exchange_begin(); 189 181 190 182 sysarg_t rc_orig; 191 aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, devmap_handle, flags, NULL); 192 sysarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size); 193 if (rc != EOK) { 194 vfs_exchange_end(vfs_phone); 183 aid_t req = async_send_3(exch, VFS_IN_MOUNT, service_id, flags, 184 instance, NULL); 185 sysarg_t rc = async_data_write_start(exch, (void *) mpa, mpa_size); 186 if (rc != EOK) { 187 vfs_exchange_end(exch); 195 188 free(mpa); 196 189 async_wait_for(req, &rc_orig); 197 190 198 191 if (null_id != -1) 199 devmap_null_destroy(null_id);200 201 if (rc_orig == EOK) 202 return (int) rc; 203 else 204 return (int) rc_orig; 205 } 206 207 rc = async_data_write_start( vfs_phone, (void *) opts, str_size(opts));208 if (rc != EOK) { 209 vfs_exchange_end( vfs_phone);192 loc_null_destroy(null_id); 193 194 if (rc_orig == EOK) 195 return (int) rc; 196 else 197 return (int) rc_orig; 198 } 199 200 rc = async_data_write_start(exch, (void *) opts, str_size(opts)); 201 if (rc != EOK) { 202 vfs_exchange_end(exch); 210 203 free(mpa); 211 204 async_wait_for(req, &rc_orig); 212 205 213 206 if (null_id != -1) 214 devmap_null_destroy(null_id);215 216 if (rc_orig == EOK) 217 return (int) rc; 218 else 219 return (int) rc_orig; 220 } 221 222 rc = async_data_write_start( vfs_phone, (void *) fs_name, str_size(fs_name));223 if (rc != EOK) { 224 vfs_exchange_end( vfs_phone);207 loc_null_destroy(null_id); 208 209 if (rc_orig == EOK) 210 return (int) rc; 211 else 212 return (int) rc_orig; 213 } 214 215 rc = async_data_write_start(exch, (void *) fs_name, str_size(fs_name)); 216 if (rc != EOK) { 217 vfs_exchange_end(exch); 225 218 free(mpa); 226 219 async_wait_for(req, &rc_orig); 227 220 228 221 if (null_id != -1) 229 devmap_null_destroy(null_id);222 loc_null_destroy(null_id); 230 223 231 224 if (rc_orig == EOK) … … 236 229 237 230 /* Ask VFS whether it likes fs_name. */ 238 rc = async_req_0_0( vfs_phone, IPC_M_PING);239 if (rc != EOK) { 240 vfs_exchange_end( vfs_phone);231 rc = async_req_0_0(exch, VFS_IN_PING); 232 if (rc != EOK) { 233 vfs_exchange_end(exch); 241 234 free(mpa); 242 235 async_wait_for(req, &rc_orig); 243 236 244 237 if (null_id != -1) 245 devmap_null_destroy(null_id);246 247 if (rc_orig == EOK) 248 return (int) rc; 249 else 250 return (int) rc_orig; 251 } 252 253 vfs_exchange_end( vfs_phone);238 loc_null_destroy(null_id); 239 240 if (rc_orig == EOK) 241 return (int) rc; 242 else 243 return (int) rc_orig; 244 } 245 246 vfs_exchange_end(exch); 254 247 free(mpa); 255 248 async_wait_for(req, &rc); 256 249 257 250 if ((rc != EOK) && (null_id != -1)) 258 devmap_null_destroy(null_id);251 loc_null_destroy(null_id); 259 252 260 253 return (int) rc; … … 273 266 return ENOMEM; 274 267 275 int vfs_phone= vfs_exchange_begin();276 277 req = async_send_0( vfs_phone, VFS_IN_UNMOUNT, NULL);278 rc = async_data_write_start( vfs_phone, (void *) mpa, mpa_size);279 if (rc != EOK) { 280 vfs_exchange_end( vfs_phone);268 async_exch_t *exch = vfs_exchange_begin(); 269 270 req = async_send_0(exch, VFS_IN_UNMOUNT, NULL); 271 rc = async_data_write_start(exch, (void *) mpa, mpa_size); 272 if (rc != EOK) { 273 vfs_exchange_end(exch); 281 274 free(mpa); 282 275 async_wait_for(req, &rc_orig); … … 288 281 289 282 290 vfs_exchange_end( vfs_phone);283 vfs_exchange_end(exch); 291 284 free(mpa); 292 285 async_wait_for(req, &rc); … … 297 290 static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag) 298 291 { 299 int vfs_phone= vfs_exchange_begin();292 async_exch_t *exch = vfs_exchange_begin(); 300 293 301 294 ipc_call_t answer; 302 aid_t req = async_send_3( vfs_phone, VFS_IN_OPEN, lflag, oflag, 0, &answer);303 sysarg_t rc = async_data_write_start( vfs_phone, abs, abs_size);304 305 if (rc != EOK) { 306 vfs_exchange_end( vfs_phone);295 aid_t req = async_send_3(exch, VFS_IN_OPEN, lflag, oflag, 0, &answer); 296 sysarg_t rc = async_data_write_start(exch, abs, abs_size); 297 298 if (rc != EOK) { 299 vfs_exchange_end(exch); 307 300 308 301 sysarg_t rc_orig; … … 315 308 } 316 309 317 vfs_exchange_end( vfs_phone);310 vfs_exchange_end(exch); 318 311 async_wait_for(req, &rc); 319 312 … … 337 330 } 338 331 339 int open_node(fdi_node_t *node, int oflag)340 {341 int vfs_phone = vfs_exchange_begin();342 343 ipc_call_t answer;344 aid_t req = async_send_4(vfs_phone, VFS_IN_OPEN_NODE, node->fs_handle,345 node->devmap_handle, node->index, oflag, &answer);346 347 vfs_exchange_end(vfs_phone);348 349 sysarg_t rc;350 async_wait_for(req, &rc);351 352 if (rc != EOK)353 return (int) rc;354 355 return (int) IPC_GET_ARG1(answer);356 }357 358 332 int close(int fildes) 359 333 { 360 334 sysarg_t rc; 361 335 362 int vfs_phone = vfs_exchange_begin(); 363 364 rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes); 365 366 vfs_exchange_end(vfs_phone); 367 368 return (int)rc; 336 async_exch_t *exch = vfs_exchange_begin(); 337 rc = async_req_1_0(exch, VFS_IN_CLOSE, fildes); 338 vfs_exchange_end(exch); 339 340 return (int) rc; 369 341 } 370 342 … … 374 346 ipc_call_t answer; 375 347 aid_t req; 376 377 int vfs_phone = vfs_exchange_begin(); 378 379 req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer); 380 rc = async_data_read_start_generic(vfs_phone, (void *) buf, nbyte, 381 IPC_XF_RESTRICT); 382 if (rc != EOK) { 383 vfs_exchange_end(vfs_phone); 348 349 async_exch_t *exch = vfs_exchange_begin(); 350 351 req = async_send_1(exch, VFS_IN_READ, fildes, &answer); 352 rc = async_data_read_start(exch, (void *)buf, nbyte); 353 if (rc != EOK) { 354 vfs_exchange_end(exch); 384 355 385 356 sysarg_t rc_orig; … … 391 362 return (ssize_t) rc_orig; 392 363 } 393 vfs_exchange_end( vfs_phone);364 vfs_exchange_end(exch); 394 365 async_wait_for(req, &rc); 395 366 if (rc == EOK) … … 404 375 ipc_call_t answer; 405 376 aid_t req; 406 407 int vfs_phone = vfs_exchange_begin(); 408 409 req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer); 410 rc = async_data_write_start_generic(vfs_phone, (void *) buf, nbyte, 411 IPC_XF_RESTRICT); 412 if (rc != EOK) { 413 vfs_exchange_end(vfs_phone); 377 378 async_exch_t *exch = vfs_exchange_begin(); 379 380 req = async_send_1(exch, VFS_IN_WRITE, fildes, &answer); 381 rc = async_data_write_start(exch, (void *)buf, nbyte); 382 if (rc != EOK) { 383 vfs_exchange_end(exch); 414 384 415 385 sysarg_t rc_orig; … … 421 391 return (ssize_t) rc_orig; 422 392 } 423 vfs_exchange_end( vfs_phone);393 vfs_exchange_end(exch); 424 394 async_wait_for(req, &rc); 425 395 if (rc == EOK) … … 429 399 } 430 400 401 /** Read entire buffer. 402 * 403 * In face of short reads this function continues reading until either 404 * the entire buffer is read or no more data is available (at end of file). 405 * 406 * @param fildes File descriptor 407 * @param buf Buffer, @a nbytes bytes long 408 * @param nbytes Number of bytes to read 409 * 410 * @return On success, positive number of bytes read. 411 * On failure, negative error code from read(). 412 */ 413 ssize_t read_all(int fildes, void *buf, size_t nbyte) 414 { 415 ssize_t cnt = 0; 416 size_t nread = 0; 417 uint8_t *bp = (uint8_t *) buf; 418 419 do { 420 bp += cnt; 421 nread += cnt; 422 cnt = read(fildes, bp, nbyte - nread); 423 } while (cnt > 0 && (nbyte - nread - cnt) > 0); 424 425 if (cnt < 0) 426 return cnt; 427 428 return nread + cnt; 429 } 430 431 /** Write entire buffer. 432 * 433 * This function fails if it cannot write exactly @a len bytes to the file. 434 * 435 * @param fildes File descriptor 436 * @param buf Data, @a nbytes bytes long 437 * @param nbytes Number of bytes to write 438 * 439 * @return EOK on error, return value from write() if writing 440 * failed. 441 */ 442 ssize_t write_all(int fildes, const void *buf, size_t nbyte) 443 { 444 ssize_t cnt = 0; 445 ssize_t nwritten = 0; 446 const uint8_t *bp = (uint8_t *) buf; 447 448 do { 449 bp += cnt; 450 nwritten += cnt; 451 cnt = write(fildes, bp, nbyte - nwritten); 452 } while (cnt > 0 && ((ssize_t )nbyte - nwritten - cnt) > 0); 453 454 if (cnt < 0) 455 return cnt; 456 457 if ((ssize_t)nbyte - nwritten - cnt > 0) 458 return EIO; 459 460 return nbyte; 461 } 462 431 463 int fsync(int fildes) 432 464 { 433 int vfs_phone = vfs_exchange_begin(); 434 435 sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes); 436 437 vfs_exchange_end(vfs_phone); 465 async_exch_t *exch = vfs_exchange_begin(); 466 sysarg_t rc = async_req_1_0(exch, VFS_IN_SYNC, fildes); 467 vfs_exchange_end(exch); 438 468 439 469 return (int) rc; … … 442 472 off64_t lseek(int fildes, off64_t offset, int whence) 443 473 { 444 int vfs_phone= vfs_exchange_begin();474 async_exch_t *exch = vfs_exchange_begin(); 445 475 446 476 sysarg_t newoff_lo; 447 477 sysarg_t newoff_hi; 448 sysarg_t rc = async_req_4_2( vfs_phone, VFS_IN_SEEK, fildes,478 sysarg_t rc = async_req_4_2(exch, VFS_IN_SEEK, fildes, 449 479 LOWER32(offset), UPPER32(offset), whence, 450 480 &newoff_lo, &newoff_hi); 451 481 452 vfs_exchange_end( vfs_phone);482 vfs_exchange_end(exch); 453 483 454 484 if (rc != EOK) … … 462 492 sysarg_t rc; 463 493 464 int vfs_phone = vfs_exchange_begin(); 465 466 rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes, 494 async_exch_t *exch = vfs_exchange_begin(); 495 rc = async_req_3_0(exch, VFS_IN_TRUNCATE, fildes, 467 496 LOWER32(length), UPPER32(length)); 468 vfs_exchange_end( vfs_phone);497 vfs_exchange_end(exch); 469 498 470 499 return (int) rc; … … 475 504 sysarg_t rc; 476 505 aid_t req; 477 478 int vfs_phone= vfs_exchange_begin();479 480 req = async_send_1( vfs_phone, VFS_IN_FSTAT, fildes, NULL);481 rc = async_data_read_start( vfs_phone, (void *) stat, sizeof(struct stat));482 if (rc != EOK) { 483 vfs_exchange_end( vfs_phone);506 507 async_exch_t *exch = vfs_exchange_begin(); 508 509 req = async_send_1(exch, VFS_IN_FSTAT, fildes, NULL); 510 rc = async_data_read_start(exch, (void *) stat, sizeof(struct stat)); 511 if (rc != EOK) { 512 vfs_exchange_end(exch); 484 513 485 514 sysarg_t rc_orig; … … 491 520 return (ssize_t) rc_orig; 492 521 } 493 vfs_exchange_end( vfs_phone);522 vfs_exchange_end(exch); 494 523 async_wait_for(req, &rc); 495 524 … … 508 537 return ENOMEM; 509 538 510 int vfs_phone= vfs_exchange_begin();511 512 req = async_send_0( vfs_phone, VFS_IN_STAT, NULL);513 rc = async_data_write_start( vfs_phone, pa, pa_size);514 if (rc != EOK) { 515 vfs_exchange_end( vfs_phone);539 async_exch_t *exch = vfs_exchange_begin(); 540 541 req = async_send_0(exch, VFS_IN_STAT, NULL); 542 rc = async_data_write_start(exch, pa, pa_size); 543 if (rc != EOK) { 544 vfs_exchange_end(exch); 516 545 free(pa); 517 546 async_wait_for(req, &rc_orig); … … 521 550 return (int) rc_orig; 522 551 } 523 rc = async_data_read_start( vfs_phone, stat, sizeof(struct stat));524 if (rc != EOK) { 525 vfs_exchange_end( vfs_phone);552 rc = async_data_read_start(exch, stat, sizeof(struct stat)); 553 if (rc != EOK) { 554 vfs_exchange_end(exch); 526 555 free(pa); 527 556 async_wait_for(req, &rc_orig); … … 531 560 return (int) rc_orig; 532 561 } 533 vfs_exchange_end( vfs_phone);562 vfs_exchange_end(exch); 534 563 free(pa); 535 564 async_wait_for(req, &rc); … … 592 621 return ENOMEM; 593 622 594 int vfs_phone= vfs_exchange_begin();595 596 req = async_send_1( vfs_phone, VFS_IN_MKDIR, mode, NULL);597 rc = async_data_write_start( vfs_phone, pa, pa_size);598 if (rc != EOK) { 599 vfs_exchange_end( vfs_phone);623 async_exch_t *exch = vfs_exchange_begin(); 624 625 req = async_send_1(exch, VFS_IN_MKDIR, mode, NULL); 626 rc = async_data_write_start(exch, pa, pa_size); 627 if (rc != EOK) { 628 vfs_exchange_end(exch); 600 629 free(pa); 601 630 … … 608 637 return (int) rc_orig; 609 638 } 610 vfs_exchange_end( vfs_phone);639 vfs_exchange_end(exch); 611 640 free(pa); 612 641 async_wait_for(req, &rc); … … 623 652 if (!pa) 624 653 return ENOMEM; 625 626 int vfs_phone= vfs_exchange_begin();627 628 req = async_send_ 0(vfs_phone, VFS_IN_UNLINK, NULL);629 rc = async_data_write_start( vfs_phone, pa, pa_size);630 if (rc != EOK) { 631 vfs_exchange_end( vfs_phone);654 655 async_exch_t *exch = vfs_exchange_begin(); 656 657 req = async_send_1(exch, VFS_IN_UNLINK, lflag, NULL); 658 rc = async_data_write_start(exch, pa, pa_size); 659 if (rc != EOK) { 660 vfs_exchange_end(exch); 632 661 free(pa); 633 662 … … 640 669 return (int) rc_orig; 641 670 } 642 vfs_exchange_end( vfs_phone);671 vfs_exchange_end(exch); 643 672 free(pa); 644 673 async_wait_for(req, &rc); … … 673 702 return ENOMEM; 674 703 } 675 676 int vfs_phone= vfs_exchange_begin();677 678 req = async_send_0( vfs_phone, VFS_IN_RENAME, NULL);679 rc = async_data_write_start( vfs_phone, olda, olda_size);680 if (rc != EOK) { 681 vfs_exchange_end( vfs_phone);704 705 async_exch_t *exch = vfs_exchange_begin(); 706 707 req = async_send_0(exch, VFS_IN_RENAME, NULL); 708 rc = async_data_write_start(exch, olda, olda_size); 709 if (rc != EOK) { 710 vfs_exchange_end(exch); 682 711 free(olda); 683 712 free(newa); … … 688 717 return (int) rc_orig; 689 718 } 690 rc = async_data_write_start( vfs_phone, newa, newa_size);691 if (rc != EOK) { 692 vfs_exchange_end( vfs_phone);719 rc = async_data_write_start(exch, newa, newa_size); 720 if (rc != EOK) { 721 vfs_exchange_end(exch); 693 722 free(olda); 694 723 free(newa); … … 699 728 return (int) rc_orig; 700 729 } 701 vfs_exchange_end( vfs_phone);730 vfs_exchange_end(exch); 702 731 free(olda); 703 732 free(newa); … … 755 784 } 756 785 757 int fd_phone(int fildes)786 async_sess_t *fd_session(exch_mgmt_t mgmt, int fildes) 758 787 { 759 788 struct stat stat; 760 761 789 int rc = fstat(fildes, &stat); 762 if (rc != 0) 763 return rc; 764 765 if (!stat.device) 766 return -1; 767 768 return devmap_device_connect(stat.device, 0); 769 } 770 771 int fd_node(int fildes, fdi_node_t *node) 772 { 773 struct stat stat; 774 int rc; 775 776 rc = fstat(fildes, &stat); 777 778 if (rc == EOK) { 779 node->fs_handle = stat.fs_handle; 780 node->devmap_handle = stat.devmap_handle; 781 node->index = stat.index; 782 } 783 784 return rc; 790 if (rc != 0) { 791 errno = rc; 792 return NULL; 793 } 794 795 if (!stat.service) { 796 errno = ENOENT; 797 return NULL; 798 } 799 800 return loc_service_connect(mgmt, stat.service, 0); 785 801 } 786 802 787 803 int dup2(int oldfd, int newfd) 788 804 { 789 int vfs_phone= vfs_exchange_begin();805 async_exch_t *exch = vfs_exchange_begin(); 790 806 791 807 sysarg_t ret; 792 sysarg_t rc = async_req_2_1( vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);793 794 vfs_exchange_end( vfs_phone);808 sysarg_t rc = async_req_2_1(exch, VFS_IN_DUP, oldfd, newfd, &ret); 809 810 vfs_exchange_end(exch); 795 811 796 812 if (rc == EOK) … … 800 816 } 801 817 818 int fd_wait(void) 819 { 820 async_exch_t *exch = vfs_exchange_begin(); 821 822 sysarg_t ret; 823 sysarg_t rc = async_req_0_1(exch, VFS_IN_WAIT_HANDLE, &ret); 824 825 vfs_exchange_end(exch); 826 827 if (rc == EOK) 828 return (int) ret; 829 830 return (int) rc; 831 } 832 833 int get_mtab_list(list_t *mtab_list) 834 { 835 sysarg_t rc; 836 aid_t req; 837 size_t i; 838 sysarg_t num_mounted_fs; 839 840 async_exch_t *exch = vfs_exchange_begin(); 841 842 req = async_send_0(exch, VFS_IN_MTAB_GET, NULL); 843 844 /* Ask VFS how many filesystems are mounted */ 845 rc = async_req_0_1(exch, VFS_IN_PING, &num_mounted_fs); 846 if (rc != EOK) 847 goto exit; 848 849 for (i = 0; i < num_mounted_fs; ++i) { 850 mtab_ent_t *mtab_ent; 851 852 mtab_ent = malloc(sizeof(mtab_ent_t)); 853 if (!mtab_ent) { 854 rc = ENOMEM; 855 goto exit; 856 } 857 858 memset(mtab_ent, 0, sizeof(mtab_ent_t)); 859 860 rc = async_data_read_start(exch, (void *) mtab_ent->mp, 861 MAX_PATH_LEN); 862 if (rc != EOK) 863 goto exit; 864 865 rc = async_data_read_start(exch, (void *) mtab_ent->opts, 866 MAX_MNTOPTS_LEN); 867 if (rc != EOK) 868 goto exit; 869 870 rc = async_data_read_start(exch, (void *) mtab_ent->fs_name, 871 FS_NAME_MAXLEN); 872 if (rc != EOK) 873 goto exit; 874 875 sysarg_t p[2]; 876 877 rc = async_req_0_2(exch, VFS_IN_PING, &p[0], &p[1]); 878 if (rc != EOK) 879 goto exit; 880 881 mtab_ent->instance = p[0]; 882 mtab_ent->service_id = p[1]; 883 884 link_initialize(&mtab_ent->link); 885 list_append(&mtab_ent->link, mtab_list); 886 } 887 888 exit: 889 async_wait_for(req, &rc); 890 vfs_exchange_end(exch); 891 return rc; 892 } 893 802 894 /** @} 803 895 */
Note:
See TracChangeset
for help on using the changeset viewer.
