Ignore:
File:
1 edited

Legend:

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

    r1db6dfd rdf956b9b  
    109109#include <sys/time.h>
    110110#include <libarch/barrier.h>
    111 #include <bool.h>
     111#include <stdbool.h>
    112112#include <malloc.h>
    113113#include <mem.h>
    114114#include <stdlib.h>
    115115#include <macros.h>
    116 
    117 #define CLIENT_HASH_TABLE_BUCKETS  32
    118 #define CONN_HASH_TABLE_BUCKETS    32
     116#include "private/libc.h"
     117
    119118
    120119/** Session data */
     
    204203/* Client connection data */
    205204typedef struct {
    206         link_t link;
     205        ht_link_t link;
    207206       
    208207        task_id_t in_task_id;
     
    216215       
    217216        /** Hash table link. */
    218         link_t link;
     217        ht_link_t link;
    219218       
    220219        /** Incoming client task ID. */
     
    351350static async_client_conn_t client_connection = default_client_connection;
    352351static async_interrupt_handler_t interrupt_received = default_interrupt_received;
     352static 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 */
     379void async_set_interrupt_handler_stack_size(size_t size)
     380{
     381        interrupt_handler_stksz = size;
    373382}
    374383
     
    392401static LIST_INITIALIZE(timeout_list);
    393402
    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 }
     403static size_t client_key_hash(void *k)
     404{
     405        task_id_t key = *(task_id_t*)k;
     406        return key;
     407}
     408
     409static 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
     415static 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
    415422
    416423/** Operations for the client hash table. */
    417 static hash_table_operations_t client_hash_table_ops = {
     424static hash_table_ops_t client_hash_table_ops = {
    418425        .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
    421430};
    422431
     
    428437 *
    429438 */
    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 }
     439static size_t conn_key_hash(void *key)
     440{
     441        sysarg_t in_phone_hash  = *(sysarg_t*)key;
     442        return in_phone_hash ;
     443}
     444
     445static 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
     451static 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
    458458
    459459/** Operations for the connection hash table. */
    460 static hash_table_operations_t conn_hash_table_ops = {
     460static hash_table_ops_t conn_hash_table_ops = {
    461461        .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
    464466};
    465467
     
    509511        futex_down(&async_futex);
    510512       
    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);
    513514       
    514515        if (!hlp) {
     
    517518        }
    518519       
    519         connection_t *conn = hash_table_get_instance(hlp, connection_t, link);
     520        connection_t *conn = hash_table_get_inst(hlp, connection_t, link);
    520521       
    521522        msg_t *msg = malloc(sizeof(*msg));
     
    596597        msg->call = *call;
    597598       
    598         fid_t fid = fibril_create(notification_fibril, msg);
     599        fid_t fid = fibril_create_generic(notification_fibril, msg,
     600            interrupt_handler_stksz);
    599601        if (fid == 0) {
    600602                free(msg);
     
    637639       
    638640        if (usecs) {
    639                 gettimeofday(&conn->wdata.to_event.expires, NULL);
     641                getuptime(&conn->wdata.to_event.expires);
    640642                tv_add(&conn->wdata.to_event.expires, usecs);
    641643        } else
     
    697699static client_t *async_client_get(task_id_t client_id, bool create)
    698700{
    699         unsigned long key[2] = {
    700                 LOWER32(client_id),
    701                 UPPER32(client_id),
    702         };
    703701        client_t *client = NULL;
    704702
    705703        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);
    707705        if (lnk) {
    708                 client = hash_table_get_instance(lnk, client_t, link);
     706                client = hash_table_get_inst(lnk, client_t, link);
    709707                atomic_inc(&client->refcnt);
    710708        } else if (create) {
     
    715713               
    716714                        atomic_set(&client->refcnt, 1);
    717                         hash_table_insert(&client_hash_table, key, &client->link);
     715                        hash_table_insert(&client_hash_table, &client->link);
    718716                }
    719717        }
     
    726724{
    727725        bool destroy;
    728         unsigned long key[2] = {
    729                 LOWER32(client->in_task_id),
    730                 UPPER32(client->in_task_id)
    731         };
    732        
     726
    733727        futex_down(&async_futex);
    734728       
    735729        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);
    737731                destroy = true;
    738732        } else
     
    830824         */
    831825        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);
    834827        futex_up(&async_futex);
    835828       
     
    915908       
    916909        /* Add connection to the connection hash table */
    917         unsigned long key = conn->in_phone_hash;
    918910       
    919911        futex_down(&async_futex);
    920         hash_table_insert(&conn_hash_table, &key, &conn->link);
     912        hash_table_insert(&conn_hash_table, &conn->link);
    921913        futex_up(&async_futex);
    922914       
     
    946938       
    947939        switch (IPC_GET_IMETHOD(*call)) {
    948         case IPC_M_CONNECT_ME:
     940        case IPC_M_CLONE_ESTABLISH:
    949941        case IPC_M_CONNECT_ME_TO:
    950942                /* Open new connection with fibril, etc. */
     
    966958{
    967959        struct timeval tv;
    968         gettimeofday(&tv, NULL);
     960        getuptime(&tv);
    969961       
    970962        futex_down(&async_futex);
     
    10231015                       
    10241016                        struct timeval tv;
    1025                         gettimeofday(&tv, NULL);
     1017                        getuptime(&tv);
    10261018                       
    10271019                        if (tv_gteq(&tv, &waiter->to_event.expires)) {
     
    11101102void __async_init(void)
    11111103{
    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))
    11141105                abort();
    11151106       
    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))
    11181108                abort();
    11191109       
     
    13301320                timeout = 0;
    13311321
    1332         gettimeofday(&msg->wdata.to_event.expires, NULL);
     1322        getuptime(&msg->wdata.to_event.expires);
    13331323        tv_add(&msg->wdata.to_event.expires, timeout);
    13341324       
     
    13881378
    13891379        futex_down(&async_futex);
    1390         if (msg->done)
     1380        if (msg->done) {
    13911381                amsg_destroy(msg);
    1392         else
     1382        } else {
     1383                msg->dataptr = NULL;
    13931384                msg->forget = true;
     1385        }
    13941386        futex_up(&async_futex);
    13951387}
     
    14101402        msg->wdata.fid = fibril_get_id();
    14111403       
    1412         gettimeofday(&msg->wdata.to_event.expires, NULL);
     1404        getuptime(&msg->wdata.to_event.expires);
    14131405        tv_add(&msg->wdata.to_event.expires, timeout);
    14141406       
     
    16681660}
    16691661
    1670 /** Wrapper for making IPC_M_CONNECT_ME calls using the async framework.
    1671  *
    1672  * Ask through for 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.
    16731665 *
    16741666 * @param mgmt Exchange management style.
     
    16781670 *
    16791671 */
    1680 async_sess_t *async_connect_me(exch_mgmt_t mgmt, async_exch_t *exch)
     1672async_sess_t *async_clone_establish(exch_mgmt_t mgmt, async_exch_t *exch)
    16811673{
    16821674        if (exch == NULL) {
     
    17031695        msg->wdata.active = true;
    17041696       
    1705         ipc_call_async_0(exch->phone, IPC_M_CONNECT_ME, msg,
     1697        ipc_call_async_0(exch->phone, IPC_M_CLONE_ESTABLISH, msg,
    17061698            reply_received, true);
    17071699       
     
    20762068       
    20772069        async_sess_t *sess = exch->sess;
     2070        assert(sess != NULL);
    20782071       
    20792072        atomic_dec(&sess->refcnt);
     
    20972090 * @param arg   User defined argument.
    20982091 * @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.
    21002094 *
    21012095 * @return Zero on success or a negative error code from errno.h.
     
    21642158int async_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags)
    21652159{
    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);
    21672162}
    21682163
     
    22242219 *
    22252220 * @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.
    22272223 *
    22282224 * @return Zero on success or a value from @ref errno.h on failure.
     
    22312227int async_share_out_finalize(ipc_callid_t callid, void **dst)
    22322228{
    2233         return ipc_share_out_finalize(callid, dst);
     2229        return ipc_answer_2(callid, EOK, (sysarg_t) __entry, (sysarg_t) dst);
    22342230}
    22352231
     
    23152311int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
    23162312{
    2317         return ipc_data_read_finalize(callid, src, size);
     2313        return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) size);
    23182314}
    23192315
     
    24182414int async_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)
    24192415{
    2420         return ipc_data_write_finalize(callid, dst, size);
     2416        return ipc_answer_2(callid, EOK, (sysarg_t) dst, (sysarg_t) size);
    24212417}
    24222418
Note: See TracChangeset for help on using the changeset viewer.