Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/async.c

    rdf956b9b r1db6dfd  
    109109#include <sys/time.h>
    110110#include <libarch/barrier.h>
    111 #include <stdbool.h>
     111#include <bool.h>
    112112#include <malloc.h>
    113113#include <mem.h>
    114114#include <stdlib.h>
    115115#include <macros.h>
    116 #include "private/libc.h"
    117 
     116
     117#define CLIENT_HASH_TABLE_BUCKETS  32
     118#define CONN_HASH_TABLE_BUCKETS    32
    118119
    119120/** Session data */
     
    203204/* Client connection data */
    204205typedef struct {
    205         ht_link_t link;
     206        link_t link;
    206207       
    207208        task_id_t in_task_id;
     
    215216       
    216217        /** Hash table link. */
    217         ht_link_t link;
     218        link_t link;
    218219       
    219220        /** Incoming client task ID. */
     
    350351static async_client_conn_t client_connection = default_client_connection;
    351352static async_interrupt_handler_t interrupt_received = default_interrupt_received;
    352 static size_t interrupt_handler_stksz = FIBRIL_DFLT_STK_SIZE;
    353353
    354354/** Setter for client_connection function pointer.
     
    371371{
    372372        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;
    382373}
    383374
     
    401392static LIST_INITIALIZE(timeout_list);
    402393
    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 
     394static hash_index_t client_hash(unsigned long key[])
     395{
     396        assert(key);
     397       
     398        return (((key[0]) >> 4) % CLIENT_HASH_TABLE_BUCKETS);
     399}
     400
     401static 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
     412static void client_remove(link_t *item)
     413{
     414}
    422415
    423416/** Operations for the client hash table. */
    424 static hash_table_ops_t client_hash_table_ops = {
     417static hash_table_operations_t client_hash_table_ops = {
    425418        .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
    430421};
    431422
     
    437428 *
    438429 */
    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 
     430static 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 */
     446static 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
     455static void conn_remove(link_t *item)
     456{
     457}
    458458
    459459/** Operations for the connection hash table. */
    460 static hash_table_ops_t conn_hash_table_ops = {
     460static hash_table_operations_t conn_hash_table_ops = {
    461461        .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
    466464};
    467465
     
    511509        futex_down(&async_futex);
    512510       
    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);
    514513       
    515514        if (!hlp) {
     
    518517        }
    519518       
    520         connection_t *conn = hash_table_get_inst(hlp, connection_t, link);
     519        connection_t *conn = hash_table_get_instance(hlp, connection_t, link);
    521520       
    522521        msg_t *msg = malloc(sizeof(*msg));
     
    597596        msg->call = *call;
    598597       
    599         fid_t fid = fibril_create_generic(notification_fibril, msg,
    600             interrupt_handler_stksz);
     598        fid_t fid = fibril_create(notification_fibril, msg);
    601599        if (fid == 0) {
    602600                free(msg);
     
    639637       
    640638        if (usecs) {
    641                 getuptime(&conn->wdata.to_event.expires);
     639                gettimeofday(&conn->wdata.to_event.expires, NULL);
    642640                tv_add(&conn->wdata.to_event.expires, usecs);
    643641        } else
     
    699697static client_t *async_client_get(task_id_t client_id, bool create)
    700698{
     699        unsigned long key[2] = {
     700                LOWER32(client_id),
     701                UPPER32(client_id),
     702        };
    701703        client_t *client = NULL;
    702704
    703705        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);
    705707        if (lnk) {
    706                 client = hash_table_get_inst(lnk, client_t, link);
     708                client = hash_table_get_instance(lnk, client_t, link);
    707709                atomic_inc(&client->refcnt);
    708710        } else if (create) {
     
    713715               
    714716                        atomic_set(&client->refcnt, 1);
    715                         hash_table_insert(&client_hash_table, &client->link);
     717                        hash_table_insert(&client_hash_table, key, &client->link);
    716718                }
    717719        }
     
    724726{
    725727        bool destroy;
    726 
     728        unsigned long key[2] = {
     729                LOWER32(client->in_task_id),
     730                UPPER32(client->in_task_id)
     731        };
     732       
    727733        futex_down(&async_futex);
    728734       
    729735        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);
    731737                destroy = true;
    732738        } else
     
    824830         */
    825831        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);
    827834        futex_up(&async_futex);
    828835       
     
    908915       
    909916        /* Add connection to the connection hash table */
     917        unsigned long key = conn->in_phone_hash;
    910918       
    911919        futex_down(&async_futex);
    912         hash_table_insert(&conn_hash_table, &conn->link);
     920        hash_table_insert(&conn_hash_table, &key, &conn->link);
    913921        futex_up(&async_futex);
    914922       
     
    938946       
    939947        switch (IPC_GET_IMETHOD(*call)) {
    940         case IPC_M_CLONE_ESTABLISH:
     948        case IPC_M_CONNECT_ME:
    941949        case IPC_M_CONNECT_ME_TO:
    942950                /* Open new connection with fibril, etc. */
     
    958966{
    959967        struct timeval tv;
    960         getuptime(&tv);
     968        gettimeofday(&tv, NULL);
    961969       
    962970        futex_down(&async_futex);
     
    10151023                       
    10161024                        struct timeval tv;
    1017                         getuptime(&tv);
     1025                        gettimeofday(&tv, NULL);
    10181026                       
    10191027                        if (tv_gteq(&tv, &waiter->to_event.expires)) {
     
    11021110void __async_init(void)
    11031111{
    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))
    11051114                abort();
    11061115       
    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))
    11081118                abort();
    11091119       
     
    13201330                timeout = 0;
    13211331
    1322         getuptime(&msg->wdata.to_event.expires);
     1332        gettimeofday(&msg->wdata.to_event.expires, NULL);
    13231333        tv_add(&msg->wdata.to_event.expires, timeout);
    13241334       
     
    13781388
    13791389        futex_down(&async_futex);
    1380         if (msg->done) {
     1390        if (msg->done)
    13811391                amsg_destroy(msg);
    1382         } else {
    1383                 msg->dataptr = NULL;
     1392        else
    13841393                msg->forget = true;
    1385         }
    13861394        futex_up(&async_futex);
    13871395}
     
    14021410        msg->wdata.fid = fibril_get_id();
    14031411       
    1404         getuptime(&msg->wdata.to_event.expires);
     1412        gettimeofday(&msg->wdata.to_event.expires, NULL);
    14051413        tv_add(&msg->wdata.to_event.expires, timeout);
    14061414       
     
    16601668}
    16611669
    1662 /** Wrapper for making IPC_M_CLONE_ESTABLISH calls 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.
    16651673 *
    16661674 * @param mgmt Exchange management style.
     
    16701678 *
    16711679 */
    1672 async_sess_t *async_clone_establish(exch_mgmt_t mgmt, async_exch_t *exch)
     1680async_sess_t *async_connect_me(exch_mgmt_t mgmt, async_exch_t *exch)
    16731681{
    16741682        if (exch == NULL) {
     
    16951703        msg->wdata.active = true;
    16961704       
    1697         ipc_call_async_0(exch->phone, IPC_M_CLONE_ESTABLISH, msg,
     1705        ipc_call_async_0(exch->phone, IPC_M_CONNECT_ME, msg,
    16981706            reply_received, true);
    16991707       
     
    20682076       
    20692077        async_sess_t *sess = exch->sess;
    2070         assert(sess != NULL);
    20712078       
    20722079        atomic_dec(&sess->refcnt);
     
    20902097 * @param arg   User defined argument.
    20912098 * @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.
    20942100 *
    20952101 * @return Zero on success or a negative error code from errno.h.
     
    21582164int async_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags)
    21592165{
    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);
    21622167}
    21632168
     
    22192224 *
    22202225 * @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.
    22232227 *
    22242228 * @return Zero on success or a value from @ref errno.h on failure.
     
    22272231int async_share_out_finalize(ipc_callid_t callid, void **dst)
    22282232{
    2229         return ipc_answer_2(callid, EOK, (sysarg_t) __entry, (sysarg_t) dst);
     2233        return ipc_share_out_finalize(callid, dst);
    22302234}
    22312235
     
    23112315int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
    23122316{
    2313         return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) size);
     2317        return ipc_data_read_finalize(callid, src, size);
    23142318}
    23152319
     
    24142418int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)
    24152419{
    2416         return ipc_answer_2(callid, EOK, (sysarg_t) dst, (sysarg_t) size);
     2420        return ipc_data_write_finalize(callid, dst, size);
    24172421}
    24182422
Note: See TracChangeset for help on using the changeset viewer.