Changeset 8b5690f in mainline for uspace/lib/c/generic


Ignore:
Timestamp:
2011-02-03T05:11:01Z (15 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ba38f72c
Parents:
22027b6e (diff), 86d7bfa (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.
Message:

Merge mainline changes.

Location:
uspace/lib/c/generic
Files:
2 added
23 edited
5 moved

Legend:

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

    r22027b6e r8b5690f  
    4343 * framework will automatically take care of most synchronization problems.
    4444 *
    45  * Default semantics:
    46  * - async_send_*(): Send asynchronously. If the kernel refuses to send
    47  *                   more messages, [ try to get responses from kernel, if
    48  *                   nothing found, might try synchronous ]
    49  *
    5045 * Example of use (pseudo C):
    5146 *
     
    5853 *   int fibril1(void *arg)
    5954 *   {
    60  *     conn = ipc_connect_me_to();
     55 *     conn = async_connect_me_to();
    6156 *     c1 = async_send(conn);
    6257 *     c2 = async_send(conn);
     
    7772 *   {
    7873 *     if (want_refuse) {
    79  *       ipc_answer_0(icallid, ELIMIT);
     74 *       async_answer_0(icallid, ELIMIT);
    8075 *       return;
    8176 *     }
    82  *     ipc_answer_0(icallid, EOK);
     77 *     async_answer_0(icallid, EOK);
    8378 *
    8479 *     callid = async_get_call(&call);
    8580 *     somehow_handle_the_call(callid, call);
    86  *     ipc_answer_2(callid, 1, 2, 3);
     81 *     async_answer_2(callid, 1, 2, 3);
    8782 *
    8883 *     callid = async_get_call(&call);
     
    9287 */
    9388
     89#define LIBC_ASYNC_C_
     90#include <ipc/ipc.h>
     91#include <async.h>
     92#undef LIBC_ASYNC_C_
     93
    9494#include <futex.h>
    95 #include <async.h>
    96 #include <async_priv.h>
    9795#include <fibril.h>
    9896#include <stdio.h>
    9997#include <adt/hash_table.h>
    10098#include <adt/list.h>
    101 #include <ipc/ipc.h>
    10299#include <assert.h>
    103100#include <errno.h>
     
    105102#include <arch/barrier.h>
    106103#include <bool.h>
     104#include "private/async.h"
    107105
    108106atomic_t async_futex = FUTEX_INITIALIZER;
     
    124122
    125123/**
    126  * Structures of this type are used to group information about a call and a
    127  * message queue link.
     124 * Structures of this type are used to group information about
     125 * a call and about a message queue link.
    128126 */
    129127typedef struct {
     
    134132
    135133typedef struct {
     134        sysarg_t in_task_hash;
     135        link_t link;
     136        int refcnt;
     137        void *data;
     138} client_t;
     139
     140typedef struct {
    136141        awaiter_t wdata;
    137142       
     
    139144        link_t link;
    140145       
     146        /** Incoming client task hash. */
     147        sysarg_t in_task_hash;
    141148        /** Incoming phone hash. */
    142149        sysarg_t in_phone_hash;
     150       
     151        /** Link to the client tracking structure. */
     152        client_t *client;
    143153       
    144154        /** Messages that should be delivered to this fibril. */
     
    158168
    159169/** Identifier of the incoming connection handled by the current fibril. */
    160 fibril_local connection_t *FIBRIL_connection;
    161 
    162 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call);
    163 static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call);
     170static fibril_local connection_t *FIBRIL_connection;
     171
     172static void *default_client_data_constructor(void)
     173{
     174        return NULL;
     175}
     176
     177static void default_client_data_destructor(void *data)
     178{
     179}
     180
     181static async_client_data_ctor_t async_client_data_create =
     182    default_client_data_constructor;
     183static async_client_data_dtor_t async_client_data_destroy =
     184    default_client_data_destructor;
     185
     186void async_set_client_data_constructor(async_client_data_ctor_t ctor)
     187{
     188        async_client_data_create = ctor;
     189}
     190
     191void async_set_client_data_destructor(async_client_data_dtor_t dtor)
     192{
     193        async_client_data_destroy = dtor;
     194}
     195
     196void *async_client_data_get(void)
     197{
     198        assert(FIBRIL_connection);
     199        return FIBRIL_connection->client->data;
     200}
     201
     202/** Default fibril function that gets called to handle new connection.
     203 *
     204 * This function is defined as a weak symbol - to be redefined in user code.
     205 *
     206 * @param callid Hash of the incoming call.
     207 * @param call   Data of the incoming call.
     208 *
     209 */
     210static void default_client_connection(ipc_callid_t callid, ipc_call_t *call)
     211{
     212        ipc_answer_0(callid, ENOENT);
     213}
    164214
    165215/**
     
    167217 */
    168218static async_client_conn_t client_connection = default_client_connection;
     219
     220/** Default fibril function that gets called to handle interrupt notifications.
     221 *
     222 * This function is defined as a weak symbol - to be redefined in user code.
     223 *
     224 * @param callid Hash of the incoming call.
     225 * @param call   Data of the incoming call.
     226 *
     227 */
     228static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call)
     229{
     230}
    169231
    170232/**
     
    174236static async_client_conn_t interrupt_received = default_interrupt_received;
    175237
     238static hash_table_t client_hash_table;
    176239static hash_table_t conn_hash_table;
    177240static LIST_INITIALIZE(timeout_list);
    178241
    179 #define CONN_HASH_TABLE_CHAINS  32
     242#define CLIENT_HASH_TABLE_BUCKETS  32
     243#define CONN_HASH_TABLE_BUCKETS    32
     244
     245static hash_index_t client_hash(unsigned long key[])
     246{
     247        assert(key);
     248        return (((key[0]) >> 4) % CLIENT_HASH_TABLE_BUCKETS);
     249}
     250
     251static int client_compare(unsigned long key[], hash_count_t keys, link_t *item)
     252{
     253        client_t *client = hash_table_get_instance(item, client_t, link);
     254        return (key[0] == client->in_task_hash);
     255}
     256
     257static void client_remove(link_t *item)
     258{
     259}
     260
     261/** Operations for the client hash table. */
     262static hash_table_operations_t client_hash_table_ops = {
     263        .hash = client_hash,
     264        .compare = client_compare,
     265        .remove_callback = client_remove
     266};
    180267
    181268/** Compute hash into the connection hash table based on the source phone hash.
     
    186273 *
    187274 */
    188 static hash_index_t conn_hash(unsigned long *key)
     275static hash_index_t conn_hash(unsigned long key[])
    189276{
    190277        assert(key);
    191         return (((*key) >> 4) % CONN_HASH_TABLE_CHAINS);
     278        return (((key[0]) >> 4) % CONN_HASH_TABLE_BUCKETS);
    192279}
    193280
     
    203290static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item)
    204291{
    205         connection_t *hs = hash_table_get_instance(item, connection_t, link);
    206         return (key[0] == hs->in_phone_hash);
     292        connection_t *conn = hash_table_get_instance(item, connection_t, link);
     293        return (key[0] == conn->in_phone_hash);
    207294}
    208295
     
    219306        free(hash_table_get_instance(item, connection_t, link));
    220307}
    221 
    222308
    223309/** Operations for the connection hash table. */
     
    240326        link_t *tmp = timeout_list.next;
    241327        while (tmp != &timeout_list) {
    242                 awaiter_t *cur;
    243                
    244                 cur = list_get_instance(tmp, awaiter_t, to_event.link);
     328                awaiter_t *cur
     329                    = list_get_instance(tmp, awaiter_t, to_event.link);
     330               
    245331                if (tv_gteq(&cur->to_event.expires, &wd->to_event.expires))
    246332                        break;
     333               
    247334                tmp = tmp->next;
    248335        }
     
    261348 *
    262349 * @return False if the call doesn't match any connection.
    263  *         True if the call was passed to the respective connection fibril.
     350 * @return True if the call was passed to the respective connection fibril.
    264351 *
    265352 */
     
    352439       
    353440        fid_t fid = fibril_create(notification_fibril, msg);
     441        if (fid == 0) {
     442                free(msg);
     443                futex_up(&async_futex);
     444                return false;
     445        }
     446       
    354447        fibril_add_ready(fid);
    355448       
     
    398491                         * the first IPC_M_PHONE_HUNGUP call and continues to
    399492                         * call async_get_call_timeout(). Repeat
    400                          * IPC_M_PHONE_HUNGUP until the caller notices. 
     493                         * IPC_M_PHONE_HUNGUP until the caller notices.
    401494                         */
    402495                        memset(call, 0, sizeof(ipc_call_t));
     
    405498                        return conn->close_callid;
    406499                }
    407 
     500               
    408501                if (usecs)
    409502                        async_insert_timeout(&conn->wdata);
     
    443536}
    444537
    445 /** Default fibril function that gets called to handle new connection.
    446  *
    447  * This function is defined as a weak symbol - to be redefined in user code.
    448  *
    449  * @param callid Hash of the incoming call.
    450  * @param call   Data of the incoming call.
    451  *
    452  */
    453 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call)
    454 {
    455         ipc_answer_0(callid, ENOENT);
    456 }
    457 
    458 /** Default fibril function that gets called to handle interrupt notifications.
    459  *
    460  * This function is defined as a weak symbol - to be redefined in user code.
    461  *
    462  * @param callid Hash of the incoming call.
    463  * @param call   Data of the incoming call.
    464  *
    465  */
    466 static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call)
    467 {
    468 }
    469 
    470538/** Wrapper for client connection fibril.
    471539 *
     
    481549{
    482550        /*
    483          * Setup fibril-local connection pointer and call client_connection().
    484          *
     551         * Setup fibril-local connection pointer.
    485552         */
    486553        FIBRIL_connection = (connection_t *) arg;
     554       
     555        futex_down(&async_futex);
     556       
     557        /*
     558         * Add our reference for the current connection in the client task
     559         * tracking structure. If this is the first reference, create and
     560         * hash in a new tracking structure.
     561         */
     562       
     563        unsigned long key = FIBRIL_connection->in_task_hash;
     564        link_t *lnk = hash_table_find(&client_hash_table, &key);
     565       
     566        client_t *client;
     567       
     568        if (lnk) {
     569                client = hash_table_get_instance(lnk, client_t, link);
     570                client->refcnt++;
     571        } else {
     572                client = malloc(sizeof(client_t));
     573                if (!client) {
     574                        ipc_answer_0(FIBRIL_connection->callid, ENOMEM);
     575                        futex_up(&async_futex);
     576                        return 0;
     577                }
     578               
     579                client->in_task_hash = FIBRIL_connection->in_task_hash;
     580               
     581                async_serialize_start();
     582                client->data = async_client_data_create();
     583                async_serialize_end();
     584               
     585                client->refcnt = 1;
     586                hash_table_insert(&client_hash_table, &key, &client->link);
     587        }
     588       
     589        futex_up(&async_futex);
     590       
     591        FIBRIL_connection->client = client;
     592       
     593        /*
     594         * Call the connection handler function.
     595         */
    487596        FIBRIL_connection->cfibril(FIBRIL_connection->callid,
    488597            &FIBRIL_connection->call);
    489598       
    490         /* Remove myself from the connection hash table */
     599        /*
     600         * Remove the reference for this client task connection.
     601         */
     602        bool destroy;
     603       
    491604        futex_down(&async_futex);
    492         unsigned long key = FIBRIL_connection->in_phone_hash;
     605       
     606        if (--client->refcnt == 0) {
     607                hash_table_remove(&client_hash_table, &key, 1);
     608                destroy = true;
     609        } else
     610                destroy = false;
     611       
     612        futex_up(&async_futex);
     613       
     614        if (destroy) {
     615                if (client->data)
     616                        async_client_data_destroy(client->data);
     617               
     618                free(client);
     619        }
     620       
     621        /*
     622         * Remove myself from the connection hash table.
     623         */
     624        futex_down(&async_futex);
     625        key = FIBRIL_connection->in_phone_hash;
    493626        hash_table_remove(&conn_hash_table, &key, 1);
    494627        futex_up(&async_futex);
    495628       
    496         /* Answer all remaining messages with EHANGUP */
     629        /*
     630         * Answer all remaining messages with EHANGUP.
     631         */
    497632        while (!list_empty(&FIBRIL_connection->msg_queue)) {
    498                 msg_t *msg;
    499                
    500                 msg = list_get_instance(FIBRIL_connection->msg_queue.next,
    501                     msg_t, link);
     633                msg_t *msg =
     634                    list_get_instance(FIBRIL_connection->msg_queue.next, msg_t,
     635                    link);
     636               
    502637                list_remove(&msg->link);
    503638                ipc_answer_0(msg->callid, EHANGUP);
     
    505640        }
    506641       
     642        /*
     643         * If the connection was hung-up, answer the last call,
     644         * i.e. IPC_M_PHONE_HUNGUP.
     645         */
    507646        if (FIBRIL_connection->close_callid)
    508647                ipc_answer_0(FIBRIL_connection->close_callid, EOK);
     
    517656 * particular fibrils.
    518657 *
     658 * @param in_task_hash  Identification of the incoming connection.
    519659 * @param in_phone_hash Identification of the incoming connection.
    520660 * @param callid        Hash of the opening IPC_M_CONNECT_ME_TO call.
     
    529669 *
    530670 */
    531 fid_t async_new_connection(sysarg_t in_phone_hash, ipc_callid_t callid,
    532     ipc_call_t *call, void (*cfibril)(ipc_callid_t, ipc_call_t *))
     671fid_t async_new_connection(sysarg_t in_task_hash, sysarg_t in_phone_hash,
     672    ipc_callid_t callid, ipc_call_t *call,
     673    void (*cfibril)(ipc_callid_t, ipc_call_t *))
    533674{
    534675        connection_t *conn = malloc(sizeof(*conn));
     
    536677                if (callid)
    537678                        ipc_answer_0(callid, ENOMEM);
     679               
    538680                return (uintptr_t) NULL;
    539681        }
    540682       
     683        conn->in_task_hash = in_task_hash;
    541684        conn->in_phone_hash = in_phone_hash;
    542685        list_initialize(&conn->msg_queue);
     
    552695        conn->wdata.fid = fibril_create(connection_fibril, conn);
    553696       
    554         if (!conn->wdata.fid) {
     697        if (conn->wdata.fid == 0) {
    555698                free(conn);
     699               
    556700                if (callid)
    557701                        ipc_answer_0(callid, ENOMEM);
     702               
    558703                return (uintptr_t) NULL;
    559704        }
     
    582727static void handle_call(ipc_callid_t callid, ipc_call_t *call)
    583728{
    584         /* Unrouted call - do some default behaviour */
     729        /* Unrouted call - take some default action */
    585730        if ((callid & IPC_CALLID_NOTIFICATION)) {
    586731                process_notification(callid, call);
    587                 goto out;
     732                return;
    588733        }
    589734       
     
    591736        case IPC_M_CONNECT_ME:
    592737        case IPC_M_CONNECT_ME_TO:
    593                 /* Open new connection with fibril etc. */
    594                 async_new_connection(IPC_GET_ARG5(*call), callid, call,
    595                     client_connection);
    596                 goto out;
     738                /* Open new connection with fibril, etc. */
     739                async_new_connection(call->in_task_hash, IPC_GET_ARG5(*call),
     740                    callid, call, client_connection);
     741                return;
    597742        }
    598743       
    599744        /* Try to route the call through the connection hash table */
    600745        if (route_call(callid, call))
    601                 goto out;
     746                return;
    602747       
    603748        /* Unknown call from unknown phone - hang it up */
    604749        ipc_answer_0(callid, EHANGUP);
    605         return;
    606        
    607 out:
    608         ;
    609750}
    610751
     
    619760        link_t *cur = timeout_list.next;
    620761        while (cur != &timeout_list) {
    621                 awaiter_t *waiter;
    622                
    623                 waiter = list_get_instance(cur, awaiter_t, to_event.link);
     762                awaiter_t *waiter =
     763                    list_get_instance(cur, awaiter_t, to_event.link);
     764               
    624765                if (tv_gt(&waiter->to_event.expires, &tv))
    625766                        break;
    626 
     767               
    627768                cur = cur->next;
    628 
     769               
    629770                list_remove(&waiter->to_event.link);
    630771                waiter->to_event.inlist = false;
     
    653794        while (true) {
    654795                if (fibril_switch(FIBRIL_FROM_MANAGER)) {
    655                         futex_up(&async_futex); 
     796                        futex_up(&async_futex);
    656797                        /*
    657798                         * async_futex is always held when entering a manager
     
    676817                                continue;
    677818                        } else
    678                                 timeout = tv_sub(&waiter->to_event.expires,
    679                                     &tv);
     819                                timeout = tv_sub(&waiter->to_event.expires, &tv);
    680820                } else
    681821                        timeout = SYNCH_NO_TIMEOUT;
    682822               
    683823                futex_up(&async_futex);
    684 
     824               
    685825                atomic_inc(&threads_in_ipc_wait);
    686826               
     
    690830               
    691831                atomic_dec(&threads_in_ipc_wait);
    692 
     832               
    693833                if (!callid) {
    694834                        handle_expired_timeouts();
     
    729869{
    730870        fid_t fid = fibril_create(async_manager_fibril, NULL);
    731         fibril_add_manager(fid);
     871        if (fid != 0)
     872                fibril_add_manager(fid);
    732873}
    733874
     
    740881/** Initialize the async framework.
    741882 *
    742  * @return Zero on success or an error code.
    743  */
    744 int __async_init(void)
    745 {
    746         if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_CHAINS, 1,
    747             &conn_hash_table_ops)) {
    748                 printf("%s: Cannot create async hash table\n", "libc");
    749                 return ENOMEM;
    750         }
    751 
    752         _async_sess_init();
    753        
    754         return 0;
     883 */
     884void __async_init(void)
     885{
     886        if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 1,
     887            &client_hash_table_ops))
     888                abort();
     889       
     890        if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS, 1,
     891            &conn_hash_table_ops))
     892                abort();
    755893}
    756894
     
    765903 * @param retval Value returned in the answer.
    766904 * @param data   Call data of the answer.
     905 *
    767906 */
    768907static void reply_received(void *arg, int retval, ipc_call_t *data)
     
    812951    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
    813952{
    814         amsg_t *msg = malloc(sizeof(*msg));
     953        amsg_t *msg = malloc(sizeof(amsg_t));
    815954       
    816955        if (!msg)
     
    821960       
    822961        msg->wdata.to_event.inlist = false;
    823         /* We may sleep in the next method, but it will use its own mechanism */
     962       
     963        /*
     964         * We may sleep in the next method,
     965         * but it will use its own means
     966         */
    824967        msg->wdata.active = true;
    825968       
     
    852995    ipc_call_t *dataptr)
    853996{
    854         amsg_t *msg = malloc(sizeof(*msg));
     997        amsg_t *msg = malloc(sizeof(amsg_t));
    855998       
    856999        if (!msg)
     
    8611004       
    8621005        msg->wdata.to_event.inlist = false;
    863         /* We may sleep in next method, but it will use its own mechanism */
     1006       
     1007        /*
     1008         * We may sleep in the next method,
     1009         * but it will use its own means
     1010         */
    8641011        msg->wdata.active = true;
    8651012       
     
    9601107void async_usleep(suseconds_t timeout)
    9611108{
    962         amsg_t *msg = malloc(sizeof(*msg));
     1109        amsg_t *msg = malloc(sizeof(amsg_t));
    9631110       
    9641111        if (!msg)
     
    11031250}
    11041251
     1252void async_msg_0(int phone, sysarg_t imethod)
     1253{
     1254        ipc_call_async_0(phone, imethod, NULL, NULL, true);
     1255}
     1256
     1257void async_msg_1(int phone, sysarg_t imethod, sysarg_t arg1)
     1258{
     1259        ipc_call_async_1(phone, imethod, arg1, NULL, NULL, true);
     1260}
     1261
     1262void async_msg_2(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2)
     1263{
     1264        ipc_call_async_2(phone, imethod, arg1, arg2, NULL, NULL, true);
     1265}
     1266
     1267void async_msg_3(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
     1268    sysarg_t arg3)
     1269{
     1270        ipc_call_async_3(phone, imethod, arg1, arg2, arg3, NULL, NULL, true);
     1271}
     1272
     1273void async_msg_4(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
     1274    sysarg_t arg3, sysarg_t arg4)
     1275{
     1276        ipc_call_async_4(phone, imethod, arg1, arg2, arg3, arg4, NULL, NULL,
     1277            true);
     1278}
     1279
     1280void async_msg_5(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
     1281    sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
     1282{
     1283        ipc_call_async_5(phone, imethod, arg1, arg2, arg3, arg4, arg5, NULL,
     1284            NULL, true);
     1285}
     1286
     1287sysarg_t async_answer_0(ipc_callid_t callid, sysarg_t retval)
     1288{
     1289        return ipc_answer_0(callid, retval);
     1290}
     1291
     1292sysarg_t async_answer_1(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1)
     1293{
     1294        return ipc_answer_1(callid, retval, arg1);
     1295}
     1296
     1297sysarg_t async_answer_2(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     1298    sysarg_t arg2)
     1299{
     1300        return ipc_answer_2(callid, retval, arg1, arg2);
     1301}
     1302
     1303sysarg_t async_answer_3(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     1304    sysarg_t arg2, sysarg_t arg3)
     1305{
     1306        return ipc_answer_3(callid, retval, arg1, arg2, arg3);
     1307}
     1308
     1309sysarg_t async_answer_4(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     1310    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
     1311{
     1312        return ipc_answer_4(callid, retval, arg1, arg2, arg3, arg4);
     1313}
     1314
     1315sysarg_t async_answer_5(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     1316    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
     1317{
     1318        return ipc_answer_5(callid, retval, arg1, arg2, arg3, arg4, arg5);
     1319}
     1320
     1321int async_forward_fast(ipc_callid_t callid, int phoneid, sysarg_t imethod,
     1322    sysarg_t arg1, sysarg_t arg2, unsigned int mode)
     1323{
     1324        return ipc_forward_fast(callid, phoneid, imethod, arg1, arg2, mode);
     1325}
     1326
     1327int async_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod,
     1328    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
     1329    unsigned int mode)
     1330{
     1331        return ipc_forward_slow(callid, phoneid, imethod, arg1, arg2, arg3, arg4,
     1332            arg5, mode);
     1333}
     1334
     1335/** Wrapper for making IPC_M_CONNECT_TO_ME calls using the async framework.
     1336 *
     1337 * Ask through phone for a new connection to some service.
     1338 *
     1339 * @param phone           Phone handle used for contacting the other side.
     1340 * @param arg1            User defined argument.
     1341 * @param arg2            User defined argument.
     1342 * @param arg3            User defined argument.
     1343 * @param client_receiver Connection handing routine.
     1344 *
     1345 * @return New phone handle on success or a negative error code.
     1346 *
     1347 */
     1348int async_connect_to_me(int phone, sysarg_t arg1, sysarg_t arg2,
     1349    sysarg_t arg3, async_client_conn_t client_receiver)
     1350{
     1351        sysarg_t task_hash;
     1352        sysarg_t phone_hash;
     1353        int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
     1354            NULL, NULL, NULL, &task_hash, &phone_hash);
     1355        if (rc != EOK)
     1356                return rc;
     1357       
     1358        if (client_receiver != NULL)
     1359                async_new_connection(task_hash, phone_hash, 0, NULL,
     1360                    client_receiver);
     1361       
     1362        return EOK;
     1363}
     1364
    11051365/** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
    1106  * 
     1366 *
    11071367 * Ask through phone for a new connection to some service.
    11081368 *
    1109  * @param phoneid       Phone handle used for contacting the other side.
    1110  * @param arg1          User defined argument.
    1111  * @param arg2          User defined argument.
    1112  * @param arg3          User defined argument.
    1113  *
    1114  * @return              New phone handle on success or a negative error code.
    1115  */
    1116 int
    1117 async_connect_me_to(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
    1118 {
    1119         int rc;
     1369 * @param phone Phone handle used for contacting the other side.
     1370 * @param arg1  User defined argument.
     1371 * @param arg2  User defined argument.
     1372 * @param arg3  User defined argument.
     1373 *
     1374 * @return New phone handle on success or a negative error code.
     1375 *
     1376 */
     1377int async_connect_me_to(int phone, sysarg_t arg1, sysarg_t arg2,
     1378    sysarg_t arg3)
     1379{
    11201380        sysarg_t newphid;
    1121 
    1122         rc = async_req_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, NULL,
    1123             NULL, NULL, NULL, &newphid);
    1124        
    1125         if (rc != EOK) 
     1381        int rc = async_req_3_5(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     1382            NULL, NULL, NULL, NULL, &newphid);
     1383       
     1384        if (rc != EOK)
    11261385                return rc;
    1127 
     1386       
    11281387        return newphid;
    11291388}
    11301389
    11311390/** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
    1132  * 
     1391 *
    11331392 * Ask through phone for a new connection to some service and block until
    11341393 * success.
    11351394 *
    1136  * @param phoneid       Phone handle used for contacting the other side.
    1137  * @param arg1          User defined argument.
    1138  * @param arg2          User defined argument.
    1139  * @param arg3          User defined argument.
    1140  *
    1141  * @return              New phone handle on success or a negative error code.
    1142  */
    1143 int
    1144 async_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,
     1395 * @param phoneid Phone handle used for contacting the other side.
     1396 * @param arg1    User defined argument.
     1397 * @param arg2    User defined argument.
     1398 * @param arg3    User defined argument.
     1399 *
     1400 * @return New phone handle on success or a negative error code.
     1401 *
     1402 */
     1403int async_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,
    11451404    sysarg_t arg3)
    11461405{
    1147         int rc;
    11481406        sysarg_t newphid;
    1149 
    1150         rc = async_req_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     1407        int rc = async_req_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
    11511408            IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
    11521409       
    1153         if (rc != EOK) 
     1410        if (rc != EOK)
    11541411                return rc;
    1155 
     1412       
    11561413        return newphid;
    11571414}
    11581415
    1159 /** Wrapper for making IPC_M_SHARE_IN calls using the async framework.
    1160  *
    1161  * @param phoneid       Phone that will be used to contact the receiving side.
    1162  * @param dst           Destination address space area base.
    1163  * @param size          Size of the destination address space area.
    1164  * @param arg           User defined argument.
    1165  * @param flags         Storage where the received flags will be stored. Can be
    1166  *                      NULL.
    1167  *
    1168  * @return              Zero on success or a negative error code from errno.h.
     1416/** Connect to a task specified by id.
     1417 *
     1418 */
     1419int async_connect_kbox(task_id_t id)
     1420{
     1421        return ipc_connect_kbox(id);
     1422}
     1423
     1424/** Wrapper for ipc_hangup.
     1425 *
     1426 * @param phone Phone handle to hung up.
     1427 *
     1428 * @return Zero on success or a negative error code.
     1429 *
     1430 */
     1431int async_hangup(int phone)
     1432{
     1433        return ipc_hangup(phone);
     1434}
     1435
     1436/** Interrupt one thread of this task from waiting for IPC. */
     1437void async_poke(void)
     1438{
     1439        ipc_poke();
     1440}
     1441
     1442/** Wrapper for IPC_M_SHARE_IN calls using the async framework.
     1443 *
     1444 * @param phoneid Phone that will be used to contact the receiving side.
     1445 * @param dst     Destination address space area base.
     1446 * @param size    Size of the destination address space area.
     1447 * @param arg     User defined argument.
     1448 * @param flags   Storage for the received flags. Can be NULL.
     1449 *
     1450 * @return Zero on success or a negative error code from errno.h.
     1451 *
    11691452 */
    11701453int async_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg,
    1171     int *flags)
    1172 {
    1173         int res;
     1454    unsigned int *flags)
     1455{
    11741456        sysarg_t tmp_flags;
    1175         res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,
     1457        int res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,
    11761458            (sysarg_t) size, arg, NULL, &tmp_flags);
     1459       
    11771460        if (flags)
    1178                 *flags = tmp_flags;
     1461                *flags = (unsigned int) tmp_flags;
     1462       
    11791463        return res;
    11801464}
     
    11821466/** Wrapper for receiving the IPC_M_SHARE_IN calls using the async framework.
    11831467 *
    1184  * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN calls
    1185  * so that the user doesn't have to remember the meaning of each IPC argument.
     1468 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN
     1469 * calls so that the user doesn't have to remember the meaning of each IPC
     1470 * argument.
    11861471 *
    11871472 * So far, this wrapper is to be used from within a connection fibril.
    11881473 *
    1189  * @param callid        Storage where the hash of the IPC_M_SHARE_IN call will
    1190  *                      be stored.
    1191  * @param size          Destination address space area size.   
    1192  *
    1193  * @return              Non-zero on success, zero on failure.
    1194  */
    1195 int async_share_in_receive(ipc_callid_t *callid, size_t *size)
    1196 {
    1197         ipc_call_t data;
    1198        
     1474 * @param callid Storage for the hash of the IPC_M_SHARE_IN call.
     1475 * @param size   Destination address space area size.
     1476 *
     1477 * @return True on success, false on failure.
     1478 *
     1479 */
     1480bool async_share_in_receive(ipc_callid_t *callid, size_t *size)
     1481{
    11991482        assert(callid);
    12001483        assert(size);
    1201 
     1484       
     1485        ipc_call_t data;
    12021486        *callid = async_get_call(&data);
     1487       
    12031488        if (IPC_GET_IMETHOD(data) != IPC_M_SHARE_IN)
    1204                 return 0;
     1489                return false;
     1490       
    12051491        *size = (size_t) IPC_GET_ARG2(data);
    1206         return 1;
     1492        return true;
    12071493}
    12081494
    12091495/** Wrapper for answering the IPC_M_SHARE_IN calls using the async framework.
    12101496 *
    1211  * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
    1212  * so that the user doesn't have to remember the meaning of each IPC argument.
    1213  *
    1214  * @param callid        Hash of the IPC_M_DATA_READ call to answer.
    1215  * @param src           Source address space base.
    1216  * @param flags         Flags to be used for sharing. Bits can be only cleared.
    1217  *
    1218  * @return              Zero on success or a value from @ref errno.h on failure.
    1219  */
    1220 int async_share_in_finalize(ipc_callid_t callid, void *src, int flags)
     1497 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ
     1498 * calls so that the user doesn't have to remember the meaning of each IPC
     1499 * argument.
     1500 *
     1501 * @param callid Hash of the IPC_M_DATA_READ call to answer.
     1502 * @param src    Source address space base.
     1503 * @param flags  Flags to be used for sharing. Bits can be only cleared.
     1504 *
     1505 * @return Zero on success or a value from @ref errno.h on failure.
     1506 *
     1507 */
     1508int async_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags)
    12211509{
    12221510        return ipc_share_in_finalize(callid, src, flags);
    12231511}
    12241512
    1225 /** Wrapper for making IPC_M_SHARE_OUT calls using the async framework.
    1226  *
    1227  * @param phoneid       Phone that will be used to contact the receiving side.
    1228  * @param src           Source address space area base address.
    1229  * @param flags         Flags to be used for sharing. Bits can be only cleared.
    1230  *
    1231  * @return              Zero on success or a negative error code from errno.h.
    1232  */
    1233 int async_share_out_start(int phoneid, void *src, int flags)
     1513/** Wrapper for IPC_M_SHARE_OUT calls using the async framework.
     1514 *
     1515 * @param phoneid Phone that will be used to contact the receiving side.
     1516 * @param src     Source address space area base address.
     1517 * @param flags   Flags to be used for sharing. Bits can be only cleared.
     1518 *
     1519 * @return Zero on success or a negative error code from errno.h.
     1520 *
     1521 */
     1522int async_share_out_start(int phoneid, void *src, unsigned int flags)
    12341523{
    12351524        return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
     
    12391528/** Wrapper for receiving the IPC_M_SHARE_OUT calls using the async framework.
    12401529 *
    1241  * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT calls
    1242  * so that the user doesn't have to remember the meaning of each IPC argument.
     1530 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT
     1531 * calls so that the user doesn't have to remember the meaning of each IPC
     1532 * argument.
    12431533 *
    12441534 * So far, this wrapper is to be used from within a connection fibril.
    12451535 *
    1246  * @param callid        Storage where the hash of the IPC_M_SHARE_OUT call will
    1247  *                      be stored.
    1248  * @param size          Storage where the source address space area size will be
    1249  *                      stored.
    1250  * @param flags         Storage where the sharing flags will be stored.
    1251  *
    1252  * @return              Non-zero on success, zero on failure.
    1253  */
    1254 int async_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags)
    1255 {
    1256         ipc_call_t data;
    1257        
     1536 * @param callid Storage for the hash of the IPC_M_SHARE_OUT call.
     1537 * @param size   Storage for the source address space area size.
     1538 * @param flags  Storage for the sharing flags.
     1539 *
     1540 * @return True on success, false on failure.
     1541 *
     1542 */
     1543bool async_share_out_receive(ipc_callid_t *callid, size_t *size, unsigned int *flags)
     1544{
    12581545        assert(callid);
    12591546        assert(size);
    12601547        assert(flags);
    1261 
     1548       
     1549        ipc_call_t data;
    12621550        *callid = async_get_call(&data);
     1551       
    12631552        if (IPC_GET_IMETHOD(data) != IPC_M_SHARE_OUT)
    1264                 return 0;
     1553                return false;
     1554       
    12651555        *size = (size_t) IPC_GET_ARG2(data);
    1266         *flags = (int) IPC_GET_ARG3(data);
    1267         return 1;
     1556        *flags = (unsigned int) IPC_GET_ARG3(data);
     1557        return true;
    12681558}
    12691559
    12701560/** Wrapper for answering the IPC_M_SHARE_OUT calls using the async framework.
    12711561 *
    1272  * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT calls
    1273  * so that the user doesn't have to remember the meaning of each IPC argument.
    1274  *
    1275  * @param callid        Hash of the IPC_M_DATA_WRITE call to answer.
    1276  * @param dst           Destination address space area base address.   
    1277  *
    1278  * @return              Zero on success or a value from @ref errno.h on failure.
     1562 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT
     1563 * calls so that the user doesn't have to remember the meaning of each IPC
     1564 * argument.
     1565 *
     1566 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.
     1567 * @param dst    Destination address space area base address.
     1568 *
     1569 * @return Zero on success or a value from @ref errno.h on failure.
     1570 *
    12791571 */
    12801572int async_share_out_finalize(ipc_callid_t callid, void *dst)
     
    12831575}
    12841576
    1285 
    1286 /** Wrapper for making IPC_M_DATA_READ calls using the async framework.
    1287  *
    1288  * @param phoneid       Phone that will be used to contact the receiving side.
    1289  * @param dst           Address of the beginning of the destination buffer.
    1290  * @param size          Size of the destination buffer.
    1291  *
    1292  * @return              Zero on success or a negative error code from errno.h.
     1577/** Wrapper for IPC_M_DATA_READ calls using the async framework.
     1578 *
     1579 * @param phoneid Phone that will be used to contact the receiving side.
     1580 * @param dst     Address of the beginning of the destination buffer.
     1581 * @param size    Size of the destination buffer.
     1582 *
     1583 * @return Zero on success or a negative error code from errno.h.
     1584 *
    12931585 */
    12941586int async_data_read_start(int phoneid, void *dst, size_t size)
     
    13001592/** Wrapper for receiving the IPC_M_DATA_READ calls using the async framework.
    13011593 *
    1302  * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ calls
    1303  * so that the user doesn't have to remember the meaning of each IPC argument.
     1594 * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ
     1595 * calls so that the user doesn't have to remember the meaning of each IPC
     1596 * argument.
    13041597 *
    13051598 * So far, this wrapper is to be used from within a connection fibril.
    13061599 *
    1307  * @param callid        Storage where the hash of the IPC_M_DATA_READ call will
    1308  *                      be stored.
    1309  * @param size          Storage where the maximum size will be stored. Can be
    1310  *                      NULL.
    1311  *
    1312  * @return              Non-zero on success, zero on failure.
    1313  */
    1314 int async_data_read_receive(ipc_callid_t *callid, size_t *size)
    1315 {
     1600 * @param callid Storage for the hash of the IPC_M_DATA_READ.
     1601 * @param size   Storage for the maximum size. Can be NULL.
     1602 *
     1603 * @return True on success, false on failure.
     1604 *
     1605 */
     1606bool async_data_read_receive(ipc_callid_t *callid, size_t *size)
     1607{
     1608        assert(callid);
     1609       
    13161610        ipc_call_t data;
    1317        
    1318         assert(callid);
    1319 
    13201611        *callid = async_get_call(&data);
     1612       
    13211613        if (IPC_GET_IMETHOD(data) != IPC_M_DATA_READ)
    1322                 return 0;
     1614                return false;
     1615       
    13231616        if (size)
    13241617                *size = (size_t) IPC_GET_ARG2(data);
    1325         return 1;
     1618       
     1619        return true;
    13261620}
    13271621
    13281622/** Wrapper for answering the IPC_M_DATA_READ calls using the async framework.
    13291623 *
    1330  * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
    1331  * so that the user doesn't have to remember the meaning of each IPC argument.
    1332  *
    1333  * @param callid        Hash of the IPC_M_DATA_READ call to answer.
    1334  * @param src           Source address for the IPC_M_DATA_READ call.
    1335  * @param size          Size for the IPC_M_DATA_READ call. Can be smaller than
    1336  *                      the maximum size announced by the sender.
    1337  *
    1338  * @return              Zero on success or a value from @ref errno.h on failure.
     1624 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ
     1625 * calls so that the user doesn't have to remember the meaning of each IPC
     1626 * argument.
     1627 *
     1628 * @param callid Hash of the IPC_M_DATA_READ call to answer.
     1629 * @param src    Source address for the IPC_M_DATA_READ call.
     1630 * @param size   Size for the IPC_M_DATA_READ call. Can be smaller than
     1631 *               the maximum size announced by the sender.
     1632 *
     1633 * @return Zero on success or a value from @ref errno.h on failure.
     1634 *
    13391635 */
    13401636int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
     
    13441640
    13451641/** Wrapper for forwarding any read request
    1346  *
    13471642 *
    13481643 */
     
    13771672}
    13781673
    1379 /** Wrapper for making IPC_M_DATA_WRITE calls using the async framework.
     1674/** Wrapper for IPC_M_DATA_WRITE calls using the async framework.
    13801675 *
    13811676 * @param phoneid Phone that will be used to contact the receiving side.
     
    13941689/** Wrapper for receiving the IPC_M_DATA_WRITE calls using the async framework.
    13951690 *
    1396  * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE calls
    1397  * so that the user doesn't have to remember the meaning of each IPC argument.
     1691 * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE
     1692 * calls so that the user doesn't have to remember the meaning of each IPC
     1693 * argument.
    13981694 *
    13991695 * So far, this wrapper is to be used from within a connection fibril.
    14001696 *
    1401  * @param callid Storage where the hash of the IPC_M_DATA_WRITE call will
    1402  *               be stored.
    1403  * @param size   Storage where the suggested size will be stored. May be
    1404  *               NULL
    1405  *
    1406  * @return Non-zero on success, zero on failure.
    1407  *
    1408  */
    1409 int async_data_write_receive(ipc_callid_t *callid, size_t *size)
    1410 {
     1697 * @param callid Storage for the hash of the IPC_M_DATA_WRITE.
     1698 * @param size   Storage for the suggested size. May be NULL.
     1699 *
     1700 * @return True on success, false on failure.
     1701 *
     1702 */
     1703bool async_data_write_receive(ipc_callid_t *callid, size_t *size)
     1704{
     1705        assert(callid);
     1706       
    14111707        ipc_call_t data;
    1412        
    1413         assert(callid);
    1414        
    14151708        *callid = async_get_call(&data);
     1709       
    14161710        if (IPC_GET_IMETHOD(data) != IPC_M_DATA_WRITE)
    1417                 return 0;
     1711                return false;
    14181712       
    14191713        if (size)
    14201714                *size = (size_t) IPC_GET_ARG2(data);
    14211715       
    1422         return 1;
     1716        return true;
    14231717}
    14241718
    14251719/** Wrapper for answering the IPC_M_DATA_WRITE calls using the async framework.
    14261720 *
    1427  * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE calls
    1428  * so that the user doesn't have to remember the meaning of each IPC argument.
     1721 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE
     1722 * calls so that the user doesn't have to remember the meaning of each IPC
     1723 * argument.
    14291724 *
    14301725 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.
     
    15221817 *
    15231818 */
    1524 void async_data_write_void(const int retval)
     1819void async_data_write_void(sysarg_t retval)
    15251820{
    15261821        ipc_callid_t callid;
     
    15301825
    15311826/** Wrapper for forwarding any data that is about to be received
    1532  *
    15331827 *
    15341828 */
  • uspace/lib/c/generic/async_sess.c

    r22027b6e r8b5690f  
    9999
    100100#include <async_sess.h>
    101 #include <ipc/ipc.h>
    102101#include <fibril_synch.h>
    103102#include <adt/list.h>
     
    106105#include <errno.h>
    107106#include <assert.h>
     107#include "private/async_sess.h"
    108108
    109109/** An inactive open connection. */
    110110typedef struct {
    111111        link_t sess_link;       /**< Link for the session list of inactive connections. */
    112         link_t global_link;     /**< Link for the global list of inactive connectinos. */
     112        link_t global_link;     /**< Link for the global list of inactive connections. */
    113113        int data_phone;         /**< Connected data phone. */
    114114} conn_node_t;
    115115
    116116/**
    117  * Mutex protecting the inactive_conn_head list and the session list.
     117 * Mutex protecting the inactive_conn_head list, the session list and the
     118 * avail_phone condition variable.
    118119 */
    119120static fibril_mutex_t async_sess_mutex;
     
    129130static LIST_INITIALIZE(session_list_head);
    130131
     132/**
     133 * Condition variable used to wait for a phone to become available.
     134 */
     135static FIBRIL_CONDVAR_INITIALIZE(avail_phone_cv);
     136
    131137/** Initialize the async_sess subsystem.
    132138 *
    133139 * Needs to be called prior to any other interface in this file.
    134  */
    135 void _async_sess_init(void)
     140 *
     141 */
     142void __async_sess_init(void)
    136143{
    137144        fibril_mutex_initialize(&async_sess_mutex);
     
    194201                list_remove(&conn->global_link);
    195202               
    196                 ipc_hangup(conn->data_phone);
     203                async_hangup(conn->data_phone);
    197204                free(conn);
    198205        }
     206       
     207        fibril_condvar_broadcast(&avail_phone_cv);
    199208}
    200209
     
    252261                        data_phone = conn->data_phone;
    253262                        free(conn);
    254                         ipc_hangup(data_phone);
     263                        async_hangup(data_phone);
    255264                        goto retry;
    256265                } else {
    257266                        /*
    258                          * This is unfortunate. We failed both to find a cached
    259                          * connection or to create a new one even after cleaning up
    260                          * the cache. This is most likely due to too many
    261                          * open sessions (connected session phones).
     267                         * Wait for a phone to become available.
    262268                         */
    263                         data_phone = ELIMIT;
     269                        fibril_condvar_wait(&avail_phone_cv, &async_sess_mutex);
     270                        goto retry;
    264271                }
    265272        }
     
    279286
    280287        fibril_mutex_lock(&async_sess_mutex);
     288        fibril_condvar_signal(&avail_phone_cv);
    281289        conn = (conn_node_t *) malloc(sizeof(conn_node_t));
    282290        if (!conn) {
     
    285293                 * means that we simply hang up.
    286294                 */
     295                async_hangup(data_phone);
    287296                fibril_mutex_unlock(&async_sess_mutex);
    288                 ipc_hangup(data_phone);
    289297                return;
    290298        }
  • uspace/lib/c/generic/clipboard.c

    r22027b6e r8b5690f  
    3939
    4040#include <clipboard.h>
     41#include <ipc/ns.h>
    4142#include <ipc/services.h>
    4243#include <ipc/clipboard.h>
     
    5455{
    5556        while (clip_phone < 0)
    56                 clip_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_CLIPBOARD, 0, 0);
     57                clip_phone = service_connect_blocking(SERVICE_CLIPBOARD, 0, 0);
    5758}
    5859
  • uspace/lib/c/generic/ddi.c

    r22027b6e r8b5690f  
    9696}
    9797
    98 /** Enable an interrupt.
    99  *
    100  * @param irq the interrupt.
    101  *
    102  * @return Zero on success, negative error code otherwise.
    103  */
    104 int interrupt_enable(int irq)
    105 {
    106         return __SYSCALL2(SYS_INTERRUPT_ENABLE, (sysarg_t) irq, 1);
    107 }
    108 
    109 /** Disable an interrupt.
    110  *
    111  * @param irq the interrupt.
    112  *
    113  * @return Zero on success, negative error code otherwise.
    114  */
    115 int interrupt_disable(int irq)
    116 {
    117         return __SYSCALL2(SYS_INTERRUPT_ENABLE, (sysarg_t) irq, 0);
    118 }
    119 
    12098/** Enable PIO for specified I/O range.
    12199 *
     
    149127}
    150128
     129/** Register IRQ notification.
     130 *
     131 * @param inr    IRQ number.
     132 * @param devno  Device number of the device generating inr.
     133 * @param method Use this method for notifying me.
     134 * @param ucode  Top-half pseudocode handler.
     135 *
     136 * @return Value returned by the kernel.
     137 *
     138 */
     139int register_irq(int inr, int devno, int method, irq_code_t *ucode)
     140{
     141        return __SYSCALL4(SYS_REGISTER_IRQ, inr, devno, method,
     142            (sysarg_t) ucode);
     143}
     144
     145/** Unregister IRQ notification.
     146 *
     147 * @param inr   IRQ number.
     148 * @param devno Device number of the device generating inr.
     149 *
     150 * @return Value returned by the kernel.
     151 *
     152 */
     153int unregister_irq(int inr, int devno)
     154{
     155        return __SYSCALL2(SYS_UNREGISTER_IRQ, inr, devno);
     156}
     157
    151158/** @}
    152159 */
  • uspace/lib/c/generic/devman.c

    r22027b6e r8b5690f  
    2828 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2929 */
    30  
    31  /** @addtogroup libc
     30
     31/** @addtogroup libc
    3232 * @{
    3333 */
     
    3737#include <str.h>
    3838#include <stdio.h>
    39 #include <ipc/ipc.h>
    4039#include <ipc/services.h>
    4140#include <ipc/devman.h>
    4241#include <devman.h>
    4342#include <async.h>
     43#include <fibril_synch.h>
    4444#include <errno.h>
    4545#include <malloc.h>
     
    5050static int devman_phone_client = -1;
    5151
     52static FIBRIL_MUTEX_INITIALIZE(devman_phone_mutex);
     53
    5254int devman_get_phone(devman_interface_t iface, unsigned int flags)
    5355{
    5456        switch (iface) {
    5557        case DEVMAN_DRIVER:
    56                 if (devman_phone_driver >= 0)
     58                fibril_mutex_lock(&devman_phone_mutex);
     59                if (devman_phone_driver >= 0) {
     60                        fibril_mutex_unlock(&devman_phone_mutex);
    5761                        return devman_phone_driver;
     62                }
    5863               
    5964                if (flags & IPC_FLAG_BLOCKING)
     
    6469                            SERVICE_DEVMAN, DEVMAN_DRIVER, 0);
    6570               
     71                fibril_mutex_unlock(&devman_phone_mutex);
    6672                return devman_phone_driver;
    6773        case DEVMAN_CLIENT:
    68                 if (devman_phone_client >= 0)
     74                fibril_mutex_lock(&devman_phone_mutex);
     75                if (devman_phone_client >= 0) {
     76                        fibril_mutex_unlock(&devman_phone_mutex);
    6977                        return devman_phone_client;
    70                
    71                 if (flags & IPC_FLAG_BLOCKING)
     78                }
     79               
     80                if (flags & IPC_FLAG_BLOCKING) {
    7281                        devman_phone_client = async_connect_me_to_blocking(
    7382                            PHONE_NS, SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
    74                 else
     83                } else {
    7584                        devman_phone_client = async_connect_me_to(PHONE_NS,
    7685                            SERVICE_DEVMAN, DEVMAN_CLIENT, 0);
    77                
     86                }
     87               
     88                fibril_mutex_unlock(&devman_phone_mutex);
    7889                return devman_phone_client;
    7990        default:
     
    104115        async_set_client_connection(conn);
    105116       
    106         sysarg_t callback_phonehash;
    107         ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
     117        async_connect_to_me(phone, 0, 0, 0, NULL);
    108118        async_wait_for(req, &retval);
    109119       
     
    210220        case DEVMAN_DRIVER:
    211221                if (devman_phone_driver >= 0) {
    212                         ipc_hangup(devman_phone_driver);
     222                        async_hangup(devman_phone_driver);
    213223                        devman_phone_driver = -1;
    214224                }
     
    216226        case DEVMAN_CLIENT:
    217227                if (devman_phone_client >= 0) {
    218                         ipc_hangup(devman_phone_client);
     228                        async_hangup(devman_phone_client);
    219229                        devman_phone_client = -1;
    220230                }
  • uspace/lib/c/generic/devmap.c

    r22027b6e r8b5690f  
    2929
    3030#include <str.h>
    31 #include <ipc/ipc.h>
    3231#include <ipc/services.h>
     32#include <ipc/ns.h>
    3333#include <ipc/devmap.h>
    3434#include <devmap.h>
     
    5050               
    5151                if (flags & IPC_FLAG_BLOCKING)
    52                         devmap_phone_driver = ipc_connect_me_to_blocking(PHONE_NS,
    53                             SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
     52                        devmap_phone_driver = service_connect_blocking(SERVICE_DEVMAP,
     53                            DEVMAP_DRIVER, 0);
    5454                else
    55                         devmap_phone_driver = ipc_connect_me_to(PHONE_NS,
    56                             SERVICE_DEVMAP, DEVMAP_DRIVER, 0);
     55                        devmap_phone_driver = service_connect(SERVICE_DEVMAP,
     56                            DEVMAP_DRIVER, 0);
    5757               
    5858                return devmap_phone_driver;
     
    6262               
    6363                if (flags & IPC_FLAG_BLOCKING)
    64                         devmap_phone_client = ipc_connect_me_to_blocking(PHONE_NS,
    65                             SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
     64                        devmap_phone_client = service_connect_blocking(SERVICE_DEVMAP,
     65                            DEVMAP_CLIENT, 0);
    6666                else
    67                         devmap_phone_client = ipc_connect_me_to(PHONE_NS,
    68                             SERVICE_DEVMAP, DEVMAP_CLIENT, 0);
     67                        devmap_phone_client = service_connect(SERVICE_DEVMAP,
     68                            DEVMAP_CLIENT, 0);
    6969               
    7070                return devmap_phone_client;
     
    7979        case DEVMAP_DRIVER:
    8080                if (devmap_phone_driver >= 0) {
    81                         ipc_hangup(devmap_phone_driver);
     81                        async_hangup(devmap_phone_driver);
    8282                        devmap_phone_driver = -1;
    8383                }
     
    8585        case DEVMAP_CLIENT:
    8686                if (devmap_phone_client >= 0) {
    87                         ipc_hangup(devmap_phone_client);
     87                        async_hangup(devmap_phone_client);
    8888                        devmap_phone_client = -1;
    8989                }
     
    116116        async_set_client_connection(conn);
    117117       
    118         sysarg_t callback_phonehash;
    119         ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
     118        async_connect_to_me(phone, 0, 0, 0, NULL);
    120119        async_wait_for(req, &retval);
    121120       
  • uspace/lib/c/generic/event.c

    r22027b6e r8b5690f  
    3535 */
    3636/** @file
    37  */ 
     37 */
    3838
    3939#include <libc.h>
    4040#include <event.h>
    4141#include <kernel/ipc/event_types.h>
    42 #include <ipc/ipc.h>
    4342
    4443/** Subscribe for event notifications.
  • uspace/lib/c/generic/fibril_synch.c

    r22027b6e r8b5690f  
    3636#include <fibril.h>
    3737#include <async.h>
    38 #include <async_priv.h>
    3938#include <adt/list.h>
    4039#include <futex.h>
     
    4443#include <stacktrace.h>
    4544#include <stdlib.h>
     45#include "private/async.h"
    4646
    4747static void optimize_execution_power(void)
     
    5555         */
    5656        if (atomic_get(&threads_in_ipc_wait) > 0)
    57                 ipc_poke();
     57                async_poke();
    5858}
    5959
     
    103103{
    104104        fibril_t *f = (fibril_t *) fibril_get_id();
     105
     106        if (fibril_get_sercount() != 0)
     107                abort();
    105108
    106109        futex_down(&async_futex);
     
    194197        fibril_t *f = (fibril_t *) fibril_get_id();
    195198       
     199        if (fibril_get_sercount() != 0)
     200                abort();
     201
    196202        futex_down(&async_futex);
    197203        if (frw->writers) {
     
    219225        fibril_t *f = (fibril_t *) fibril_get_id();
    220226       
     227        if (fibril_get_sercount() != 0)
     228                abort();
     229
    221230        futex_down(&async_futex);
    222231        if (frw->writers || frw->readers) {
  • uspace/lib/c/generic/io/io.c

    r22027b6e r8b5690f  
    4141#include <bool.h>
    4242#include <malloc.h>
     43#include <async.h>
    4344#include <io/klog.h>
    4445#include <vfs/vfs.h>
    4546#include <ipc/devmap.h>
    4647#include <adt/list.h>
     48#include "../private/io.h"
    4749
    4850static void _ffillbuf(FILE *stream);
     
    322324       
    323325        if (stream->phone >= 0)
    324                 ipc_hangup(stream->phone);
     326                async_hangup(stream->phone);
    325327       
    326328        if (stream->fd >= 0)
  • uspace/lib/c/generic/ipc.c

    r22027b6e r8b5690f  
    4545#include <errno.h>
    4646#include <adt/list.h>
    47 #include <stdio.h>
    48 #include <unistd.h>
    4947#include <futex.h>
    50 #include <kernel/synch/synch.h>
    51 #include <async.h>
    5248#include <fibril.h>
    53 #include <assert.h>
    5449
    5550/**
    56  * Structures of this type are used for keeping track of sent asynchronous calls
    57  * and queing unsent calls.
     51 * Structures of this type are used for keeping track
     52 * of sent asynchronous calls and queing unsent calls.
    5853 */
    5954typedef struct {
    6055        link_t list;
    61 
     56       
    6257        ipc_async_callback_t callback;
    6358        void *private;
     59       
    6460        union {
    6561                ipc_callid_t callid;
     
    6965                } msg;
    7066        } u;
    71         fid_t fid;      /**< Fibril waiting for sending this call. */
     67       
     68        /** Fibril waiting for sending this call. */
     69        fid_t fid;
    7270} async_call_t;
    7371
     
    7674/** List of asynchronous calls that were not accepted by kernel.
    7775 *
    78  * It is protected by async_futex, because if the call cannot be sent into the
    79  * kernel, the async framework is used automatically.
     76 * Protected by async_futex, because if the call is not accepted
     77 * by the kernel, the async framework is used automatically.
     78 *
    8079 */
    8180LIST_INITIALIZE(queued_calls);
     
    8382static atomic_t ipc_futex = FUTEX_INITIALIZER;
    8483
    85 /** Make a fast synchronous call.
    86  *
    87  * Only three payload arguments can be passed using this function. However, this
    88  * function is faster than the generic ipc_call_sync_slow() because the payload
    89  * is passed directly in registers.
    90  *
    91  * @param phoneid       Phone handle for the call.
    92  * @param method        Requested method.
    93  * @param arg1          Service-defined payload argument.
    94  * @param arg2          Service-defined payload argument.
    95  * @param arg3          Service-defined payload argument.
    96  * @param result1       If non-NULL, the return ARG1 will be stored there.
    97  * @param result2       If non-NULL, the return ARG2 will be stored there.
    98  * @param result3       If non-NULL, the return ARG3 will be stored there.
    99  * @param result4       If non-NULL, the return ARG4 will be stored there.
    100  * @param result5       If non-NULL, the return ARG5 will be stored there.
    101  *
    102  * @return              Negative values represent errors returned by IPC.
    103  *                      Otherwise the RETVAL of the answer is returned.
    104  */
    105 int
    106 ipc_call_sync_fast(int phoneid, sysarg_t method, sysarg_t arg1, sysarg_t arg2,
    107     sysarg_t arg3, sysarg_t *result1, sysarg_t *result2, sysarg_t *result3,
    108     sysarg_t *result4, sysarg_t *result5)
     84/** Fast synchronous call.
     85 *
     86 * Only three payload arguments can be passed using this function. However,
     87 * this function is faster than the generic ipc_call_sync_slow() because
     88 * the payload is passed directly in registers.
     89 *
     90 * @param phoneid Phone handle for the call.
     91 * @param method  Requested method.
     92 * @param arg1    Service-defined payload argument.
     93 * @param arg2    Service-defined payload argument.
     94 * @param arg3    Service-defined payload argument.
     95 * @param result1 If non-NULL, the return ARG1 will be stored there.
     96 * @param result2 If non-NULL, the return ARG2 will be stored there.
     97 * @param result3 If non-NULL, the return ARG3 will be stored there.
     98 * @param result4 If non-NULL, the return ARG4 will be stored there.
     99 * @param result5 If non-NULL, the return ARG5 will be stored there.
     100 *
     101 * @return Negative values representing IPC errors.
     102 * @return Otherwise the RETVAL of the answer.
     103 *
     104 */
     105int ipc_call_sync_fast(int phoneid, sysarg_t method, sysarg_t arg1,
     106    sysarg_t arg2, sysarg_t arg3, sysarg_t *result1, sysarg_t *result2,
     107    sysarg_t *result3, sysarg_t *result4, sysarg_t *result5)
    109108{
    110109        ipc_call_t resdata;
    111         int callres;
    112        
    113         callres = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1,
     110        int callres = __SYSCALL6(SYS_IPC_CALL_SYNC_FAST, phoneid, method, arg1,
    114111            arg2, arg3, (sysarg_t) &resdata);
    115112        if (callres)
    116113                return callres;
     114       
    117115        if (result1)
    118116                *result1 = IPC_GET_ARG1(resdata);
     
    125123        if (result5)
    126124                *result5 = IPC_GET_ARG5(resdata);
    127 
     125       
    128126        return IPC_GET_RETVAL(resdata);
    129127}
    130128
    131 /** Make a synchronous call transmitting 5 arguments of payload.
     129/** Synchronous call transmitting 5 arguments of payload.
    132130 *
    133131 * @param phoneid Phone handle for the call.
     
    144142 * @param result5 If non-NULL, storage for the fifth return argument.
    145143 *
    146  * @return Negative value means IPC error.
    147  *         Otherwise the RETVAL of the answer.
    148  *
    149  */
    150 int
    151 ipc_call_sync_slow(int phoneid, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
    152     sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *result1,
    153     sysarg_t *result2, sysarg_t *result3, sysarg_t *result4, sysarg_t *result5)
     144 * @return Negative values representing IPC errors.
     145 * @return Otherwise the RETVAL of the answer.
     146 *
     147 */
     148int ipc_call_sync_slow(int phoneid, sysarg_t imethod, sysarg_t arg1,
     149    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
     150    sysarg_t *result1, sysarg_t *result2, sysarg_t *result3, sysarg_t *result4,
     151    sysarg_t *result5)
    154152{
    155153        ipc_call_t data;
     
    181179}
    182180
    183 /** Syscall to send asynchronous message.
     181/** Send asynchronous message via syscall.
    184182 *
    185183 * @param phoneid Phone handle for the call.
     
    189187 *
    190188 */
    191 static ipc_callid_t _ipc_call_async(int phoneid, ipc_call_t *data)
     189static ipc_callid_t ipc_call_async_internal(int phoneid, ipc_call_t *data)
    192190{
    193191        return __SYSCALL2(SYS_IPC_CALL_ASYNC_SLOW, phoneid, (sysarg_t) data);
    194192}
    195193
    196 /** Prolog to ipc_call_async_*() functions.
    197  *
    198  * @param private       Argument for the answer/error callback.
    199  * @param callback      Answer/error callback.
    200  *
    201  * @return              New, partially initialized async_call structure or NULL.
     194/** Prolog for ipc_call_async_*() functions.
     195 *
     196 * @param private  Argument for the answer/error callback.
     197 * @param callback Answer/error callback.
     198 *
     199 * @return New, partially initialized async_call structure or NULL.
     200 *
    202201 */
    203202static inline async_call_t *ipc_prepare_async(void *private,
    204203    ipc_async_callback_t callback)
    205204{
    206         async_call_t *call;
    207 
    208         call = malloc(sizeof(*call));
     205        async_call_t *call =
     206            (async_call_t *) malloc(sizeof(async_call_t));
    209207        if (!call) {
    210208                if (callback)
    211209                        callback(private, ENOMEM, NULL);
     210               
    212211                return NULL;
    213212        }
     213       
    214214        call->callback = callback;
    215215        call->private = private;
    216 
     216       
    217217        return call;
    218218}
    219219
    220 /** Epilogue of ipc_call_async_*() functions.
    221  *
    222  * @param callid        Value returned by the SYS_IPC_CALL_ASYNC_* syscall.
    223  * @param phoneid       Phone handle through which the call was made.
    224  * @param call          async_call structure returned by ipc_prepare_async().
    225  * @param can_preempt   If non-zero, the current fibril can be preempted in this
    226  *                      call.
     220/** Epilog for ipc_call_async_*() functions.
     221 *
     222 * @param callid      Value returned by the SYS_IPC_CALL_ASYNC_* syscall.
     223 * @param phoneid     Phone handle through which the call was made.
     224 * @param call        Structure returned by ipc_prepare_async().
     225 * @param can_preempt If true, the current fibril can be preempted
     226 *                    in this call.
     227 *
    227228 */
    228229static inline void ipc_finish_async(ipc_callid_t callid, int phoneid,
    229     async_call_t *call, int can_preempt)
    230 {
    231         if (!call) { /* Nothing to do regardless if failed or not */
     230    async_call_t *call, bool can_preempt)
     231{
     232        if (!call) {
     233                /* Nothing to do regardless if failed or not */
    232234                futex_up(&ipc_futex);
    233235                return;
    234236        }
    235 
     237       
    236238        if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) {
    237239                futex_up(&ipc_futex);
     240               
    238241                /* Call asynchronous handler with error code */
    239242                if (call->callback)
    240243                        call->callback(call->private, ENOENT, NULL);
     244               
    241245                free(call);
    242246                return;
    243247        }
    244 
     248       
    245249        if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
    246250                futex_up(&ipc_futex);
    247 
     251               
    248252                call->u.msg.phoneid = phoneid;
    249253               
    250254                futex_down(&async_futex);
    251255                list_append(&call->list, &queued_calls);
    252 
     256               
    253257                if (can_preempt) {
    254258                        call->fid = fibril_get_id();
     
    259263                        futex_up(&async_futex);
    260264                }
     265               
    261266                return;
    262267        }
     268       
    263269        call->u.callid = callid;
     270       
    264271        /* Add call to the list of dispatched calls */
    265272        list_append(&call->list, &dispatched_calls);
    266273        futex_up(&ipc_futex);
    267        
    268 }
    269 
    270 /** Make a fast asynchronous call.
     274}
     275
     276/** Fast asynchronous call.
    271277 *
    272278 * This function can only handle four arguments of payload. It is, however,
     
    274280 *
    275281 * Note that this function is a void function.
    276  * During normal opertation, answering this call will trigger the callback.
    277  * In case of fatal error, call the callback handler with the proper error code.
    278  * If the call cannot be temporarily made, queue it.
     282 *
     283 * During normal operation, answering this call will trigger the callback.
     284 * In case of fatal error, the callback handler is called with the proper
     285 * error code. If the call cannot be temporarily made, it is queued.
    279286 *
    280287 * @param phoneid     Phone handle for the call.
     
    286293 * @param private     Argument to be passed to the answer/error callback.
    287294 * @param callback    Answer or error callback.
    288  * @param can_preempt If non-zero, the current fibril will be preempted in
     295 * @param can_preempt If true, the current fibril will be preempted in
    289296 *                    case the kernel temporarily refuses to accept more
    290297 *                    asynchronous calls.
     
    293300void ipc_call_async_fast(int phoneid, sysarg_t imethod, sysarg_t arg1,
    294301    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, void *private,
    295     ipc_async_callback_t callback, int can_preempt)
     302    ipc_async_callback_t callback, bool can_preempt)
    296303{
    297304        async_call_t *call = NULL;
     
    304311       
    305312        /*
    306          * We need to make sure that we get callid before another thread
    307          * accesses the queue again.
     313         * We need to make sure that we get callid
     314         * before another thread accesses the queue again.
    308315         */
     316       
    309317        futex_down(&ipc_futex);
    310318        ipc_callid_t callid = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phoneid,
     
    317325                                return;
    318326                }
     327               
    319328                IPC_SET_IMETHOD(call->u.msg.data, imethod);
    320329                IPC_SET_ARG1(call->u.msg.data, arg1);
     
    322331                IPC_SET_ARG3(call->u.msg.data, arg3);
    323332                IPC_SET_ARG4(call->u.msg.data, arg4);
     333               
    324334                /*
    325335                 * To achieve deterministic behavior, we always zero out the
    326336                 * arguments that are beyond the limits of the fast version.
    327337                 */
     338               
    328339                IPC_SET_ARG5(call->u.msg.data, 0);
    329340        }
     341       
    330342        ipc_finish_async(callid, phoneid, call, can_preempt);
    331343}
    332344
    333 /** Make an asynchronous call transmitting the entire payload.
     345/** Asynchronous call transmitting the entire payload.
    334346 *
    335347 * Note that this function is a void function.
    336  * During normal opertation, answering this call will trigger the callback.
    337  * In case of fatal error, call the callback handler with the proper error code.
    338  * If the call cannot be temporarily made, queue it.
     348 *
     349 * During normal operation, answering this call will trigger the callback.
     350 * In case of fatal error, the callback handler is called with the proper
     351 * error code. If the call cannot be temporarily made, it is queued.
    339352 *
    340353 * @param phoneid     Phone handle for the call.
     
    347360 * @param private     Argument to be passed to the answer/error callback.
    348361 * @param callback    Answer or error callback.
    349  * @param can_preempt If non-zero, the current fibril will be preempted in
     362 * @param can_preempt If true, the current fibril will be preempted in
    350363 *                    case the kernel temporarily refuses to accept more
    351364 *                    asynchronous calls.
     
    354367void ipc_call_async_slow(int phoneid, sysarg_t imethod, sysarg_t arg1,
    355368    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, void *private,
    356     ipc_async_callback_t callback, int can_preempt)
    357 {
    358         async_call_t *call;
    359         ipc_callid_t callid;
    360 
    361         call = ipc_prepare_async(private, callback);
     369    ipc_async_callback_t callback, bool can_preempt)
     370{
     371        async_call_t *call = ipc_prepare_async(private, callback);
    362372        if (!call)
    363373                return;
    364 
     374       
    365375        IPC_SET_IMETHOD(call->u.msg.data, imethod);
    366376        IPC_SET_ARG1(call->u.msg.data, arg1);
     
    369379        IPC_SET_ARG4(call->u.msg.data, arg4);
    370380        IPC_SET_ARG5(call->u.msg.data, arg5);
     381       
    371382        /*
    372          * We need to make sure that we get callid before another thread
    373          * accesses the queue again.
     383         * We need to make sure that we get callid
     384         * before another threadaccesses the queue again.
    374385         */
     386       
    375387        futex_down(&ipc_futex);
    376         callid = _ipc_call_async(phoneid, &call->u.msg.data);
    377 
     388        ipc_callid_t callid =
     389            ipc_call_async_internal(phoneid, &call->u.msg.data);
     390       
    378391        ipc_finish_async(callid, phoneid, call, can_preempt);
    379392}
    380393
    381 
    382 /** Answer a received call - fast version.
     394/** Answer received call (fast version).
    383395 *
    384396 * The fast answer makes use of passing retval and first four arguments in
    385397 * registers. If you need to return more, use the ipc_answer_slow() instead.
    386398 *
    387  * @param callid        Hash of the call being answered.
    388  * @param retval        Return value.
    389  * @param arg1          First return argument.
    390  * @param arg2          Second return argument.
    391  * @param arg3          Third return argument.
    392  * @param arg4          Fourth return argument.
    393  *
    394  * @return              Zero on success or a value from @ref errno.h on failure.
     399 * @param callid Hash of the call being answered.
     400 * @param retval Return value.
     401 * @param arg1   First return argument.
     402 * @param arg2   Second return argument.
     403 * @param arg3   Third return argument.
     404 * @param arg4   Fourth return argument.
     405 *
     406 * @return Zero on success.
     407 * @return Value from @ref errno.h on failure.
     408 *
    395409 */
    396410sysarg_t ipc_answer_fast(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     
    401415}
    402416
    403 /** Answer a received call - slow full version.
    404  *
    405  * @param callid        Hash of the call being answered.
    406  * @param retval        Return value.
    407  * @param arg1          First return argument.
    408  * @param arg2          Second return argument.
    409  * @param arg3          Third return argument.
    410  * @param arg4          Fourth return argument.
    411  * @param arg5          Fifth return argument.
    412  *
    413  * @return              Zero on success or a value from @ref errno.h on failure.
     417/** Answer received call (entire payload).
     418 *
     419 * @param callid Hash of the call being answered.
     420 * @param retval Return value.
     421 * @param arg1   First return argument.
     422 * @param arg2   Second return argument.
     423 * @param arg3   Third return argument.
     424 * @param arg4   Fourth return argument.
     425 * @param arg5   Fifth return argument.
     426 *
     427 * @return Zero on success.
     428 * @return Value from @ref errno.h on failure.
     429 *
    414430 */
    415431sysarg_t ipc_answer_slow(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     
    417433{
    418434        ipc_call_t data;
    419 
     435       
    420436        IPC_SET_RETVAL(data, retval);
    421437        IPC_SET_ARG1(data, arg1);
     
    424440        IPC_SET_ARG4(data, arg4);
    425441        IPC_SET_ARG5(data, arg5);
    426 
     442       
    427443        return __SYSCALL2(SYS_IPC_ANSWER_SLOW, callid, (sysarg_t) &data);
    428444}
    429445
    430 
    431 /** Try to dispatch queued calls from the async queue. */
    432 static void try_dispatch_queued_calls(void)
    433 {
    434         async_call_t *call;
    435         ipc_callid_t callid;
    436 
     446/** Try to dispatch queued calls from the async queue.
     447 *
     448 */
     449static void dispatch_queued_calls(void)
     450{
    437451        /** @todo
    438          * Integrate intelligently ipc_futex, so that it is locked during
    439          * ipc_call_async_*(), until it is added to dispatched_calls.
     452         * Integrate intelligently ipc_futex so that it is locked during
     453         * ipc_call_async_*() until it is added to dispatched_calls.
    440454         */
     455       
    441456        futex_down(&async_futex);
     457       
    442458        while (!list_empty(&queued_calls)) {
    443                 call = list_get_instance(queued_calls.next, async_call_t, list);
    444                 callid = _ipc_call_async(call->u.msg.phoneid,
    445                     &call->u.msg.data);
    446                 if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY) {
     459                async_call_t *call =
     460                    list_get_instance(queued_calls.next, async_call_t, list);
     461                ipc_callid_t callid =
     462                    ipc_call_async_internal(call->u.msg.phoneid, &call->u.msg.data);
     463               
     464                if (callid == (ipc_callid_t) IPC_CALLRET_TEMPORARY)
    447465                        break;
    448                 }
     466               
    449467                list_remove(&call->list);
    450 
     468               
    451469                futex_up(&async_futex);
     470               
    452471                if (call->fid)
    453472                        fibril_add_ready(call->fid);
     
    456475                        if (call->callback)
    457476                                call->callback(call->private, ENOENT, NULL);
     477                       
    458478                        free(call);
    459479                } else {
    460480                        call->u.callid = callid;
     481                       
    461482                        futex_down(&ipc_futex);
    462483                        list_append(&call->list, &dispatched_calls);
    463484                        futex_up(&ipc_futex);
    464485                }
     486               
    465487                futex_down(&async_futex);
    466488        }
     489       
    467490        futex_up(&async_futex);
    468491}
    469492
    470 /** Handle a received answer.
     493/** Handle received answer.
    471494 *
    472495 * Find the hash of the answer and call the answer callback.
    473496 *
    474  * @todo Make it use hash table.
    475  *
    476  * @param callid        Hash of the received answer.
    477  *                      The answer has the same hash as the request OR'ed with
    478  *                      the IPC_CALLID_ANSWERED bit.
    479  * @param data          Call data of the answer.
     497 * The answer has the same hash as the request OR'ed with
     498 * the IPC_CALLID_ANSWERED bit.
     499 *
     500 * @todo Use hash table.
     501 *
     502 * @param callid Hash of the received answer.
     503 * @param data   Call data of the answer.
     504 *
    480505 */
    481506static void handle_answer(ipc_callid_t callid, ipc_call_t *data)
    482507{
     508        callid &= ~IPC_CALLID_ANSWERED;
     509       
     510        futex_down(&ipc_futex);
     511       
    483512        link_t *item;
    484         async_call_t *call;
    485 
    486         callid &= ~IPC_CALLID_ANSWERED;
    487        
    488         futex_down(&ipc_futex);
    489513        for (item = dispatched_calls.next; item != &dispatched_calls;
    490514            item = item->next) {
    491                 call = list_get_instance(item, async_call_t, list);
     515                async_call_t *call =
     516                    list_get_instance(item, async_call_t, list);
     517               
    492518                if (call->u.callid == callid) {
    493519                        list_remove(&call->list);
     520                       
    494521                        futex_up(&ipc_futex);
     522                       
    495523                        if (call->callback)
    496                                 call->callback(call->private, 
     524                                call->callback(call->private,
    497525                                    IPC_GET_RETVAL(*data), data);
     526                       
    498527                        free(call);
    499528                        return;
    500529                }
    501530        }
     531       
    502532        futex_up(&ipc_futex);
    503533}
    504534
    505 
    506 /** Wait for a first call to come.
    507  *
    508  * @param call          Storage where the incoming call data will be stored.
    509  * @param usec          Timeout in microseconds
    510  * @param flags         Flags passed to SYS_IPC_WAIT (blocking, nonblocking).
    511  *
    512  * @return              Hash of the call. Note that certain bits have special
    513  *                      meaning. IPC_CALLID_ANSWERED will be set in an answer
    514  *                      and IPC_CALLID_NOTIFICATION is used for notifications.
    515  *                     
    516  */
    517 ipc_callid_t ipc_wait_cycle(ipc_call_t *call, uint32_t usec, int flags)
    518 {
    519         ipc_callid_t callid;
    520 
    521         callid = __SYSCALL3(SYS_IPC_WAIT, (sysarg_t) call, usec, flags);
     535/** Wait for first IPC call to come.
     536 *
     537 * @param call  Incoming call storage.
     538 * @param usec  Timeout in microseconds
     539 * @param flags Flags passed to SYS_IPC_WAIT (blocking, nonblocking).
     540 *
     541 * @return Hash of the call. Note that certain bits have special
     542 *         meaning: IPC_CALLID_ANSWERED is set in an answer
     543 *         and IPC_CALLID_NOTIFICATION is used for notifications.
     544 *
     545 */
     546ipc_callid_t ipc_wait_cycle(ipc_call_t *call, sysarg_t usec,
     547    unsigned int flags)
     548{
     549        ipc_callid_t callid =
     550            __SYSCALL3(SYS_IPC_WAIT, (sysarg_t) call, usec, flags);
     551       
    522552        /* Handle received answers */
    523553        if (callid & IPC_CALLID_ANSWERED) {
    524554                handle_answer(callid, call);
    525                 try_dispatch_queued_calls();
     555                dispatch_queued_calls();
    526556        }
    527 
     557       
    528558        return callid;
    529559}
    530560
    531 /** Wait some time for an IPC call.
    532  *
    533  * The call will return after an answer is received.
    534  *
    535  * @param call          Storage where the incoming call data will be stored.
    536  * @param usec          Timeout in microseconds.
    537  *
    538  * @return              Hash of the answer.
    539  */
    540 ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *call, uint32_t usec)
     561/** Interrupt one thread of this task from waiting for IPC.
     562 *
     563 */
     564void ipc_poke(void)
     565{
     566        __SYSCALL0(SYS_IPC_POKE);
     567}
     568
     569/** Wait for first IPC call to come.
     570 *
     571 * Only requests are returned, answers are processed internally.
     572 *
     573 * @param call Incoming call storage.
     574 * @param usec Timeout in microseconds
     575 *
     576 * @return Hash of the call.
     577 *
     578 */
     579ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *call, sysarg_t usec)
    541580{
    542581        ipc_callid_t callid;
    543 
     582       
    544583        do {
    545584                callid = ipc_wait_cycle(call, usec, SYNCH_FLAGS_NONE);
    546585        } while (callid & IPC_CALLID_ANSWERED);
    547 
     586       
    548587        return callid;
    549588}
     
    551590/** Check if there is an IPC call waiting to be picked up.
    552591 *
    553  * @param call          Storage where the incoming call will be stored.
    554  * @return              Hash of the answer.
     592 * Only requests are returned, answers are processed internally.
     593 *
     594 * @param call Incoming call storage.
     595 *
     596 * @return Hash of the call.
     597 *
    555598 */
    556599ipc_callid_t ipc_trywait_for_call(ipc_call_t *call)
    557600{
    558601        ipc_callid_t callid;
    559 
     602       
    560603        do {
    561604                callid = ipc_wait_cycle(call, SYNCH_NO_TIMEOUT,
    562605                    SYNCH_FLAGS_NON_BLOCKING);
    563606        } while (callid & IPC_CALLID_ANSWERED);
    564 
     607       
    565608        return callid;
    566609}
    567610
    568 /** Interrupt one thread of this task from waiting for IPC. */
    569 void ipc_poke(void)
    570 {
    571         __SYSCALL0(SYS_IPC_POKE);
    572 }
    573 
    574 /** Ask destination to do a callback connection.
    575  *
    576  * @param phoneid       Phone handle used for contacting the other side.
    577  * @param arg1          Service-defined argument.
    578  * @param arg2          Service-defined argument.
    579  * @param arg3          Service-defined argument.
    580  * @param phonehash     Storage where the library will store an opaque
    581  *                      identifier of the phone that will be used for incoming
    582  *                      calls. This identifier can be used for connection
    583  *                      tracking.
    584  *
    585  * @return              Zero on success or a negative error code.
    586  */
    587 int ipc_connect_to_me(int phoneid, int arg1, int arg2, int arg3,
    588     sysarg_t *phonehash)
     611/** Request callback connection.
     612 *
     613 * The @a taskhash and @a phonehash identifiers returned
     614 * by the kernel can be used for connection tracking.
     615 *
     616 * @param phoneid   Phone handle used for contacting the other side.
     617 * @param arg1      User defined argument.
     618 * @param arg2      User defined argument.
     619 * @param arg3      User defined argument.
     620 * @param taskhash  Opaque identifier of the client task.
     621 * @param phonehash Opaque identifier of the phone that will
     622 *                  be used for incoming calls.
     623 *
     624 * @return Zero on success or a negative error code.
     625 *
     626 */
     627int ipc_connect_to_me(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3,
     628    sysarg_t *taskhash, sysarg_t *phonehash)
    589629{
    590630        return ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_TO_ME, arg1, arg2,
    591             arg3, NULL, NULL, NULL, NULL, phonehash);
    592 }
    593 
    594 /** Ask through phone for a new connection to some service.
    595  *
    596  * @param phoneid       Phone handle used for contacting the other side.
    597  * @param arg1          User defined argument.
    598  * @param arg2          User defined argument.
    599  * @param arg3          User defined argument.
    600  *
    601  * @return              New phone handle on success or a negative error code.
    602  */
    603 int ipc_connect_me_to(int phoneid, int arg1, int arg2, int arg3)
     631            arg3, NULL, NULL, NULL, taskhash, phonehash);
     632}
     633
     634/** Request new connection.
     635 *
     636 * @param phoneid Phone handle used for contacting the other side.
     637 * @param arg1    User defined argument.
     638 * @param arg2    User defined argument.
     639 * @param arg3    User defined argument.
     640 *
     641 * @return New phone handle on success or a negative error code.
     642 *
     643 */
     644int ipc_connect_me_to(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
    604645{
    605646        sysarg_t newphid;
    606         int res;
    607 
    608         res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     647        int res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
    609648            NULL, NULL, NULL, NULL, &newphid);
    610649        if (res)
    611650                return res;
     651       
    612652        return newphid;
    613653}
    614654
    615 /** Ask through phone for a new connection to some service.
     655/** Request new connection (blocking)
    616656 *
    617657 * If the connection is not available at the moment, the
    618  * call will block.
    619  *
    620  * @param phoneid       Phone handle used for contacting the other side.
    621  * @param arg1          User defined argument.
    622  * @param arg2          User defined argument.
    623  * @param arg3          User defined argument.
    624  *
    625  * @return              New phone handle on success or a negative error code.
    626  */
    627 int ipc_connect_me_to_blocking(int phoneid, int arg1, int arg2, int arg3)
     658 * call should block. This has to be, however, implemented
     659 * on the server side.
     660 *
     661 * @param phoneid Phone handle used for contacting the other side.
     662 * @param arg1    User defined argument.
     663 * @param arg2    User defined argument.
     664 * @param arg3    User defined argument.
     665 *
     666 * @return New phone handle on success or a negative error code.
     667 *
     668 */
     669int ipc_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,
     670    sysarg_t arg3)
    628671{
    629672        sysarg_t newphid;
    630         int res;
    631 
    632         res = ipc_call_sync_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     673        int res = ipc_call_sync_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
    633674            IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
    634675        if (res)
    635676                return res;
     677       
    636678        return newphid;
    637679}
     
    639681/** Hang up a phone.
    640682 *
    641  * @param phoneid       Handle of the phone to be hung up.
    642  *
    643  * @return              Zero on success or a negative error code.
     683 * @param phoneid Handle of the phone to be hung up.
     684 *
     685 * @return Zero on success or a negative error code.
     686 *
    644687 */
    645688int ipc_hangup(int phoneid)
     
    648691}
    649692
    650 /** Register IRQ notification.
    651  *
    652  * @param inr           IRQ number.
    653  * @param devno         Device number of the device generating inr.
    654  * @param method        Use this method for notifying me.
    655  * @param ucode         Top-half pseudocode handler.
    656  *
    657  * @return              Value returned by the kernel.
    658  */
    659 int ipc_register_irq(int inr, int devno, int method, irq_code_t *ucode)
    660 {
    661         return __SYSCALL4(SYS_IPC_REGISTER_IRQ, inr, devno, method,
    662             (sysarg_t) ucode);
    663 }
    664 
    665 /** Unregister IRQ notification.
    666  *
    667  * @param inr           IRQ number.
    668  * @param devno         Device number of the device generating inr.
    669  *
    670  * @return              Value returned by the kernel.
    671  */
    672 int ipc_unregister_irq(int inr, int devno)
    673 {
    674         return __SYSCALL2(SYS_IPC_UNREGISTER_IRQ, inr, devno);
    675 }
    676 
    677693/** Forward a received call to another destination.
     694 *
     695 * For non-system methods, the old method, arg1 and arg2 are rewritten
     696 * by the new values. For system methods, the new method, arg1 and arg2
     697 * are written to the old arg1, arg2 and arg3, respectivelly. Calls with
     698 * immutable methods are forwarded verbatim.
    678699 *
    679700 * @param callid  Hash of the call to forward.
     
    686707 * @return Zero on success or an error code.
    687708 *
    688  * For non-system methods, the old method, arg1 and arg2 are rewritten by the
    689  * new values. For system methods, the new method, arg1 and arg2 are written
    690  * to the old arg1, arg2 and arg3, respectivelly. Calls with immutable
    691  * methods are forwarded verbatim.
    692  */
    693 int ipc_forward_fast(ipc_callid_t callid, int phoneid, int imethod,
    694     sysarg_t arg1, sysarg_t arg2, int mode)
     709 */
     710int ipc_forward_fast(ipc_callid_t callid, int phoneid, sysarg_t imethod,
     711    sysarg_t arg1, sysarg_t arg2, unsigned int mode)
    695712{
    696713        return __SYSCALL6(SYS_IPC_FORWARD_FAST, callid, phoneid, imethod, arg1,
     
    698715}
    699716
    700 
    701 int ipc_forward_slow(ipc_callid_t callid, int phoneid, int imethod,
     717int ipc_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod,
    702718    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
    703     int mode)
     719    unsigned int mode)
    704720{
    705721        ipc_call_t data;
     
    712728        IPC_SET_ARG5(data, arg5);
    713729       
    714         return __SYSCALL4(SYS_IPC_FORWARD_SLOW, callid, phoneid, (sysarg_t) &data, mode);
    715 }
    716 
    717 /** Wrapper for making IPC_M_SHARE_IN calls.
    718  *
    719  * @param phoneid       Phone that will be used to contact the receiving side.
    720  * @param dst           Destination address space area base.
    721  * @param size          Size of the destination address space area.
    722  * @param arg           User defined argument.
    723  * @param flags         Storage where the received flags will be stored. Can be
    724  *                      NULL.
    725  *
    726  * @return              Zero on success or a negative error code from errno.h.
     730        return __SYSCALL4(SYS_IPC_FORWARD_SLOW, callid, phoneid, (sysarg_t) &data,
     731            mode);
     732}
     733
     734/** Wrapper for IPC_M_SHARE_IN calls.
     735 *
     736 * @param phoneid Phone that will be used to contact the receiving side.
     737 * @param dst     Destination address space area base.
     738 * @param size    Size of the destination address space area.
     739 * @param arg     User defined argument.
     740 * @param flags   Storage for received flags. Can be NULL.
     741 *
     742 * @return Zero on success or a negative error code from errno.h.
     743 *
    727744 */
    728745int ipc_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg,
    729     int *flags)
     746    unsigned int *flags)
    730747{
    731748        sysarg_t tmp_flags = 0;
     
    734751       
    735752        if (flags)
    736                 *flags = tmp_flags;
     753                *flags = (unsigned int) tmp_flags;
    737754       
    738755        return res;
     
    741758/** Wrapper for answering the IPC_M_SHARE_IN calls.
    742759 *
    743  * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
    744  * so that the user doesn't have to remember the meaning of each IPC argument.
    745  *
    746  * @param callid        Hash of the IPC_M_DATA_READ call to answer.
    747  * @param src           Source address space base.
    748  * @param flags         Flags to be used for sharing. Bits can be only cleared.
    749  *
    750  * @return              Zero on success or a value from @ref errno.h on failure.
    751  */
    752 int ipc_share_in_finalize(ipc_callid_t callid, void *src, int flags)
     760 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ
     761 * calls so that the user doesn't have to remember the meaning of each
     762 * IPC argument.
     763 *
     764 * @param callid Hash of the IPC_M_DATA_READ call to answer.
     765 * @param src    Source address space base.
     766 * @param flags Flags to be used for sharing. Bits can be only cleared.
     767 *
     768 * @return Zero on success or a value from @ref errno.h on failure.
     769 *
     770 */
     771int ipc_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags)
    753772{
    754773        return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) flags);
    755774}
    756775
    757 /** Wrapper for making IPC_M_SHARE_OUT calls.
    758  *
    759  * @param phoneid       Phone that will be used to contact the receiving side.
    760  * @param src           Source address space area base address.
    761  * @param flags         Flags to be used for sharing. Bits can be only cleared.
    762  *
    763  * @return              Zero on success or a negative error code from errno.h.
    764  */
    765 int ipc_share_out_start(int phoneid, void *src, int flags)
     776/** Wrapper for IPC_M_SHARE_OUT calls.
     777 *
     778 * @param phoneid Phone that will be used to contact the receiving side.
     779 * @param src     Source address space area base address.
     780 * @param flags   Flags to be used for sharing. Bits can be only cleared.
     781 *
     782 * @return Zero on success or a negative error code from errno.h.
     783 *
     784 */
     785int ipc_share_out_start(int phoneid, void *src, unsigned int flags)
    766786{
    767787        return ipc_call_sync_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
     
    771791/** Wrapper for answering the IPC_M_SHARE_OUT calls.
    772792 *
    773  * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT calls
    774  * so that the user doesn't have to remember the meaning of each IPC argument.
    775  *
    776  * @param callid        Hash of the IPC_M_DATA_WRITE call to answer.
    777  * @param dst           Destination address space area base address.   
    778  *
    779  * @return              Zero on success or a value from @ref errno.h on failure.
     793 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT
     794 * calls so that the user doesn't have to remember the meaning of each
     795 * IPC argument.
     796 *
     797 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.
     798 * @param dst    Destination address space area base address.
     799 *
     800 * @return Zero on success or a value from @ref errno.h on failure.
     801 *
    780802 */
    781803int ipc_share_out_finalize(ipc_callid_t callid, void *dst)
     
    784806}
    785807
    786 
    787 /** Wrapper for making IPC_M_DATA_READ calls.
    788  *
    789  * @param phoneid       Phone that will be used to contact the receiving side.
    790  * @param dst           Address of the beginning of the destination buffer.
    791  * @param size          Size of the destination buffer.
    792  *
    793  * @return              Zero on success or a negative error code from errno.h.
     808/** Wrapper for IPC_M_DATA_READ calls.
     809 *
     810 * @param phoneid Phone that will be used to contact the receiving side.
     811 * @param dst     Address of the beginning of the destination buffer.
     812 * @param size    Size of the destination buffer.
     813 *
     814 * @return Zero on success or a negative error code from errno.h.
     815 *
    794816 */
    795817int ipc_data_read_start(int phoneid, void *dst, size_t size)
     
    801823/** Wrapper for answering the IPC_M_DATA_READ calls.
    802824 *
    803  * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
    804  * so that the user doesn't have to remember the meaning of each IPC argument.
    805  *
    806  * @param callid        Hash of the IPC_M_DATA_READ call to answer.
    807  * @param src           Source address for the IPC_M_DATA_READ call.
    808  * @param size          Size for the IPC_M_DATA_READ call. Can be smaller than
    809  *                      the maximum size announced by the sender.
    810  *
    811  * @return              Zero on success or a value from @ref errno.h on failure.
     825 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ
     826 * calls so that the user doesn't have to remember the meaning of each
     827 * IPC argument.
     828 *
     829 * @param callid Hash of the IPC_M_DATA_READ call to answer.
     830 * @param src    Source address for the IPC_M_DATA_READ call.
     831 * @param size   Size for the IPC_M_DATA_READ call. Can be smaller than
     832 *               the maximum size announced by the sender.
     833 *
     834 * @return Zero on success or a value from @ref errno.h on failure.
     835 *
    812836 */
    813837int ipc_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
     
    816840}
    817841
    818 /** Wrapper for making IPC_M_DATA_WRITE calls.
    819  *
    820  * @param phoneid       Phone that will be used to contact the receiving side.
    821  * @param src           Address of the beginning of the source buffer.
    822  * @param size          Size of the source buffer.
    823  *
    824  * @return              Zero on success or a negative error code from errno.h.
     842/** Wrapper for IPC_M_DATA_WRITE calls.
     843 *
     844 * @param phoneid Phone that will be used to contact the receiving side.
     845 * @param src     Address of the beginning of the source buffer.
     846 * @param size    Size of the source buffer.
     847 *
     848 * @return Zero on success or a negative error code from errno.h.
     849 *
    825850 */
    826851int ipc_data_write_start(int phoneid, const void *src, size_t size)
     
    832857/** Wrapper for answering the IPC_M_DATA_WRITE calls.
    833858 *
    834  * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE calls
    835  * so that the user doesn't have to remember the meaning of each IPC argument.
    836  *
    837  * @param callid        Hash of the IPC_M_DATA_WRITE call to answer.
    838  * @param dst           Final destination address for the IPC_M_DATA_WRITE call.
    839  * @param size          Final size for the IPC_M_DATA_WRITE call.
    840  *
    841  * @return              Zero on success or a value from @ref errno.h on failure.
     859 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE
     860 * calls so that the user doesn't have to remember the meaning of each
     861 * IPC argument.
     862 *
     863 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.
     864 * @param dst    Final destination address for the IPC_M_DATA_WRITE call.
     865 * @param size   Final size for the IPC_M_DATA_WRITE call.
     866 *
     867 * @return Zero on success or a value from @ref errno.h on failure.
     868 *
    842869 */
    843870int ipc_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)
  • uspace/lib/c/generic/libc.c

    r22027b6e r8b5690f  
    4242
    4343#include <libc.h>
    44 #include <stdio.h>
    45 #include <unistd.h>
    46 #include <malloc.h>
     44#include <stdlib.h>
    4745#include <tls.h>
    48 #include <thread.h>
    4946#include <fibril.h>
    50 #include <ipc/ipc.h>
    51 #include <async.h>
    52 #include <as.h>
     47#include <task.h>
    5348#include <loader/pcb.h>
     49#include "private/libc.h"
     50#include "private/async.h"
     51#include "private/async_sess.h"
     52#include "private/malloc.h"
     53#include "private/io.h"
    5454
    55 extern int main(int argc, char *argv[]);
    56 
    57 void _exit(int status)
    58 {
    59         thread_exit(status);
    60 }
     55static bool env_setup = false;
    6156
    6257void __main(void *pcb_ptr)
    6358{
    6459        /* Initialize user task run-time environment */
    65         __heap_init();
     60        __malloc_init();
    6661        __async_init();
     62        __async_sess_init();
     63       
    6764        fibril_t *fibril = fibril_setup();
     65        if (fibril == NULL)
     66                abort();
     67       
    6868        __tcb_set(fibril->tcb);
    6969       
     
    7171        __pcb = (pcb_t *) pcb_ptr;
    7272       
     73        /* The basic run-time environment is setup */
     74        env_setup = true;
     75       
    7376        int argc;
    7477        char **argv;
    7578       
    76         /* Get command line arguments and initialize
    77            standard input and output */
     79        /*
     80         * Get command line arguments and initialize
     81         * standard input and output
     82         */
    7883        if (__pcb == NULL) {
    7984                argc = 0;
     
    8792        }
    8893       
    89         /* Run main() and set task return value
    90            according the result */
    91         (void) task_retval(main(argc, argv));
     94        /*
     95         * Run main() and set task return value
     96         * according the result
     97         */
     98        int retval = main(argc, argv);
     99        exit(retval);
    92100}
    93101
    94 void __exit(void)
     102void exit(int status)
    95103{
    96         __stdio_done();
    97         fibril_teardown(__tcb_get()->fibril_data);
    98         _exit(0);
     104        if (env_setup) {
     105                __stdio_done();
     106                task_retval(status);
     107                fibril_teardown(__tcb_get()->fibril_data);
     108        }
     109       
     110        __SYSCALL1(SYS_TASK_EXIT, false);
     111       
     112        /* Unreachable */
     113        while (1);
     114}
     115
     116void abort(void)
     117{
     118        __SYSCALL1(SYS_TASK_EXIT, true);
     119       
     120        /* Unreachable */
     121        while (1);
    99122}
    100123
  • uspace/lib/c/generic/loader.c

    r22027b6e r8b5690f  
    3333 */
    3434
    35 #include <ipc/ipc.h>
    3635#include <ipc/loader.h>
    3736#include <ipc/services.h>
     37#include <ipc/ns.h>
    3838#include <libc.h>
    3939#include <task.h>
     
    6363loader_t *loader_connect(void)
    6464{
    65         int phone_id = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_LOAD, 0, 0);
     65        int phone_id = service_connect_blocking(SERVICE_LOAD, 0, 0);
    6666        if (phone_id < 0)
    6767                return NULL;
     
    319319                return rc;
    320320       
    321         ipc_hangup(ldr->phone_id);
     321        async_hangup(ldr->phone_id);
    322322        ldr->phone_id = 0;
    323323        return EOK;
     
    337337void loader_abort(loader_t *ldr)
    338338{
    339         ipc_hangup(ldr->phone_id);
     339        async_hangup(ldr->phone_id);
    340340        ldr->phone_id = 0;
    341341}
  • uspace/lib/c/generic/malloc.c

    r22027b6e r8b5690f  
    4545#include <futex.h>
    4646#include <adt/gcdlcm.h>
     47#include "private/malloc.h"
    4748
    4849/* Magic used in heap headers. */
     
    215216/** Initialize the heap allocator
    216217 *
    217  * Find how much physical memory we have and create
    218  * the heap management structures that mark the whole
    219  * physical memory as a single free block.
    220  *
    221  */
    222 void __heap_init(void)
    223 {
    224         futex_down(&malloc_futex);
    225        
    226         if (as_area_create((void *) &_heap, PAGE_SIZE,
    227             AS_AREA_WRITE | AS_AREA_READ)) {
    228                 heap_pages = 1;
    229                 heap_start = (void *) ALIGN_UP((uintptr_t) &_heap, BASE_ALIGN);
    230                 heap_end =
    231                     (void *) ALIGN_DOWN(((uintptr_t) &_heap) + PAGE_SIZE, BASE_ALIGN);
    232                
    233                 /* Make the entire area one large block. */
    234                 block_init(heap_start, heap_end - heap_start, true);
    235         }
    236        
    237         futex_up(&malloc_futex);
     218 * Create initial heap memory area. This routine is
     219 * only called from libc initialization, thus we do not
     220 * take any locks.
     221 *
     222 */
     223void __malloc_init(void)
     224{
     225        if (!as_area_create((void *) &_heap, PAGE_SIZE,
     226            AS_AREA_WRITE | AS_AREA_READ))
     227                abort();
     228       
     229        heap_pages = 1;
     230        heap_start = (void *) ALIGN_UP((uintptr_t) &_heap, BASE_ALIGN);
     231        heap_end =
     232            (void *) ALIGN_DOWN(((uintptr_t) &_heap) + PAGE_SIZE, BASE_ALIGN);
     233       
     234        /* Make the entire area one large block. */
     235        block_init(heap_start, heap_end - heap_start, true);
    238236}
    239237
  • uspace/lib/c/generic/net/icmp_api.c

    r22027b6e r8b5690f  
    4141#include <net/modules.h>
    4242#include <net/ip_codes.h>
    43 
    4443#include <async.h>
    4544#include <sys/types.h>
    4645#include <sys/time.h>
    4746#include <errno.h>
    48 
    49 #include <ipc/ipc.h>
    5047#include <ipc/services.h>
    5148#include <ipc/icmp.h>
  • uspace/lib/c/generic/net/icmp_common.c

    r22027b6e r8b5690f  
    2727 */
    2828
    29 /** @addtogroup libc 
     29/** @addtogroup libc
    3030 *  @{
    3131 */
     
    3838#include <net/modules.h>
    3939#include <net/icmp_common.h>
    40 
    4140#include <ipc/services.h>
    4241#include <ipc/icmp.h>
    43 
    4442#include <sys/time.h>
    4543#include <async.h>
    4644
    47 /** Connects to the ICMP module.
     45/** Connect to the ICMP module.
    4846 *
    49  * @param service       The ICMP module service. Ignored parameter.
    50  * @param[in] timeout   The connection timeout in microseconds. No timeout if
    51  *                      set to zero.
    52  * @return              The ICMP module phone on success.
    53  * @return              ETIMEOUT if the connection timeouted.
     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.
     52 *
    5453 */
    55 int icmp_connect_module(services_t service, suseconds_t timeout)
     54int icmp_connect_module(suseconds_t timeout)
    5655{
    57         int phone;
    58 
    59         phone = connect_to_service_timeout(SERVICE_ICMP, timeout);
    60         if (phone >= 0)
    61                 async_req_0_0(phone, NET_ICMP_INIT);
    62 
    63         return phone;
     56        return connect_to_service_timeout(SERVICE_ICMP, timeout);
    6457}
    6558
  • uspace/lib/c/generic/net/modules.c

    r22027b6e r8b5690f  
    3232
    3333/** @file
    34  * Generic module functions implementation. 
     34 * Generic module functions implementation.
    3535 *
    3636 * @todo MAKE IT POSSIBLE TO REMOVE THIS FILE VIA EITHER REPLACING PART OF ITS
     
    4343#include <errno.h>
    4444#include <sys/time.h>
    45 
    46 #include <ipc/ipc.h>
    4745#include <ipc/services.h>
    48 
    4946#include <net/modules.h>
    5047
     
    5249#define MODULE_WAIT_TIME        (10 * 1000)
    5350
    54 /** Answers the call.
    55  *
    56  * @param[in] callid    The call identifier.
    57  * @param[in] result    The message processing result.
    58  * @param[in] answer    The message processing answer.
    59  * @param[in] answer_count The number of answer parameters.
    60  */
    61 void
    62 answer_call(ipc_callid_t callid, int result, ipc_call_t *answer,
    63     int answer_count)
    64 {
    65         /* Choose the most efficient answer function */
    66         if (answer || (!answer_count)) {
    67                 switch (answer_count) {
     51/** Answer a call.
     52 *
     53 * @param[in] callid Call identifier.
     54 * @param[in] result Message processing result.
     55 * @param[in] answer Message processing answer.
     56 * @param[in] count  Number of answer parameters.
     57 *
     58 */
     59void answer_call(ipc_callid_t callid, int result, ipc_call_t *answer,
     60    size_t count)
     61{
     62        /* Choose the most efficient function */
     63        if ((answer != NULL) || (count == 0)) {
     64                switch (count) {
    6865                case 0:
    69                         ipc_answer_0(callid, (sysarg_t) result);
     66                        async_answer_0(callid, (sysarg_t) result);
    7067                        break;
    7168                case 1:
    72                         ipc_answer_1(callid, (sysarg_t) result,
     69                        async_answer_1(callid, (sysarg_t) result,
    7370                            IPC_GET_ARG1(*answer));
    7471                        break;
    7572                case 2:
    76                         ipc_answer_2(callid, (sysarg_t) result,
     73                        async_answer_2(callid, (sysarg_t) result,
    7774                            IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer));
    7875                        break;
    7976                case 3:
    80                         ipc_answer_3(callid, (sysarg_t) result,
     77                        async_answer_3(callid, (sysarg_t) result,
    8178                            IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer),
    8279                            IPC_GET_ARG3(*answer));
    8380                        break;
    8481                case 4:
    85                         ipc_answer_4(callid, (sysarg_t) result,
     82                        async_answer_4(callid, (sysarg_t) result,
    8683                            IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer),
    8784                            IPC_GET_ARG3(*answer), IPC_GET_ARG4(*answer));
     
    8986                case 5:
    9087                default:
    91                         ipc_answer_5(callid, (sysarg_t) result,
     88                        async_answer_5(callid, (sysarg_t) result,
    9289                            IPC_GET_ARG1(*answer), IPC_GET_ARG2(*answer),
    9390                            IPC_GET_ARG3(*answer), IPC_GET_ARG4(*answer),
     
    137134    sysarg_t arg3, async_client_conn_t client_receiver, suseconds_t timeout)
    138135{
    139         int rc;
    140        
    141136        /* Connect to the needed service */
    142137        int phone = connect_to_service_timeout(need, timeout);
    143138        if (phone >= 0) {
    144139                /* Request the bidirectional connection */
    145                 sysarg_t phonehash;
    146                
    147                 rc = ipc_connect_to_me(phone, arg1, arg2, arg3, &phonehash);
     140                int rc = async_connect_to_me(phone, arg1, arg2, arg3, client_receiver);
    148141                if (rc != EOK) {
    149                         ipc_hangup(phone);
     142                        async_hangup(phone);
    150143                        return rc;
    151144                }
    152                 async_new_connection(phonehash, 0, NULL, client_receiver);
    153145        }
    154146       
     
    228220}
    229221
    230 /** Refreshes answer structure and parameters count.
    231  *
    232  * Erases all attributes.
    233  *
    234  * @param[in,out] answer The message processing answer structure.
    235  * @param[in,out] answer_count The number of answer parameters.
    236  */
    237 void refresh_answer(ipc_call_t *answer, int *answer_count)
    238 {
    239         if (answer_count)
    240                 *answer_count = 0;
    241 
    242         if (answer) {
     222/** Refresh answer structure and argument count.
     223 *
     224 * Erase all arguments.
     225 *
     226 * @param[in,out] answer Message processing answer structure.
     227 * @param[in,out] count  Number of answer arguments.
     228 *
     229 */
     230void refresh_answer(ipc_call_t *answer, size_t *count)
     231{
     232        if (count != NULL)
     233                *count = 0;
     234       
     235        if (answer != NULL) {
    243236                IPC_SET_RETVAL(*answer, 0);
    244                 /* Just to be precise */
    245237                IPC_SET_IMETHOD(*answer, 0);
    246238                IPC_SET_ARG1(*answer, 0);
  • uspace/lib/c/generic/net/socket_client.c

    r22027b6e r8b5690f  
    4343#include <stdlib.h>
    4444#include <errno.h>
    45 
     45#include <task.h>
    4646#include <ipc/services.h>
    4747#include <ipc/socket.h>
    48 
    4948#include <net/modules.h>
    5049#include <net/in.h>
     
    278277        }
    279278
    280         ipc_answer_0(callid, (sysarg_t) rc);
     279        async_answer_0(callid, (sysarg_t) rc);
    281280        goto loop;
    282281}
     
    687686
    688687        /* Read address */
    689         ipc_data_read_start(socket->phone, cliaddr, *addrlen);
     688        async_data_read_start(socket->phone, cliaddr, *addrlen);
    690689        fibril_rwlock_write_unlock(&socket_globals.lock);
    691690        async_wait_for(message_id, &ipc_result);
  • uspace/lib/c/generic/private/async.h

    r22027b6e r8b5690f  
    3333 */
    3434
    35 #ifndef LIBC_ASYNC_PRIV_H_
    36 #define LIBC_ASYNC_PRIV_H_
     35#ifndef LIBC_PRIVATE_ASYNC_H_
     36#define LIBC_PRIVATE_ASYNC_H_
    3737
    3838#include <adt/list.h>
     
    5151        /** If true, we have timed out. */
    5252        bool occurred;
    53 
     53       
    5454        /** Expiration time. */
    5555        struct timeval expires;
     
    6565} wu_event_t;
    6666
    67 
    6867/** Structures of this type represent a waiting fibril. */
    6968typedef struct {
     
    7372        /** If true, this fibril is currently active. */
    7473        bool active;
    75 
     74       
    7675        /** Timeout wait data. */
    7776        to_event_t to_event;
     
    8079} awaiter_t;
    8180
    82 extern void async_insert_timeout(awaiter_t *wd);
     81extern void __async_init(void);
     82extern void async_insert_timeout(awaiter_t *);
    8383
    8484#endif
  • uspace/lib/c/generic/private/async_sess.h

    r22027b6e r8b5690f  
    11/*
    2  * Copyright (c) 2006 Ondrej Palkovsky
     2 * Copyright (c) 2011 Martin Decky
    33 * All rights reserved.
    44 *
     
    3333 */
    3434
    35 #include <stdio.h>
    36 #include <stdlib.h>
     35#ifndef LIBC_PRIVATE_ASYNC_SESS_H_
     36#define LIBC_PRIVATE_ASYNC_SESS_H_
    3737
    38 /* TODO
    39 void errx(int __status, __const char *__format, ...)
    40 {
    41         _exit(0);
    42 }
    43 */
     38extern void __async_sess_init(void);
     39
     40#endif
    4441
    4542/** @}
  • uspace/lib/c/generic/private/io.h

    r22027b6e r8b5690f  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2011 Martin Decky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup ip
     29/** @addtogroup libc
    3030 * @{
    3131 */
    32 
    3332/** @file
    34  * IP module functions.
    35  * The functions are used as IP module entry points.
    3633 */
    3734
    38 #ifndef NET_IP_MODULE_H_
    39 #define NET_IP_MODULE_H_
     35#ifndef LIBC_PRIVATE_IO_H_
     36#define LIBC_PRIVATE_IO_H_
    4037
    41 #include <ipc/ipc.h>
     38#include <vfs/vfs.h>
    4239
    43 extern int ip_initialize(async_client_conn_t);
    44 extern int ip_message_standalone(ipc_callid_t, ipc_call_t *, ipc_call_t *,
    45     int *);
     40extern void __stdio_init(int filc, fdi_node_t *filv[]);
     41extern void __stdio_done(void);
    4642
    4743#endif
  • uspace/lib/c/generic/private/libc.h

    r22027b6e r8b5690f  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2011 Martin Decky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup arp
     29/** @addtogroup libc
    3030 * @{
    3131 */
    32 
    3332/** @file
    34  * ARP module functions.
    35  * The functions are used as ARP module entry points.
    3633 */
    3734
    38 #ifndef NET_ARP_MODULE_H_
    39 #define NET_ARP_MODULE_H_
     35#ifndef LIBC_PRIVATE_LIBC_H_
     36#define LIBC_PRIVATE_LIBC_H_
    4037
    41 #include <ipc/ipc.h>
    42 #include <async.h>
    43 
    44 extern int arp_initialize(async_client_conn_t);
    45 extern int arp_message_standalone(ipc_callid_t, ipc_call_t *, ipc_call_t *,
    46     int *);
     38extern int main(int, char *[]);
     39extern void __main(void *) __attribute__((noreturn));
    4740
    4841#endif
  • uspace/lib/c/generic/private/thread.h

    r22027b6e r8b5690f  
    11/*
    2  * Copyright (c) 2008 Lukas Mejdrech
     2 * Copyright (c) 2011 Martin Decky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup tcp
     29/** @addtogroup libc
    3030 * @{
    3131 */
    32 
    3332/** @file
    34  * TCP module functions.
    35  * The functions are used as TCP module entry points.
    3633 */
    3734
    38 #ifndef NET_TCP_MODULE_H_
    39 #define NET_TCP_MODULE_H_
     35#ifndef LIBC_PRIVATE_THREAD_H_
     36#define LIBC_PRIVATE_THREAD_H_
    4037
    41 #include <async.h>
    42 #include <ipc/ipc.h>
     38#include <kernel/proc/uarg.h>
    4339
    44 extern int tcp_initialize(async_client_conn_t);
    45 extern int tcp_message_standalone(ipc_callid_t, ipc_call_t *, ipc_call_t *,
    46     int *);
     40extern void __thread_entry(void);
     41extern void __thread_main(uspace_arg_t *);
    4742
    4843#endif
  • uspace/lib/c/generic/stats.c

    r22027b6e r8b5690f  
    3636#include <stats.h>
    3737#include <sysinfo.h>
    38 #include <assert.h>
    3938#include <errno.h>
    4039#include <stdio.h>
    4140#include <inttypes.h>
     41#include <malloc.h>
    4242
    4343#define SYSINFO_STATS_MAX_PATH  64
     
    7171            (stats_cpu_t *) sysinfo_get_data("system.cpus", &size);
    7272       
    73         assert((size % sizeof(stats_cpu_t)) == 0);
     73        if ((size % sizeof(stats_cpu_t)) != 0) {
     74                if (stats_cpus != NULL)
     75                        free(stats_cpus);
     76                *count = 0;
     77                return NULL;
     78        }
    7479       
    7580        *count = size / sizeof(stats_cpu_t);
     
    9196            (stats_physmem_t *) sysinfo_get_data("system.physmem", &size);
    9297       
    93         assert((size == sizeof(stats_physmem_t)) || (size == 0));
     98        if (size != sizeof(stats_physmem_t)) {
     99                if (stats_physmem != NULL)
     100                        free(stats_physmem);
     101                return NULL;
     102        }
    94103       
    95104        return stats_physmem;
     
    111120            (stats_task_t *) sysinfo_get_data("system.tasks", &size);
    112121       
    113         assert((size % sizeof(stats_task_t)) == 0);
     122        if ((size % sizeof(stats_task_t)) != 0) {
     123                if (stats_tasks != NULL)
     124                        free(stats_tasks);
     125                *count = 0;
     126                return NULL;
     127        }
    114128       
    115129        *count = size / sizeof(stats_task_t);
     
    135149            (stats_task_t *) sysinfo_get_data(name, &size);
    136150       
    137         assert((size == sizeof(stats_task_t)) || (size == 0));
     151        if (size != sizeof(stats_task_t)) {
     152                if (stats_task != NULL)
     153                        free(stats_task);
     154                return NULL;
     155        }
    138156       
    139157        return stats_task;
     
    155173            (stats_thread_t *) sysinfo_get_data("system.threads", &size);
    156174       
    157         assert((size % sizeof(stats_thread_t)) == 0);
     175        if ((size % sizeof(stats_thread_t)) != 0) {
     176                if (stats_threads != NULL)
     177                        free(stats_threads);
     178                *count = 0;
     179                return NULL;
     180        }
    158181       
    159182        *count = size / sizeof(stats_thread_t);
     
    179202            (stats_thread_t *) sysinfo_get_data(name, &size);
    180203       
    181         assert((size == sizeof(stats_thread_t)) || (size == 0));
     204        if (size != sizeof(stats_thread_t)) {
     205                if (stats_thread != NULL)
     206                        free(stats_thread);
     207                return NULL;
     208        }
    182209       
    183210        return stats_thread;
     
    199226            (stats_exc_t *) sysinfo_get_data("system.exceptions", &size);
    200227       
    201         assert((size % sizeof(stats_exc_t)) == 0);
     228        if ((size % sizeof(stats_exc_t)) != 0) {
     229                if (stats_exceptions != NULL)
     230                        free(stats_exceptions);
     231                *count = 0;
     232                return NULL;
     233        }
    202234       
    203235        *count = size / sizeof(stats_exc_t);
     
    217249{
    218250        char name[SYSINFO_STATS_MAX_PATH];
    219         snprintf(name, SYSINFO_STATS_MAX_PATH, "system.exceptionss.%u", excn);
     251        snprintf(name, SYSINFO_STATS_MAX_PATH, "system.exceptions.%u", excn);
    220252       
    221253        size_t size = 0;
     
    223255            (stats_exc_t *) sysinfo_get_data(name, &size);
    224256       
    225         assert((size == sizeof(stats_exc_t)) || (size == 0));
     257        if (size != sizeof(stats_exc_t)) {
     258                if (stats_exception != NULL)
     259                        free(stats_exception);
     260                return NULL;
     261        }
    226262       
    227263        return stats_exception;
     
    243279            (load_t *) sysinfo_get_data("system.load", &size);
    244280       
    245         assert((size % sizeof(load_t)) == 0);
     281        if ((size % sizeof(load_t)) != 0) {
     282                if (load != NULL)
     283                        free(load);
     284                *count = 0;
     285                return NULL;
     286        }
    246287       
    247288        *count = size / sizeof(load_t);
  • uspace/lib/c/generic/sysinfo.c

    r22027b6e r8b5690f  
    9696void *sysinfo_get_data(const char *path, size_t *size)
    9797{
    98         /* The binary data size might change during time.
    99            Unfortunatelly we cannot allocate the buffer
    100            and transfer the data as a single atomic operation.
     98        /*
     99         * The binary data size might change during time.
     100         * Unfortunatelly we cannot allocate the buffer
     101         * and transfer the data as a single atomic operation.
     102         */
    101103       
    102            Let's hope that the number of iterations is bounded
    103            in common cases. */
    104        
    105         void *data = NULL;
    106        
    107         while (true) {
    108                 /* Get the binary data size */
    109                 int ret = sysinfo_get_data_size(path, size);
    110                 if ((ret != EOK) || (size == 0)) {
    111                         /* Not a binary data item
    112                            or an empty item */
    113                         break;
    114                 }
    115                
    116                 data = realloc(data, *size);
    117                 if (data == NULL)
    118                         break;
    119                
    120                 /* Get the data */
    121                 ret = __SYSCALL4(SYS_SYSINFO_GET_DATA, (sysarg_t) path,
    122                     (sysarg_t) str_size(path), (sysarg_t) data, (sysarg_t) *size);
    123                 if (ret == EOK)
    124                         return data;
    125                
    126                 if (ret != ENOMEM) {
    127                         /* The failure to get the data was not caused
    128                            by wrong buffer size */
    129                         break;
    130                 }
     104        /* Get the binary data size */
     105        int ret = sysinfo_get_data_size(path, size);
     106        if ((ret != EOK) || (size == 0)) {
     107                /*
     108                 * Not a binary data item
     109                 * or an empty item.
     110                 */
     111                *size = 0;
     112                return NULL;
    131113        }
    132114       
    133         if (data != NULL)
    134                 free(data);
     115        void *data = malloc(*size);
     116        if (data == NULL) {
     117                *size = 0;
     118                return NULL;
     119        }
    135120       
     121        /* Get the data */
     122        size_t sz;
     123        ret = __SYSCALL5(SYS_SYSINFO_GET_DATA, (sysarg_t) path,
     124            (sysarg_t) str_size(path), (sysarg_t) data, (sysarg_t) *size,
     125            (sysarg_t) &sz);
     126        if (ret == EOK) {
     127                *size = sz;
     128                return data;
     129        }
     130       
     131        free(data);
    136132        *size = 0;
    137133        return NULL;
  • uspace/lib/c/generic/thread.c

    r22027b6e r8b5690f  
    3131 */
    3232/** @file
    33  */ 
     33 */
    3434
    3535#include <thread.h>
     
    4141#include <str.h>
    4242#include <async.h>
     43#include "private/thread.h"
    4344
    4445#ifndef THREAD_INITIAL_STACK_PAGES_NO
     
    5051 * This function is called from __thread_entry() and is used
    5152 * to call the thread's implementing function and perform cleanup
    52  * and exit when thread returns back. Do not call this function
    53  * directly.
     53 * and exit when thread returns back.
    5454 *
    5555 * @param uarg Pointer to userspace argument structure.
     56 *
    5657 */
    5758void __thread_main(uspace_arg_t *uarg)
    5859{
    59         fibril_t *f;
    60 
    61         f = fibril_setup();
    62         __tcb_set(f->tcb);
    63 
     60        fibril_t *fibril = fibril_setup();
     61        if (fibril == NULL)
     62                thread_exit(0);
     63       
     64        __tcb_set(fibril->tcb);
     65       
    6466        uarg->uspace_thread_function(uarg->uspace_thread_arg);
    65         /* XXX: we cannot free the userspace stack while running on it */
    66 //      free(uarg->uspace_stack);
    67 //      free(uarg);
    68 
     67        /* XXX: we cannot free the userspace stack while running on it
     68                free(uarg->uspace_stack);
     69                free(uarg);
     70        */
     71       
    6972        /* If there is a manager, destroy it */
    7073        async_destroy_manager();
    71         fibril_teardown(f);
    72 
     74        fibril_teardown(fibril);
     75       
    7376        thread_exit(0);
    7477}
     
    127130 *
    128131 * @param status Exit status. Currently not used.
     132 *
    129133 */
    130134void thread_exit(int status)
    131135{
    132136        __SYSCALL1(SYS_THREAD_EXIT, (sysarg_t) status);
    133         for (;;)
    134                 ;
     137       
     138        /* Unreachable */
     139        while (1);
    135140}
    136141
  • uspace/lib/c/generic/time.c

    r22027b6e r8b5690f  
    3434
    3535#include <sys/time.h>
    36 #include <unistd.h>
    37 #include <ipc/ipc.h>
    38 #include <stdio.h>
     36#include <time.h>
     37#include <bool.h>
    3938#include <arch/barrier.h>
    40 #include <unistd.h>
    41 #include <atomic.h>
    42 #include <sysinfo.h>
    43 #include <ipc/services.h>
    44 #include <libc.h>
    45 
     39#include <macros.h>
     40#include <errno.h>
    4641#include <sysinfo.h>
    4742#include <as.h>
    4843#include <ddi.h>
    49 
    50 #include <time.h>
    51 
    52 /* Pointers to public variables with time */
     44#include <libc.h>
     45
     46/** Pointer to kernel shared variables with time */
    5347struct {
    5448        volatile sysarg_t seconds1;
     
    5953/** Add microseconds to given timeval.
    6054 *
    61  * @param tv            Destination timeval.
    62  * @param usecs         Number of microseconds to add.
     55 * @param tv    Destination timeval.
     56 * @param usecs Number of microseconds to add.
     57 *
    6358 */
    6459void tv_add(struct timeval *tv, suseconds_t usecs)
     
    6661        tv->tv_sec += usecs / 1000000;
    6762        tv->tv_usec += usecs % 1000000;
     63       
    6864        if (tv->tv_usec > 1000000) {
    6965                tv->tv_sec++;
     
    7470/** Subtract two timevals.
    7571 *
    76  * @param tv1           First timeval.
    77  * @param tv2           Second timeval.
    78  *
    79  * @return              Return difference between tv1 and tv2 (tv1 - tv2) in
    80  *                      microseconds.
     72 * @param tv1 First timeval.
     73 * @param tv2 Second timeval.
     74 *
     75 * @return Difference between tv1 and tv2 (tv1 - tv2) in
     76 *         microseconds.
     77 *
    8178 */
    8279suseconds_t tv_sub(struct timeval *tv1, struct timeval *tv2)
    8380{
    84         suseconds_t result;
    85 
    86         result = tv1->tv_usec - tv2->tv_usec;
    87         result += (tv1->tv_sec - tv2->tv_sec) * 1000000;
    88 
    89         return result;
     81        return (tv1->tv_usec - tv2->tv_usec) +
     82            ((tv1->tv_sec - tv2->tv_sec) * 1000000);
    9083}
    9184
    9285/** Decide if one timeval is greater than the other.
    9386 *
    94  * @param t1            First timeval.
    95  * @param t2            Second timeval.
    96  *
    97  * @return              Return true tv1 is greater than tv2. Otherwise return
    98  *                      false.
     87 * @param t1 First timeval.
     88 * @param t2 Second timeval.
     89 *
     90 * @return True if tv1 is greater than tv2.
     91 * @return False otherwise.
     92 *
    9993 */
    10094int tv_gt(struct timeval *tv1, struct timeval *tv2)
    10195{
    10296        if (tv1->tv_sec > tv2->tv_sec)
    103                 return 1;
    104         if (tv1->tv_sec == tv2->tv_sec && tv1->tv_usec > tv2->tv_usec)
    105                 return 1;
    106         return 0;
     97                return true;
     98       
     99        if ((tv1->tv_sec == tv2->tv_sec) && (tv1->tv_usec > tv2->tv_usec))
     100                return true;
     101       
     102        return false;
    107103}
    108104
    109105/** Decide if one timeval is greater than or equal to the other.
    110106 *
    111  * @param tv1           First timeval.
    112  * @param tv2           Second timeval.
    113  *
    114  * @return              Return true if tv1 is greater than or equal to tv2.
    115  *                      Otherwise return false.
     107 * @param tv1 First timeval.
     108 * @param tv2 Second timeval.
     109 *
     110 * @return True if tv1 is greater than or equal to tv2.
     111 * @return False otherwise.
     112 *
    116113 */
    117114int tv_gteq(struct timeval *tv1, struct timeval *tv2)
    118115{
    119116        if (tv1->tv_sec > tv2->tv_sec)
    120                 return 1;
    121         if (tv1->tv_sec == tv2->tv_sec && tv1->tv_usec >= tv2->tv_usec)
    122                 return 1;
    123         return 0;
    124 }
    125 
    126 
    127 /** POSIX gettimeofday
    128  *
    129  * The time variables are memory mapped(RO) from kernel, which updates
    130  * them periodically. As it is impossible to read 2 values atomically, we
    131  * use a trick: First read a seconds, then read microseconds, then
    132  * read seconds again. If a second elapsed in the meantime, set it to zero.
    133  * This provides assurance, that at least the
    134  * sequence of subsequent gettimeofday calls is ordered.
     117                return true;
     118       
     119        if ((tv1->tv_sec == tv2->tv_sec) && (tv1->tv_usec >= tv2->tv_usec))
     120                return true;
     121       
     122        return false;
     123}
     124
     125/** Get time of day
     126 *
     127 * The time variables are memory mapped (read-only) from kernel which
     128 * updates them periodically.
     129 *
     130 * As it is impossible to read 2 values atomically, we use a trick:
     131 * First we read the seconds, then we read the microseconds, then we
     132 * read the seconds again. If a second elapsed in the meantime, set
     133 * the microseconds to zero.
     134 *
     135 * This assures that the values returned by two subsequent calls
     136 * to gettimeofday() are monotonous.
     137 *
    135138 */
    136139int gettimeofday(struct timeval *tv, struct timezone *tz)
    137140{
    138         void *mapping;
    139         sysarg_t s1, s2;
    140         int rights;
    141         int res;
    142 
    143         if (!ktime) {
    144                 mapping = as_get_mappable_page(PAGE_SIZE);
    145                 /* Get the mapping of kernel clock */
    146                 res = ipc_share_in_start_1_1(PHONE_NS, mapping, PAGE_SIZE,
    147                     SERVICE_MEM_REALTIME, &rights);
    148                 if (res) {
    149                         printf("Failed to initialize timeofday memarea\n");
    150                         _exit(1);
     141        if (ktime == NULL) {
     142                uintptr_t faddr;
     143                int rc = sysinfo_get_value("clock.faddr", &faddr);
     144                if (rc != EOK) {
     145                        errno = rc;
     146                        return -1;
    151147                }
    152                 if (!(rights & AS_AREA_READ)) {
    153                         printf("Received bad rights on time area: %X\n",
    154                             rights);
    155                         as_area_destroy(mapping);
    156                         _exit(1);
     148               
     149                void *addr = as_get_mappable_page(PAGE_SIZE);
     150                if (addr == NULL) {
     151                        errno = ENOMEM;
     152                        return -1;
    157153                }
    158                 ktime = mapping;
    159         }
     154               
     155                rc = physmem_map((void *) faddr, addr, 1,
     156                    AS_AREA_READ | AS_AREA_CACHEABLE);
     157                if (rc != EOK) {
     158                        as_area_destroy(addr);
     159                        errno = rc;
     160                        return -1;
     161                }
     162               
     163                ktime = addr;
     164        }
     165       
    160166        if (tz) {
    161167                tz->tz_minuteswest = 0;
    162168                tz->tz_dsttime = DST_NONE;
    163169        }
    164 
    165         s2 = ktime->seconds2;
     170       
     171        sysarg_t s2 = ktime->seconds2;
     172       
    166173        read_barrier();
    167174        tv->tv_usec = ktime->useconds;
     175       
    168176        read_barrier();
    169         s1 = ktime->seconds1;
     177        sysarg_t s1 = ktime->seconds1;
     178       
    170179        if (s1 != s2) {
     180                tv->tv_sec = max(s1, s2);
    171181                tv->tv_usec = 0;
    172                 tv->tv_sec = s1 > s2 ? s1 : s2;
    173182        } else
    174183                tv->tv_sec = s1;
    175 
     184       
    176185        return 0;
    177186}
     
    180189{
    181190        struct timeval tv;
    182 
    183191        if (gettimeofday(&tv, NULL))
    184192                return (time_t) -1;
     193       
    185194        if (tloc)
    186195                *tloc = tv.tv_sec;
     196       
    187197        return tv.tv_sec;
    188198}
    189199
    190 /** Wait unconditionally for specified number of microseconds */
     200/** Wait unconditionally for specified number of microseconds
     201 *
     202 */
    191203int usleep(useconds_t usec)
    192204{
     
    195207}
    196208
    197 /** Wait unconditionally for specified number of seconds */
     209/** Wait unconditionally for specified number of seconds
     210 *
     211 */
    198212unsigned int sleep(unsigned int sec)
    199213{
    200         /* Sleep in 1000 second steps to support
    201            full argument range */
     214        /*
     215         * Sleep in 1000 second steps to support
     216         * full argument range
     217         */
     218       
    202219        while (sec > 0) {
    203220                unsigned int period = (sec > 1000) ? 1000 : sec;
    204        
     221               
    205222                usleep(period * 1000000);
    206223                sec -= period;
    207224        }
     225       
    208226        return 0;
    209227}
  • uspace/lib/c/generic/udebug.c

    r22027b6e r8b5690f  
    3131 */
    3232/** @file
    33  */ 
     33 */
    3434
    3535#include <udebug.h>
    3636#include <sys/types.h>
    37 #include <ipc/ipc.h>
    3837#include <async.h>
    3938
  • uspace/lib/c/generic/vfs/vfs.c

    r22027b6e r8b5690f  
    11/*
    2  * Copyright (c) 2008 Jakub Jermar 
     2 * Copyright (c) 2008 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    4343#include <sys/stat.h>
    4444#include <sys/types.h>
    45 #include <ipc/ipc.h>
    4645#include <ipc/services.h>
     46#include <ipc/ns.h>
    4747#include <async.h>
    48 #include <atomic.h>
    49 #include <futex.h>
     48#include <fibril_synch.h>
    5049#include <errno.h>
     50#include <assert.h>
    5151#include <str.h>
    5252#include <devmap.h>
     
    5454#include <ipc/devmap.h>
    5555
     56static async_sess_t vfs_session;
     57
     58static FIBRIL_MUTEX_INITIALIZE(vfs_phone_mutex);
    5659static int vfs_phone = -1;
    57 static futex_t vfs_phone_futex = FUTEX_INITIALIZER;
    58 static futex_t cwd_futex = FUTEX_INITIALIZER;
     60
     61static FIBRIL_MUTEX_INITIALIZE(cwd_mutex);
    5962
    6063static int cwd_fd = -1;
     
    6770        char *ncwd_path_nc;
    6871
    69         futex_down(&cwd_futex);
     72        fibril_mutex_lock(&cwd_mutex);
    7073        size_t size = str_size(path);
    7174        if (*path != '/') {
    7275                if (!cwd_path) {
    73                         futex_up(&cwd_futex);
     76                        fibril_mutex_unlock(&cwd_mutex);
    7477                        return NULL;
    7578                }
    7679                ncwd_path_nc = malloc(cwd_size + 1 + size + 1);
    7780                if (!ncwd_path_nc) {
    78                         futex_up(&cwd_futex);
     81                        fibril_mutex_unlock(&cwd_mutex);
    7982                        return NULL;
    8083                }
     
    8588                ncwd_path_nc = malloc(size + 1);
    8689                if (!ncwd_path_nc) {
    87                         futex_up(&cwd_futex);
     90                        fibril_mutex_unlock(&cwd_mutex);
    8891                        return NULL;
    8992                }
     
    9396        ncwd_path = canonify(ncwd_path_nc, retlen);
    9497        if (!ncwd_path) {
    95                 futex_up(&cwd_futex);
     98                fibril_mutex_unlock(&cwd_mutex);
    9699                free(ncwd_path_nc);
    97100                return NULL;
     
    105108        free(ncwd_path_nc);
    106109        if (!ncwd_path) {
    107                 futex_up(&cwd_futex);
     110                fibril_mutex_unlock(&cwd_mutex);
    108111                return NULL;
    109112        }
    110         futex_up(&cwd_futex);
     113        fibril_mutex_unlock(&cwd_mutex);
    111114        return ncwd_path;
    112115}
    113116
     117/** Connect to VFS service and create session. */
    114118static void vfs_connect(void)
    115119{
    116120        while (vfs_phone < 0)
    117                 vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0);
     121                vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
     122       
     123        async_session_create(&vfs_session, vfs_phone, 0);
     124}
     125
     126/** Start an async exchange on the VFS session.
     127 *
     128 * @return              New phone to be used during the exchange.
     129 */
     130static int vfs_exchange_begin(void)
     131{
     132        fibril_mutex_lock(&vfs_phone_mutex);
     133        if (vfs_phone < 0)
     134                vfs_connect();
     135        fibril_mutex_unlock(&vfs_phone_mutex);
     136
     137        return async_exchange_begin(&vfs_session);
     138}
     139
     140/** End an async exchange on the VFS session.
     141 *
     142 * @param phone         Phone used during the exchange.
     143 */
     144static void vfs_exchange_end(int phone)
     145{
     146        async_exchange_end(&vfs_session, phone);
    118147}
    119148
     
    154183        }
    155184       
    156         futex_down(&vfs_phone_futex);
    157         async_serialize_start();
    158         vfs_connect();
    159        
     185        int vfs_phone = vfs_exchange_begin();
     186
    160187        sysarg_t rc_orig;
    161188        aid_t req = async_send_2(vfs_phone, VFS_IN_MOUNT, devmap_handle, flags, NULL);
    162189        sysarg_t rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    163190        if (rc != EOK) {
    164                 async_wait_for(req, &rc_orig);
    165                 async_serialize_end();
    166                 futex_up(&vfs_phone_futex);
     191                vfs_exchange_end(vfs_phone);
    167192                free(mpa);
     193                async_wait_for(req, &rc_orig);
    168194               
    169195                if (null_id != -1)
     
    178204        rc = async_data_write_start(vfs_phone, (void *) opts, str_size(opts));
    179205        if (rc != EOK) {
    180                 async_wait_for(req, &rc_orig);
    181                 async_serialize_end();
    182                 futex_up(&vfs_phone_futex);
     206                vfs_exchange_end(vfs_phone);
    183207                free(mpa);
     208                async_wait_for(req, &rc_orig);
    184209               
    185210                if (null_id != -1)
     
    194219        rc = async_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name));
    195220        if (rc != EOK) {
    196                 async_wait_for(req, &rc_orig);
    197                 async_serialize_end();
    198                 futex_up(&vfs_phone_futex);
     221                vfs_exchange_end(vfs_phone);
    199222                free(mpa);
     223                async_wait_for(req, &rc_orig);
    200224               
    201225                if (null_id != -1)
     
    211235        rc = async_req_0_0(vfs_phone, IPC_M_PING);
    212236        if (rc != EOK) {
    213                 async_wait_for(req, &rc_orig);
    214                 async_serialize_end();
    215                 futex_up(&vfs_phone_futex);
     237                vfs_exchange_end(vfs_phone);
    216238                free(mpa);
     239                async_wait_for(req, &rc_orig);
    217240               
    218241                if (null_id != -1)
     
    225248        }
    226249       
    227         async_wait_for(req, &rc);
    228         async_serialize_end();
    229         futex_up(&vfs_phone_futex);
     250        vfs_exchange_end(vfs_phone);
    230251        free(mpa);
     252        async_wait_for(req, &rc);
    231253       
    232254        if ((rc != EOK) && (null_id != -1))
     
    248270                return ENOMEM;
    249271       
    250         futex_down(&vfs_phone_futex);
    251         async_serialize_start();
    252         vfs_connect();
     272        int vfs_phone = vfs_exchange_begin();
    253273       
    254274        req = async_send_0(vfs_phone, VFS_IN_UNMOUNT, NULL);
    255275        rc = async_data_write_start(vfs_phone, (void *) mpa, mpa_size);
    256276        if (rc != EOK) {
    257                 async_wait_for(req, &rc_orig);
    258                 async_serialize_end();
    259                 futex_up(&vfs_phone_futex);
     277                vfs_exchange_end(vfs_phone);
    260278                free(mpa);
    261                 if (rc_orig == EOK)
    262                         return (int) rc;
    263                 else
    264                         return (int) rc_orig;
    265         }
    266        
    267 
    268         async_wait_for(req, &rc);
    269         async_serialize_end();
    270         futex_up(&vfs_phone_futex);
     279                async_wait_for(req, &rc_orig);
     280                if (rc_orig == EOK)
     281                        return (int) rc;
     282                else
     283                        return (int) rc_orig;
     284        }
     285       
     286
     287        vfs_exchange_end(vfs_phone);
    271288        free(mpa);
     289        async_wait_for(req, &rc);
    272290       
    273291        return (int) rc;
     
    276294static int open_internal(const char *abs, size_t abs_size, int lflag, int oflag)
    277295{
    278         futex_down(&vfs_phone_futex);
    279         async_serialize_start();
    280         vfs_connect();
     296        int vfs_phone = vfs_exchange_begin();
    281297       
    282298        ipc_call_t answer;
     
    285301       
    286302        if (rc != EOK) {
     303                vfs_exchange_end(vfs_phone);
     304
    287305                sysarg_t rc_orig;
    288306                async_wait_for(req, &rc_orig);
    289307               
    290                 async_serialize_end();
    291                 futex_up(&vfs_phone_futex);
    292                
    293                 if (rc_orig == EOK)
    294                         return (int) rc;
    295                 else
    296                         return (int) rc_orig;
    297         }
    298        
    299         async_wait_for(req, &rc);
    300         async_serialize_end();
    301         futex_up(&vfs_phone_futex);
     308                if (rc_orig == EOK)
     309                        return (int) rc;
     310                else
     311                        return (int) rc_orig;
     312        }
     313       
     314        vfs_exchange_end(vfs_phone);
     315        async_wait_for(req, &rc);
    302316       
    303317        if (rc != EOK)
     
    322336int open_node(fdi_node_t *node, int oflag)
    323337{
    324         futex_down(&vfs_phone_futex);
    325         async_serialize_start();
    326         vfs_connect();
     338        int vfs_phone = vfs_exchange_begin();
    327339       
    328340        ipc_call_t answer;
     
    330342            node->devmap_handle, node->index, oflag, &answer);
    331343       
    332         sysarg_t rc;
    333         async_wait_for(req, &rc);
    334         async_serialize_end();
    335         futex_up(&vfs_phone_futex);
     344        vfs_exchange_end(vfs_phone);
     345
     346        sysarg_t rc;
     347        async_wait_for(req, &rc);
    336348       
    337349        if (rc != EOK)
     
    345357        sysarg_t rc;
    346358       
    347         futex_down(&vfs_phone_futex);
    348         async_serialize_start();
    349         vfs_connect();
     359        int vfs_phone = vfs_exchange_begin();
    350360       
    351361        rc = async_req_1_0(vfs_phone, VFS_IN_CLOSE, fildes);
    352362       
    353         async_serialize_end();
    354         futex_up(&vfs_phone_futex);
     363        vfs_exchange_end(vfs_phone);
    355364       
    356365        return (int)rc;
     
    363372        aid_t req;
    364373
    365         futex_down(&vfs_phone_futex);
    366         async_serialize_start();
    367         vfs_connect();
     374        int vfs_phone = vfs_exchange_begin();
    368375       
    369376        req = async_send_1(vfs_phone, VFS_IN_READ, fildes, &answer);
    370377        rc = async_data_read_start(vfs_phone, (void *)buf, nbyte);
    371378        if (rc != EOK) {
     379                vfs_exchange_end(vfs_phone);
     380
    372381                sysarg_t rc_orig;
    373        
    374                 async_wait_for(req, &rc_orig);
    375                 async_serialize_end();
    376                 futex_up(&vfs_phone_futex);
     382                async_wait_for(req, &rc_orig);
     383
    377384                if (rc_orig == EOK)
    378385                        return (ssize_t) rc;
     
    380387                        return (ssize_t) rc_orig;
    381388        }
    382         async_wait_for(req, &rc);
    383         async_serialize_end();
    384         futex_up(&vfs_phone_futex);
     389        vfs_exchange_end(vfs_phone);
     390        async_wait_for(req, &rc);
    385391        if (rc == EOK)
    386392                return (ssize_t) IPC_GET_ARG1(answer);
     
    395401        aid_t req;
    396402
    397         futex_down(&vfs_phone_futex);
    398         async_serialize_start();
    399         vfs_connect();
     403        int vfs_phone = vfs_exchange_begin();
    400404       
    401405        req = async_send_1(vfs_phone, VFS_IN_WRITE, fildes, &answer);
    402406        rc = async_data_write_start(vfs_phone, (void *)buf, nbyte);
    403407        if (rc != EOK) {
     408                vfs_exchange_end(vfs_phone);
     409
    404410                sysarg_t rc_orig;
    405        
    406                 async_wait_for(req, &rc_orig);
    407                 async_serialize_end();
    408                 futex_up(&vfs_phone_futex);
     411                async_wait_for(req, &rc_orig);
     412
    409413                if (rc_orig == EOK)
    410414                        return (ssize_t) rc;
     
    412416                        return (ssize_t) rc_orig;
    413417        }
    414         async_wait_for(req, &rc);
    415         async_serialize_end();
    416         futex_up(&vfs_phone_futex);
     418        vfs_exchange_end(vfs_phone);
     419        async_wait_for(req, &rc);
    417420        if (rc == EOK)
    418421                return (ssize_t) IPC_GET_ARG1(answer);
     
    423426int fsync(int fildes)
    424427{
    425         futex_down(&vfs_phone_futex);
    426         async_serialize_start();
    427         vfs_connect();
     428        int vfs_phone = vfs_exchange_begin();
    428429       
    429430        sysarg_t rc = async_req_1_0(vfs_phone, VFS_IN_SYNC, fildes);
    430431       
    431         async_serialize_end();
    432         futex_up(&vfs_phone_futex);
     432        vfs_exchange_end(vfs_phone);
    433433       
    434434        return (int) rc;
     
    437437off64_t lseek(int fildes, off64_t offset, int whence)
    438438{
    439         futex_down(&vfs_phone_futex);
    440         async_serialize_start();
    441         vfs_connect();
     439        int vfs_phone = vfs_exchange_begin();
    442440       
    443441        sysarg_t newoff_lo;
     
    447445            &newoff_lo, &newoff_hi);
    448446       
    449         async_serialize_end();
    450         futex_up(&vfs_phone_futex);
     447        vfs_exchange_end(vfs_phone);
    451448       
    452449        if (rc != EOK)
     
    460457        sysarg_t rc;
    461458       
    462         futex_down(&vfs_phone_futex);
    463         async_serialize_start();
    464         vfs_connect();
     459        int vfs_phone = vfs_exchange_begin();
    465460       
    466461        rc = async_req_3_0(vfs_phone, VFS_IN_TRUNCATE, fildes,
    467462            LOWER32(length), UPPER32(length));
    468         async_serialize_end();
    469         futex_up(&vfs_phone_futex);
     463        vfs_exchange_end(vfs_phone);
    470464       
    471465        return (int) rc;
     
    477471        aid_t req;
    478472
    479         futex_down(&vfs_phone_futex);
    480         async_serialize_start();
    481         vfs_connect();
     473        int vfs_phone = vfs_exchange_begin();
    482474       
    483475        req = async_send_1(vfs_phone, VFS_IN_FSTAT, fildes, NULL);
    484476        rc = async_data_read_start(vfs_phone, (void *) stat, sizeof(struct stat));
    485477        if (rc != EOK) {
     478                vfs_exchange_end(vfs_phone);
     479
    486480                sysarg_t rc_orig;
    487                
    488                 async_wait_for(req, &rc_orig);
    489                 async_serialize_end();
    490                 futex_up(&vfs_phone_futex);
     481                async_wait_for(req, &rc_orig);
     482
    491483                if (rc_orig == EOK)
    492484                        return (ssize_t) rc;
     
    494486                        return (ssize_t) rc_orig;
    495487        }
    496         async_wait_for(req, &rc);
    497         async_serialize_end();
    498         futex_up(&vfs_phone_futex);
     488        vfs_exchange_end(vfs_phone);
     489        async_wait_for(req, &rc);
    499490
    500491        return rc;
     
    512503                return ENOMEM;
    513504       
    514         futex_down(&vfs_phone_futex);
    515         async_serialize_start();
    516         vfs_connect();
     505        int vfs_phone = vfs_exchange_begin();
    517506       
    518507        req = async_send_0(vfs_phone, VFS_IN_STAT, NULL);
    519508        rc = async_data_write_start(vfs_phone, pa, pa_size);
    520509        if (rc != EOK) {
    521                 async_wait_for(req, &rc_orig);
    522                 async_serialize_end();
    523                 futex_up(&vfs_phone_futex);
     510                vfs_exchange_end(vfs_phone);
    524511                free(pa);
     512                async_wait_for(req, &rc_orig);
    525513                if (rc_orig == EOK)
    526514                        return (int) rc;
     
    530518        rc = async_data_read_start(vfs_phone, stat, sizeof(struct stat));
    531519        if (rc != EOK) {
    532                 async_wait_for(req, &rc_orig);
    533                 async_serialize_end();
    534                 futex_up(&vfs_phone_futex);
     520                vfs_exchange_end(vfs_phone);
    535521                free(pa);
    536                 if (rc_orig == EOK)
    537                         return (int) rc;
    538                 else
    539                         return (int) rc_orig;
    540         }
    541         async_wait_for(req, &rc);
    542         async_serialize_end();
    543         futex_up(&vfs_phone_futex);
     522                async_wait_for(req, &rc_orig);
     523                if (rc_orig == EOK)
     524                        return (int) rc;
     525                else
     526                        return (int) rc_orig;
     527        }
     528        vfs_exchange_end(vfs_phone);
    544529        free(pa);
     530        async_wait_for(req, &rc);
    545531        return rc;
    546532}
     
    601587                return ENOMEM;
    602588       
    603         futex_down(&vfs_phone_futex);
    604         async_serialize_start();
    605         vfs_connect();
     589        int vfs_phone = vfs_exchange_begin();
    606590       
    607591        req = async_send_1(vfs_phone, VFS_IN_MKDIR, mode, NULL);
    608592        rc = async_data_write_start(vfs_phone, pa, pa_size);
    609593        if (rc != EOK) {
     594                vfs_exchange_end(vfs_phone);
     595                free(pa);
     596
    610597                sysarg_t rc_orig;
    611        
    612                 async_wait_for(req, &rc_orig);
    613                 async_serialize_end();
    614                 futex_up(&vfs_phone_futex);
    615                 free(pa);
    616                 if (rc_orig == EOK)
    617                         return (int) rc;
    618                 else
    619                         return (int) rc_orig;
    620         }
    621         async_wait_for(req, &rc);
    622         async_serialize_end();
    623         futex_up(&vfs_phone_futex);
     598                async_wait_for(req, &rc_orig);
     599
     600                if (rc_orig == EOK)
     601                        return (int) rc;
     602                else
     603                        return (int) rc_orig;
     604        }
     605        vfs_exchange_end(vfs_phone);
    624606        free(pa);
     607        async_wait_for(req, &rc);
    625608        return rc;
    626609}
     
    636619                return ENOMEM;
    637620
    638         futex_down(&vfs_phone_futex);
    639         async_serialize_start();
    640         vfs_connect();
     621        int vfs_phone = vfs_exchange_begin();
    641622       
    642623        req = async_send_0(vfs_phone, VFS_IN_UNLINK, NULL);
    643624        rc = async_data_write_start(vfs_phone, pa, pa_size);
    644625        if (rc != EOK) {
     626                vfs_exchange_end(vfs_phone);
     627                free(pa);
     628
    645629                sysarg_t rc_orig;
    646 
    647                 async_wait_for(req, &rc_orig);
    648                 async_serialize_end();
    649                 futex_up(&vfs_phone_futex);
    650                 free(pa);
    651                 if (rc_orig == EOK)
    652                         return (int) rc;
    653                 else
    654                         return (int) rc_orig;
    655         }
    656         async_wait_for(req, &rc);
    657         async_serialize_end();
    658         futex_up(&vfs_phone_futex);
     630                async_wait_for(req, &rc_orig);
     631
     632                if (rc_orig == EOK)
     633                        return (int) rc;
     634                else
     635                        return (int) rc_orig;
     636        }
     637        vfs_exchange_end(vfs_phone);
    659638        free(pa);
     639        async_wait_for(req, &rc);
    660640        return rc;
    661641}
     
    689669        }
    690670
    691         futex_down(&vfs_phone_futex);
    692         async_serialize_start();
    693         vfs_connect();
     671        int vfs_phone = vfs_exchange_begin();
    694672       
    695673        req = async_send_0(vfs_phone, VFS_IN_RENAME, NULL);
    696674        rc = async_data_write_start(vfs_phone, olda, olda_size);
    697675        if (rc != EOK) {
    698                 async_wait_for(req, &rc_orig);
    699                 async_serialize_end();
    700                 futex_up(&vfs_phone_futex);
     676                vfs_exchange_end(vfs_phone);
    701677                free(olda);
    702678                free(newa);
     679                async_wait_for(req, &rc_orig);
    703680                if (rc_orig == EOK)
    704681                        return (int) rc;
     
    708685        rc = async_data_write_start(vfs_phone, newa, newa_size);
    709686        if (rc != EOK) {
    710                 async_wait_for(req, &rc_orig);
    711                 async_serialize_end();
    712                 futex_up(&vfs_phone_futex);
     687                vfs_exchange_end(vfs_phone);
    713688                free(olda);
    714689                free(newa);
    715                 if (rc_orig == EOK)
    716                         return (int) rc;
    717                 else
    718                         return (int) rc_orig;
    719         }
    720         async_wait_for(req, &rc);
    721         async_serialize_end();
    722         futex_up(&vfs_phone_futex);
     690                async_wait_for(req, &rc_orig);
     691                if (rc_orig == EOK)
     692                        return (int) rc;
     693                else
     694                        return (int) rc_orig;
     695        }
     696        vfs_exchange_end(vfs_phone);
    723697        free(olda);
    724698        free(newa);
     699        async_wait_for(req, &rc);
    725700        return rc;
    726701}
     
    740715        }
    741716       
    742         futex_down(&cwd_futex);
     717        fibril_mutex_lock(&cwd_mutex);
    743718       
    744719        if (cwd_fd >= 0)
     
    753728        cwd_size = abs_size;
    754729       
    755         futex_up(&cwd_futex);
     730        fibril_mutex_unlock(&cwd_mutex);
    756731        return EOK;
    757732}
     
    762737                return NULL;
    763738       
    764         futex_down(&cwd_futex);
     739        fibril_mutex_lock(&cwd_mutex);
    765740       
    766741        if ((cwd_size == 0) || (size < cwd_size + 1)) {
    767                 futex_up(&cwd_futex);
     742                fibril_mutex_unlock(&cwd_mutex);
    768743                return NULL;
    769744        }
    770745       
    771746        str_cpy(buf, size, cwd_path);
    772         futex_up(&cwd_futex);
     747        fibril_mutex_unlock(&cwd_mutex);
    773748       
    774749        return buf;
     
    806781int dup2(int oldfd, int newfd)
    807782{
    808         futex_down(&vfs_phone_futex);
    809         async_serialize_start();
    810         vfs_connect();
     783        int vfs_phone = vfs_exchange_begin();
    811784       
    812785        sysarg_t ret;
    813786        sysarg_t rc = async_req_2_1(vfs_phone, VFS_IN_DUP, oldfd, newfd, &ret);
    814787       
    815         async_serialize_end();
    816         futex_up(&vfs_phone_futex);
     788        vfs_exchange_end(vfs_phone);
    817789       
    818790        if (rc == EOK)
Note: See TracChangeset for help on using the changeset viewer.