Changes in uspace/lib/c/generic/async.c [1db6dfd:df956b9b] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async.c
r1db6dfd rdf956b9b 109 109 #include <sys/time.h> 110 110 #include <libarch/barrier.h> 111 #include < bool.h>111 #include <stdbool.h> 112 112 #include <malloc.h> 113 113 #include <mem.h> 114 114 #include <stdlib.h> 115 115 #include <macros.h> 116 117 #define CLIENT_HASH_TABLE_BUCKETS 32 118 #define CONN_HASH_TABLE_BUCKETS 32 116 #include "private/libc.h" 117 119 118 120 119 /** Session data */ … … 204 203 /* Client connection data */ 205 204 typedef struct { 206 link_t link;205 ht_link_t link; 207 206 208 207 task_id_t in_task_id; … … 216 215 217 216 /** Hash table link. */ 218 link_t link;217 ht_link_t link; 219 218 220 219 /** Incoming client task ID. */ … … 351 350 static async_client_conn_t client_connection = default_client_connection; 352 351 static async_interrupt_handler_t interrupt_received = default_interrupt_received; 352 static size_t interrupt_handler_stksz = FIBRIL_DFLT_STK_SIZE; 353 353 354 354 /** Setter for client_connection function pointer. … … 371 371 { 372 372 interrupt_received = intr; 373 } 374 375 /** Set the stack size for the interrupt handler notification fibrils. 376 * 377 * @param size Stack size in bytes. 378 */ 379 void async_set_interrupt_handler_stack_size(size_t size) 380 { 381 interrupt_handler_stksz = size; 373 382 } 374 383 … … 392 401 static LIST_INITIALIZE(timeout_list); 393 402 394 static hash_index_t client_hash(unsigned long key[]) 395 { 396 assert(key); 397 398 return (((key[0]) >> 4) % CLIENT_HASH_TABLE_BUCKETS); 399 } 400 401 static int client_compare(unsigned long key[], hash_count_t keys, link_t *item) 402 { 403 assert(key); 404 assert(keys == 2); 405 assert(item); 406 407 client_t *client = hash_table_get_instance(item, client_t, link); 408 return (key[0] == LOWER32(client->in_task_id) && 409 (key[1] == UPPER32(client->in_task_id))); 410 } 411 412 static void client_remove(link_t *item) 413 { 414 } 403 static size_t client_key_hash(void *k) 404 { 405 task_id_t key = *(task_id_t*)k; 406 return key; 407 } 408 409 static size_t client_hash(const ht_link_t *item) 410 { 411 client_t *client = hash_table_get_inst(item, client_t, link); 412 return client_key_hash(&client->in_task_id); 413 } 414 415 static bool client_key_equal(void *k, const ht_link_t *item) 416 { 417 task_id_t key = *(task_id_t*)k; 418 client_t *client = hash_table_get_inst(item, client_t, link); 419 return key == client->in_task_id; 420 } 421 415 422 416 423 /** Operations for the client hash table. */ 417 static hash_table_op erations_t client_hash_table_ops = {424 static hash_table_ops_t client_hash_table_ops = { 418 425 .hash = client_hash, 419 .compare = client_compare, 420 .remove_callback = client_remove 426 .key_hash = client_key_hash, 427 .key_equal = client_key_equal, 428 .equal = NULL, 429 .remove_callback = NULL 421 430 }; 422 431 … … 428 437 * 429 438 */ 430 static hash_index_t conn_hash(unsigned long key[]) 431 { 432 assert(key); 433 434 return (((key[0]) >> 4) % CONN_HASH_TABLE_BUCKETS); 435 } 436 437 /** Compare hash table item with a key. 438 * 439 * @param key Array containing the source phone hash as the only item. 440 * @param keys Expected 1 but ignored. 441 * @param item Connection hash table item. 442 * 443 * @return True on match, false otherwise. 444 * 445 */ 446 static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item) 447 { 448 assert(key); 449 assert(item); 450 451 connection_t *conn = hash_table_get_instance(item, connection_t, link); 452 return (key[0] == conn->in_phone_hash); 453 } 454 455 static void conn_remove(link_t *item) 456 { 457 } 439 static size_t conn_key_hash(void *key) 440 { 441 sysarg_t in_phone_hash = *(sysarg_t*)key; 442 return in_phone_hash ; 443 } 444 445 static size_t conn_hash(const ht_link_t *item) 446 { 447 connection_t *conn = hash_table_get_inst(item, connection_t, link); 448 return conn_key_hash(&conn->in_phone_hash); 449 } 450 451 static bool conn_key_equal(void *key, const ht_link_t *item) 452 { 453 sysarg_t in_phone_hash = *(sysarg_t*)key; 454 connection_t *conn = hash_table_get_inst(item, connection_t, link); 455 return (in_phone_hash == conn->in_phone_hash); 456 } 457 458 458 459 459 /** Operations for the connection hash table. */ 460 static hash_table_op erations_t conn_hash_table_ops = {460 static hash_table_ops_t conn_hash_table_ops = { 461 461 .hash = conn_hash, 462 .compare = conn_compare, 463 .remove_callback = conn_remove 462 .key_hash = conn_key_hash, 463 .key_equal = conn_key_equal, 464 .equal = NULL, 465 .remove_callback = NULL 464 466 }; 465 467 … … 509 511 futex_down(&async_futex); 510 512 511 unsigned long key = call->in_phone_hash; 512 link_t *hlp = hash_table_find(&conn_hash_table, &key); 513 ht_link_t *hlp = hash_table_find(&conn_hash_table, &call->in_phone_hash); 513 514 514 515 if (!hlp) { … … 517 518 } 518 519 519 connection_t *conn = hash_table_get_inst ance(hlp, connection_t, link);520 connection_t *conn = hash_table_get_inst(hlp, connection_t, link); 520 521 521 522 msg_t *msg = malloc(sizeof(*msg)); … … 596 597 msg->call = *call; 597 598 598 fid_t fid = fibril_create(notification_fibril, msg); 599 fid_t fid = fibril_create_generic(notification_fibril, msg, 600 interrupt_handler_stksz); 599 601 if (fid == 0) { 600 602 free(msg); … … 637 639 638 640 if (usecs) { 639 get timeofday(&conn->wdata.to_event.expires, NULL);641 getuptime(&conn->wdata.to_event.expires); 640 642 tv_add(&conn->wdata.to_event.expires, usecs); 641 643 } else … … 697 699 static client_t *async_client_get(task_id_t client_id, bool create) 698 700 { 699 unsigned long key[2] = {700 LOWER32(client_id),701 UPPER32(client_id),702 };703 701 client_t *client = NULL; 704 702 705 703 futex_down(&async_futex); 706 link_t *lnk = hash_table_find(&client_hash_table, key);704 ht_link_t *lnk = hash_table_find(&client_hash_table, &client_id); 707 705 if (lnk) { 708 client = hash_table_get_inst ance(lnk, client_t, link);706 client = hash_table_get_inst(lnk, client_t, link); 709 707 atomic_inc(&client->refcnt); 710 708 } else if (create) { … … 715 713 716 714 atomic_set(&client->refcnt, 1); 717 hash_table_insert(&client_hash_table, key,&client->link);715 hash_table_insert(&client_hash_table, &client->link); 718 716 } 719 717 } … … 726 724 { 727 725 bool destroy; 728 unsigned long key[2] = { 729 LOWER32(client->in_task_id), 730 UPPER32(client->in_task_id) 731 }; 732 726 733 727 futex_down(&async_futex); 734 728 735 729 if (atomic_predec(&client->refcnt) == 0) { 736 hash_table_remove(&client_hash_table, key, 2);730 hash_table_remove(&client_hash_table, &client->in_task_id); 737 731 destroy = true; 738 732 } else … … 830 824 */ 831 825 futex_down(&async_futex); 832 unsigned long key = fibril_connection->in_phone_hash; 833 hash_table_remove(&conn_hash_table, &key, 1); 826 hash_table_remove(&conn_hash_table, &fibril_connection->in_phone_hash); 834 827 futex_up(&async_futex); 835 828 … … 915 908 916 909 /* Add connection to the connection hash table */ 917 unsigned long key = conn->in_phone_hash;918 910 919 911 futex_down(&async_futex); 920 hash_table_insert(&conn_hash_table, & key, &conn->link);912 hash_table_insert(&conn_hash_table, &conn->link); 921 913 futex_up(&async_futex); 922 914 … … 946 938 947 939 switch (IPC_GET_IMETHOD(*call)) { 948 case IPC_M_C ONNECT_ME:940 case IPC_M_CLONE_ESTABLISH: 949 941 case IPC_M_CONNECT_ME_TO: 950 942 /* Open new connection with fibril, etc. */ … … 966 958 { 967 959 struct timeval tv; 968 get timeofday(&tv, NULL);960 getuptime(&tv); 969 961 970 962 futex_down(&async_futex); … … 1023 1015 1024 1016 struct timeval tv; 1025 get timeofday(&tv, NULL);1017 getuptime(&tv); 1026 1018 1027 1019 if (tv_gteq(&tv, &waiter->to_event.expires)) { … … 1110 1102 void __async_init(void) 1111 1103 { 1112 if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 1113 2, &client_hash_table_ops)) 1104 if (!hash_table_create(&client_hash_table, 0, 0, &client_hash_table_ops)) 1114 1105 abort(); 1115 1106 1116 if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS, 1117 1, &conn_hash_table_ops)) 1107 if (!hash_table_create(&conn_hash_table, 0, 0, &conn_hash_table_ops)) 1118 1108 abort(); 1119 1109 … … 1330 1320 timeout = 0; 1331 1321 1332 get timeofday(&msg->wdata.to_event.expires, NULL);1322 getuptime(&msg->wdata.to_event.expires); 1333 1323 tv_add(&msg->wdata.to_event.expires, timeout); 1334 1324 … … 1388 1378 1389 1379 futex_down(&async_futex); 1390 if (msg->done) 1380 if (msg->done) { 1391 1381 amsg_destroy(msg); 1392 else 1382 } else { 1383 msg->dataptr = NULL; 1393 1384 msg->forget = true; 1385 } 1394 1386 futex_up(&async_futex); 1395 1387 } … … 1410 1402 msg->wdata.fid = fibril_get_id(); 1411 1403 1412 get timeofday(&msg->wdata.to_event.expires, NULL);1404 getuptime(&msg->wdata.to_event.expires); 1413 1405 tv_add(&msg->wdata.to_event.expires, timeout); 1414 1406 … … 1668 1660 } 1669 1661 1670 /** Wrapper for making IPC_M_C ONNECT_MEcalls using the async framework.1671 * 1672 * Ask throughfor a cloned connection to some service.1662 /** Wrapper for making IPC_M_CLONE_ESTABLISH calls using the async framework. 1663 * 1664 * Ask for a cloned connection to some service. 1673 1665 * 1674 1666 * @param mgmt Exchange management style. … … 1678 1670 * 1679 1671 */ 1680 async_sess_t *async_c onnect_me(exch_mgmt_t mgmt, async_exch_t *exch)1672 async_sess_t *async_clone_establish(exch_mgmt_t mgmt, async_exch_t *exch) 1681 1673 { 1682 1674 if (exch == NULL) { … … 1703 1695 msg->wdata.active = true; 1704 1696 1705 ipc_call_async_0(exch->phone, IPC_M_C ONNECT_ME, msg,1697 ipc_call_async_0(exch->phone, IPC_M_CLONE_ESTABLISH, msg, 1706 1698 reply_received, true); 1707 1699 … … 2076 2068 2077 2069 async_sess_t *sess = exch->sess; 2070 assert(sess != NULL); 2078 2071 2079 2072 atomic_dec(&sess->refcnt); … … 2097 2090 * @param arg User defined argument. 2098 2091 * @param flags Storage for the received flags. Can be NULL. 2099 * @param dst Destination address space area base. Cannot be NULL. 2092 * @param dst Address of the storage for the destination address space area 2093 * base address. Cannot be NULL. 2100 2094 * 2101 2095 * @return Zero on success or a negative error code from errno.h. … … 2164 2158 int async_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags) 2165 2159 { 2166 return ipc_share_in_finalize(callid, src, flags); 2160 return ipc_answer_3(callid, EOK, (sysarg_t) src, (sysarg_t) flags, 2161 (sysarg_t) __entry); 2167 2162 } 2168 2163 … … 2224 2219 * 2225 2220 * @param callid Hash of the IPC_M_DATA_WRITE call to answer. 2226 * @param dst Destination address space area base address. 2221 * @param dst Address of the storage for the destination address space area 2222 * base address. 2227 2223 * 2228 2224 * @return Zero on success or a value from @ref errno.h on failure. … … 2231 2227 int async_share_out_finalize(ipc_callid_t callid, void **dst) 2232 2228 { 2233 return ipc_ share_out_finalize(callid,dst);2229 return ipc_answer_2(callid, EOK, (sysarg_t) __entry, (sysarg_t) dst); 2234 2230 } 2235 2231 … … 2315 2311 int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size) 2316 2312 { 2317 return ipc_ data_read_finalize(callid, src,size);2313 return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) size); 2318 2314 } 2319 2315 … … 2418 2414 int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size) 2419 2415 { 2420 return ipc_ data_write_finalize(callid, dst,size);2416 return ipc_answer_2(callid, EOK, (sysarg_t) dst, (sysarg_t) size); 2421 2417 } 2422 2418
Note:
See TracChangeset
for help on using the changeset viewer.