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