Changeset 12573db in mainline for uspace/lib/c/generic


Ignore:
Timestamp:
2011-01-31T20:32:33Z (14 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
37cf3792
Parents:
4fe94c66 (diff), 197ef43 (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:
5 added
22 edited
2 moved

Legend:

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

    r4fe94c66 r12573db  
    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 {
     
    153151        /** Link to the client tracking structure. */
    154152        client_t *client;
    155 
     153       
    156154        /** Messages that should be delivered to this fibril. */
    157155        link_t msg_queue;
     
    170168
    171169/** Identifier of the incoming connection handled by the current fibril. */
    172 fibril_local connection_t *FIBRIL_connection;
     170static fibril_local connection_t *FIBRIL_connection;
    173171
    174172static void *default_client_data_constructor(void)
     
    199197{
    200198        assert(FIBRIL_connection);
    201 
    202199        return FIBRIL_connection->client->data;
    203200}
    204201
    205 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call);
    206 static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call);
     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}
    207214
    208215/**
     
    210217 */
    211218static 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}
    212231
    213232/**
     
    221240static LIST_INITIALIZE(timeout_list);
    222241
    223 #define CLIENT_HASH_TABLE_BUCKETS       32
    224 #define CONN_HASH_TABLE_BUCKETS         32
    225 
    226 static hash_index_t client_hash(unsigned long *key)
     242#define CLIENT_HASH_TABLE_BUCKETS  32
     243#define CONN_HASH_TABLE_BUCKETS    32
     244
     245static hash_index_t client_hash(unsigned long key[])
    227246{
    228247        assert(key);
    229         return (((*key) >> 4) % CLIENT_HASH_TABLE_BUCKETS);
     248        return (((key[0]) >> 4) % CLIENT_HASH_TABLE_BUCKETS);
    230249}
    231250
    232251static int client_compare(unsigned long key[], hash_count_t keys, link_t *item)
    233252{
    234         client_t *cl = hash_table_get_instance(item, client_t, link);
    235         return (key[0] == cl->in_task_hash);
     253        client_t *client = hash_table_get_instance(item, client_t, link);
     254        return (key[0] == client->in_task_hash);
    236255}
    237256
     
    254273 *
    255274 */
    256 static hash_index_t conn_hash(unsigned long *key)
     275static hash_index_t conn_hash(unsigned long key[])
    257276{
    258277        assert(key);
    259         return (((*key) >> 4) % CONN_HASH_TABLE_BUCKETS);
     278        return (((key[0]) >> 4) % CONN_HASH_TABLE_BUCKETS);
    260279}
    261280
     
    271290static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item)
    272291{
    273         connection_t *hs = hash_table_get_instance(item, connection_t, link);
    274         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);
    275294}
    276295
     
    287306        free(hash_table_get_instance(item, connection_t, link));
    288307}
    289 
    290308
    291309/** Operations for the connection hash table. */
     
    308326        link_t *tmp = timeout_list.next;
    309327        while (tmp != &timeout_list) {
    310                 awaiter_t *cur;
    311                
    312                 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               
    313331                if (tv_gteq(&cur->to_event.expires, &wd->to_event.expires))
    314332                        break;
     333               
    315334                tmp = tmp->next;
    316335        }
     
    329348 *
    330349 * @return False if the call doesn't match any connection.
    331  *         True if the call was passed to the respective connection fibril.
     350 * @return True if the call was passed to the respective connection fibril.
    332351 *
    333352 */
     
    466485                         * the first IPC_M_PHONE_HUNGUP call and continues to
    467486                         * call async_get_call_timeout(). Repeat
    468                          * IPC_M_PHONE_HUNGUP until the caller notices. 
     487                         * IPC_M_PHONE_HUNGUP until the caller notices.
    469488                         */
    470489                        memset(call, 0, sizeof(ipc_call_t));
     
    473492                        return conn->close_callid;
    474493                }
    475 
     494               
    476495                if (usecs)
    477496                        async_insert_timeout(&conn->wdata);
     
    511530}
    512531
    513 /** Default fibril function that gets called to handle new connection.
    514  *
    515  * This function is defined as a weak symbol - to be redefined in user code.
    516  *
    517  * @param callid Hash of the incoming call.
    518  * @param call   Data of the incoming call.
    519  *
    520  */
    521 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call)
    522 {
    523         ipc_answer_0(callid, ENOENT);
    524 }
    525 
    526 /** Default fibril function that gets called to handle interrupt notifications.
    527  *
    528  * This function is defined as a weak symbol - to be redefined in user code.
    529  *
    530  * @param callid Hash of the incoming call.
    531  * @param call   Data of the incoming call.
    532  *
    533  */
    534 static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call)
    535 {
    536 }
    537 
    538532/** Wrapper for client connection fibril.
    539533 *
     
    548542static int connection_fibril(void *arg)
    549543{
    550         unsigned long key;
    551         client_t *cl;
    552         link_t *lnk;
    553         bool destroy = false;
    554 
    555544        /*
    556545         * Setup fibril-local connection pointer.
    557546         */
    558547        FIBRIL_connection = (connection_t *) arg;
    559 
     548       
     549        futex_down(&async_futex);
     550       
    560551        /*
    561552         * Add our reference for the current connection in the client task
     
    563554         * hash in a new tracking structure.
    564555         */
    565         futex_down(&async_futex);
    566         key = FIBRIL_connection->in_task_hash;
    567         lnk = hash_table_find(&client_hash_table, &key);
     556       
     557        unsigned long key = FIBRIL_connection->in_task_hash;
     558        link_t *lnk = hash_table_find(&client_hash_table, &key);
     559       
     560        client_t *client;
     561       
    568562        if (lnk) {
    569                 cl = hash_table_get_instance(lnk, client_t, link);
    570                 cl->refcnt++;
     563                client = hash_table_get_instance(lnk, client_t, link);
     564                client->refcnt++;
    571565        } else {
    572                 cl = malloc(sizeof(client_t));
    573                 if (!cl) {
     566                client = malloc(sizeof(client_t));
     567                if (!client) {
    574568                        ipc_answer_0(FIBRIL_connection->callid, ENOMEM);
    575569                        futex_up(&async_futex);
    576570                        return 0;
    577571                }
    578                 cl->in_task_hash = FIBRIL_connection->in_task_hash;
     572               
     573                client->in_task_hash = FIBRIL_connection->in_task_hash;
     574               
    579575                async_serialize_start();
    580                 cl->data = async_client_data_create();
     576                client->data = async_client_data_create();
    581577                async_serialize_end();
    582                 cl->refcnt = 1;
    583                 hash_table_insert(&client_hash_table, &key, &cl->link);
    584         }
     578               
     579                client->refcnt = 1;
     580                hash_table_insert(&client_hash_table, &key, &client->link);
     581        }
     582       
    585583        futex_up(&async_futex);
    586 
    587         FIBRIL_connection->client = cl;
    588 
     584       
     585        FIBRIL_connection->client = client;
     586       
    589587        /*
    590588         * Call the connection handler function.
     
    596594         * Remove the reference for this client task connection.
    597595         */
     596        bool destroy;
     597       
    598598        futex_down(&async_futex);
    599         if (--cl->refcnt == 0) {
     599       
     600        if (--client->refcnt == 0) {
    600601                hash_table_remove(&client_hash_table, &key, 1);
    601602                destroy = true;
    602         }
     603        } else
     604                destroy = false;
     605       
    603606        futex_up(&async_futex);
    604 
     607       
    605608        if (destroy) {
    606                 if (cl->data)
    607                         async_client_data_destroy(cl->data);
    608                 free(cl);
    609         }
    610 
     609                if (client->data)
     610                        async_client_data_destroy(client->data);
     611               
     612                free(client);
     613        }
     614       
    611615        /*
    612616         * Remove myself from the connection hash table.
     
    621625         */
    622626        while (!list_empty(&FIBRIL_connection->msg_queue)) {
    623                 msg_t *msg;
    624                
    625                 msg = list_get_instance(FIBRIL_connection->msg_queue.next,
    626                     msg_t, link);
     627                msg_t *msg =
     628                    list_get_instance(FIBRIL_connection->msg_queue.next, msg_t,
     629                    link);
     630               
    627631                list_remove(&msg->link);
    628632                ipc_answer_0(msg->callid, EHANGUP);
     
    667671                if (callid)
    668672                        ipc_answer_0(callid, ENOMEM);
     673               
    669674                return (uintptr_t) NULL;
    670675        }
     
    714719static void handle_call(ipc_callid_t callid, ipc_call_t *call)
    715720{
    716         /* Unrouted call - do some default behaviour */
     721        /* Unrouted call - take some default action */
    717722        if ((callid & IPC_CALLID_NOTIFICATION)) {
    718723                process_notification(callid, call);
    719                 goto out;
     724                return;
    720725        }
    721726       
     
    723728        case IPC_M_CONNECT_ME:
    724729        case IPC_M_CONNECT_ME_TO:
    725                 /* Open new connection with fibril etc. */
     730                /* Open new connection with fibril, etc. */
    726731                async_new_connection(call->in_task_hash, IPC_GET_ARG5(*call),
    727732                    callid, call, client_connection);
    728                 goto out;
     733                return;
    729734        }
    730735       
    731736        /* Try to route the call through the connection hash table */
    732737        if (route_call(callid, call))
    733                 goto out;
     738                return;
    734739       
    735740        /* Unknown call from unknown phone - hang it up */
    736741        ipc_answer_0(callid, EHANGUP);
    737         return;
    738        
    739 out:
    740         ;
    741742}
    742743
     
    751752        link_t *cur = timeout_list.next;
    752753        while (cur != &timeout_list) {
    753                 awaiter_t *waiter;
    754                
    755                 waiter = list_get_instance(cur, awaiter_t, to_event.link);
     754                awaiter_t *waiter =
     755                    list_get_instance(cur, awaiter_t, to_event.link);
     756               
    756757                if (tv_gt(&waiter->to_event.expires, &tv))
    757758                        break;
    758 
     759               
    759760                cur = cur->next;
    760 
     761               
    761762                list_remove(&waiter->to_event.link);
    762763                waiter->to_event.inlist = false;
     
    785786        while (true) {
    786787                if (fibril_switch(FIBRIL_FROM_MANAGER)) {
    787                         futex_up(&async_futex); 
     788                        futex_up(&async_futex);
    788789                        /*
    789790                         * async_futex is always held when entering a manager
     
    808809                                continue;
    809810                        } else
    810                                 timeout = tv_sub(&waiter->to_event.expires,
    811                                     &tv);
     811                                timeout = tv_sub(&waiter->to_event.expires, &tv);
    812812                } else
    813813                        timeout = SYNCH_NO_TIMEOUT;
    814814               
    815815                futex_up(&async_futex);
    816 
     816               
    817817                atomic_inc(&threads_in_ipc_wait);
    818818               
     
    822822               
    823823                atomic_dec(&threads_in_ipc_wait);
    824 
     824               
    825825                if (!callid) {
    826826                        handle_expired_timeouts();
     
    872872/** Initialize the async framework.
    873873 *
    874  * @return Zero on success or an error code.
    875  */
    876 int __async_init(void)
     874 */
     875void __async_init(void)
    877876{
    878877        if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 1,
    879             &client_hash_table_ops) || !hash_table_create(&conn_hash_table,
    880             CONN_HASH_TABLE_BUCKETS, 1, &conn_hash_table_ops)) {
    881                 return ENOMEM;
    882         }
    883 
    884         _async_sess_init();
    885        
    886         return 0;
     878            &client_hash_table_ops))
     879                abort();
     880       
     881        if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS, 1,
     882            &conn_hash_table_ops))
     883                abort();
    887884}
    888885
     
    897894 * @param retval Value returned in the answer.
    898895 * @param data   Call data of the answer.
     896 *
    899897 */
    900898static void reply_received(void *arg, int retval, ipc_call_t *data)
     
    944942    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
    945943{
    946         amsg_t *msg = malloc(sizeof(*msg));
     944        amsg_t *msg = malloc(sizeof(amsg_t));
    947945       
    948946        if (!msg)
     
    953951       
    954952        msg->wdata.to_event.inlist = false;
    955         /* We may sleep in the next method, but it will use its own mechanism */
     953       
     954        /*
     955         * We may sleep in the next method,
     956         * but it will use its own means
     957         */
    956958        msg->wdata.active = true;
    957959       
     
    984986    ipc_call_t *dataptr)
    985987{
    986         amsg_t *msg = malloc(sizeof(*msg));
     988        amsg_t *msg = malloc(sizeof(amsg_t));
    987989       
    988990        if (!msg)
     
    993995       
    994996        msg->wdata.to_event.inlist = false;
    995         /* We may sleep in next method, but it will use its own mechanism */
     997       
     998        /*
     999         * We may sleep in the next method,
     1000         * but it will use its own means
     1001         */
    9961002        msg->wdata.active = true;
    9971003       
     
    10921098void async_usleep(suseconds_t timeout)
    10931099{
    1094         amsg_t *msg = malloc(sizeof(*msg));
     1100        amsg_t *msg = malloc(sizeof(amsg_t));
    10951101       
    10961102        if (!msg)
     
    12351241}
    12361242
     1243void async_msg_0(int phone, sysarg_t imethod)
     1244{
     1245        ipc_call_async_0(phone, imethod, NULL, NULL, true);
     1246}
     1247
     1248void async_msg_1(int phone, sysarg_t imethod, sysarg_t arg1)
     1249{
     1250        ipc_call_async_1(phone, imethod, arg1, NULL, NULL, true);
     1251}
     1252
     1253void async_msg_2(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2)
     1254{
     1255        ipc_call_async_2(phone, imethod, arg1, arg2, NULL, NULL, true);
     1256}
     1257
     1258void async_msg_3(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
     1259    sysarg_t arg3)
     1260{
     1261        ipc_call_async_3(phone, imethod, arg1, arg2, arg3, NULL, NULL, true);
     1262}
     1263
     1264void async_msg_4(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
     1265    sysarg_t arg3, sysarg_t arg4)
     1266{
     1267        ipc_call_async_4(phone, imethod, arg1, arg2, arg3, arg4, NULL, NULL,
     1268            true);
     1269}
     1270
     1271void async_msg_5(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
     1272    sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
     1273{
     1274        ipc_call_async_5(phone, imethod, arg1, arg2, arg3, arg4, arg5, NULL,
     1275            NULL, true);
     1276}
     1277
     1278sysarg_t async_answer_0(ipc_callid_t callid, sysarg_t retval)
     1279{
     1280        return ipc_answer_0(callid, retval);
     1281}
     1282
     1283sysarg_t async_answer_1(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1)
     1284{
     1285        return ipc_answer_1(callid, retval, arg1);
     1286}
     1287
     1288sysarg_t async_answer_2(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     1289    sysarg_t arg2)
     1290{
     1291        return ipc_answer_2(callid, retval, arg1, arg2);
     1292}
     1293
     1294sysarg_t async_answer_3(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     1295    sysarg_t arg2, sysarg_t arg3)
     1296{
     1297        return ipc_answer_3(callid, retval, arg1, arg2, arg3);
     1298}
     1299
     1300sysarg_t async_answer_4(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     1301    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
     1302{
     1303        return ipc_answer_4(callid, retval, arg1, arg2, arg3, arg4);
     1304}
     1305
     1306sysarg_t async_answer_5(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     1307    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
     1308{
     1309        return ipc_answer_5(callid, retval, arg1, arg2, arg3, arg4, arg5);
     1310}
     1311
     1312int async_forward_fast(ipc_callid_t callid, int phoneid, sysarg_t imethod,
     1313    sysarg_t arg1, sysarg_t arg2, unsigned int mode)
     1314{
     1315        return ipc_forward_fast(callid, phoneid, imethod, arg1, arg2, mode);
     1316}
     1317
     1318int async_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod,
     1319    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
     1320    unsigned int mode)
     1321{
     1322        return ipc_forward_slow(callid, phoneid, imethod, arg1, arg2, arg3, arg4,
     1323            arg5, mode);
     1324}
     1325
     1326/** Wrapper for making IPC_M_CONNECT_TO_ME calls using the async framework.
     1327 *
     1328 * Ask through phone for a new connection to some service.
     1329 *
     1330 * @param phone           Phone handle used for contacting the other side.
     1331 * @param arg1            User defined argument.
     1332 * @param arg2            User defined argument.
     1333 * @param arg3            User defined argument.
     1334 * @param client_receiver Connection handing routine.
     1335 *
     1336 * @return New phone handle on success or a negative error code.
     1337 *
     1338 */
     1339int async_connect_to_me(int phone, sysarg_t arg1, sysarg_t arg2,
     1340    sysarg_t arg3, async_client_conn_t client_receiver)
     1341{
     1342        sysarg_t task_hash;
     1343        sysarg_t phone_hash;
     1344        int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
     1345            NULL, NULL, NULL, &task_hash, &phone_hash);
     1346        if (rc != EOK)
     1347                return rc;
     1348       
     1349        if (client_receiver != NULL)
     1350                async_new_connection(task_hash, phone_hash, 0, NULL,
     1351                    client_receiver);
     1352       
     1353        return EOK;
     1354}
     1355
    12371356/** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
    1238  * 
     1357 *
    12391358 * Ask through phone for a new connection to some service.
    12401359 *
    1241  * @param phoneid       Phone handle used for contacting the other side.
    1242  * @param arg1          User defined argument.
    1243  * @param arg2          User defined argument.
    1244  * @param arg3          User defined argument.
    1245  *
    1246  * @return              New phone handle on success or a negative error code.
    1247  */
    1248 int
    1249 async_connect_me_to(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
    1250 {
    1251         int rc;
     1360 * @param phone Phone handle used for contacting the other side.
     1361 * @param arg1  User defined argument.
     1362 * @param arg2  User defined argument.
     1363 * @param arg3  User defined argument.
     1364 *
     1365 * @return New phone handle on success or a negative error code.
     1366 *
     1367 */
     1368int async_connect_me_to(int phone, sysarg_t arg1, sysarg_t arg2,
     1369    sysarg_t arg3)
     1370{
    12521371        sysarg_t newphid;
    1253 
    1254         rc = async_req_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, NULL,
    1255             NULL, NULL, NULL, &newphid);
    1256        
    1257         if (rc != EOK) 
     1372        int rc = async_req_3_5(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     1373            NULL, NULL, NULL, NULL, &newphid);
     1374       
     1375        if (rc != EOK)
    12581376                return rc;
    1259 
     1377       
    12601378        return newphid;
    12611379}
    12621380
    12631381/** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
    1264  * 
     1382 *
    12651383 * Ask through phone for a new connection to some service and block until
    12661384 * success.
    12671385 *
    1268  * @param phoneid       Phone handle used for contacting the other side.
    1269  * @param arg1          User defined argument.
    1270  * @param arg2          User defined argument.
    1271  * @param arg3          User defined argument.
    1272  *
    1273  * @return              New phone handle on success or a negative error code.
    1274  */
    1275 int
    1276 async_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,
     1386 * @param phoneid Phone handle used for contacting the other side.
     1387 * @param arg1    User defined argument.
     1388 * @param arg2    User defined argument.
     1389 * @param arg3    User defined argument.
     1390 *
     1391 * @return New phone handle on success or a negative error code.
     1392 *
     1393 */
     1394int async_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,
    12771395    sysarg_t arg3)
    12781396{
    1279         int rc;
    12801397        sysarg_t newphid;
    1281 
    1282         rc = async_req_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     1398        int rc = async_req_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
    12831399            IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
    12841400       
    1285         if (rc != EOK) 
     1401        if (rc != EOK)
    12861402                return rc;
    1287 
     1403       
    12881404        return newphid;
    12891405}
    12901406
    1291 /** Wrapper for making IPC_M_SHARE_IN calls using the async framework.
    1292  *
    1293  * @param phoneid       Phone that will be used to contact the receiving side.
    1294  * @param dst           Destination address space area base.
    1295  * @param size          Size of the destination address space area.
    1296  * @param arg           User defined argument.
    1297  * @param flags         Storage where the received flags will be stored. Can be
    1298  *                      NULL.
    1299  *
    1300  * @return              Zero on success or a negative error code from errno.h.
     1407/** Connect to a task specified by id.
     1408 *
     1409 */
     1410int async_connect_kbox(task_id_t id)
     1411{
     1412        return ipc_connect_kbox(id);
     1413}
     1414
     1415/** Wrapper for ipc_hangup.
     1416 *
     1417 * @param phone Phone handle to hung up.
     1418 *
     1419 * @return Zero on success or a negative error code.
     1420 *
     1421 */
     1422int async_hangup(int phone)
     1423{
     1424        return ipc_hangup(phone);
     1425}
     1426
     1427/** Interrupt one thread of this task from waiting for IPC. */
     1428void async_poke(void)
     1429{
     1430        ipc_poke();
     1431}
     1432
     1433/** Wrapper for IPC_M_SHARE_IN calls using the async framework.
     1434 *
     1435 * @param phoneid Phone that will be used to contact the receiving side.
     1436 * @param dst     Destination address space area base.
     1437 * @param size    Size of the destination address space area.
     1438 * @param arg     User defined argument.
     1439 * @param flags   Storage for the received flags. Can be NULL.
     1440 *
     1441 * @return Zero on success or a negative error code from errno.h.
     1442 *
    13011443 */
    13021444int async_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg,
    1303     int *flags)
    1304 {
    1305         int res;
     1445    unsigned int *flags)
     1446{
    13061447        sysarg_t tmp_flags;
    1307         res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,
     1448        int res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,
    13081449            (sysarg_t) size, arg, NULL, &tmp_flags);
     1450       
    13091451        if (flags)
    1310                 *flags = tmp_flags;
     1452                *flags = (unsigned int) tmp_flags;
     1453       
    13111454        return res;
    13121455}
     
    13141457/** Wrapper for receiving the IPC_M_SHARE_IN calls using the async framework.
    13151458 *
    1316  * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN calls
    1317  * so that the user doesn't have to remember the meaning of each IPC argument.
     1459 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN
     1460 * calls so that the user doesn't have to remember the meaning of each IPC
     1461 * argument.
    13181462 *
    13191463 * So far, this wrapper is to be used from within a connection fibril.
    13201464 *
    1321  * @param callid        Storage where the hash of the IPC_M_SHARE_IN call will
    1322  *                      be stored.
    1323  * @param size          Destination address space area size.   
    1324  *
    1325  * @return              Non-zero on success, zero on failure.
    1326  */
    1327 int async_share_in_receive(ipc_callid_t *callid, size_t *size)
    1328 {
    1329         ipc_call_t data;
    1330        
     1465 * @param callid Storage for the hash of the IPC_M_SHARE_IN call.
     1466 * @param size   Destination address space area size.
     1467 *
     1468 * @return True on success, false on failure.
     1469 *
     1470 */
     1471bool async_share_in_receive(ipc_callid_t *callid, size_t *size)
     1472{
    13311473        assert(callid);
    13321474        assert(size);
    1333 
     1475       
     1476        ipc_call_t data;
    13341477        *callid = async_get_call(&data);
     1478       
    13351479        if (IPC_GET_IMETHOD(data) != IPC_M_SHARE_IN)
    1336                 return 0;
     1480                return false;
     1481       
    13371482        *size = (size_t) IPC_GET_ARG2(data);
    1338         return 1;
     1483        return true;
    13391484}
    13401485
    13411486/** Wrapper for answering the IPC_M_SHARE_IN calls using the async framework.
    13421487 *
    1343  * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
    1344  * so that the user doesn't have to remember the meaning of each IPC argument.
    1345  *
    1346  * @param callid        Hash of the IPC_M_DATA_READ call to answer.
    1347  * @param src           Source address space base.
    1348  * @param flags         Flags to be used for sharing. Bits can be only cleared.
    1349  *
    1350  * @return              Zero on success or a value from @ref errno.h on failure.
    1351  */
    1352 int async_share_in_finalize(ipc_callid_t callid, void *src, int flags)
     1488 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ
     1489 * calls so that the user doesn't have to remember the meaning of each IPC
     1490 * argument.
     1491 *
     1492 * @param callid Hash of the IPC_M_DATA_READ call to answer.
     1493 * @param src    Source address space base.
     1494 * @param flags  Flags to be used for sharing. Bits can be only cleared.
     1495 *
     1496 * @return Zero on success or a value from @ref errno.h on failure.
     1497 *
     1498 */
     1499int async_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags)
    13531500{
    13541501        return ipc_share_in_finalize(callid, src, flags);
    13551502}
    13561503
    1357 /** Wrapper for making IPC_M_SHARE_OUT calls using the async framework.
    1358  *
    1359  * @param phoneid       Phone that will be used to contact the receiving side.
    1360  * @param src           Source address space area base address.
    1361  * @param flags         Flags to be used for sharing. Bits can be only cleared.
    1362  *
    1363  * @return              Zero on success or a negative error code from errno.h.
    1364  */
    1365 int async_share_out_start(int phoneid, void *src, int flags)
     1504/** Wrapper for IPC_M_SHARE_OUT calls using the async framework.
     1505 *
     1506 * @param phoneid Phone that will be used to contact the receiving side.
     1507 * @param src     Source address space area base address.
     1508 * @param flags   Flags to be used for sharing. Bits can be only cleared.
     1509 *
     1510 * @return Zero on success or a negative error code from errno.h.
     1511 *
     1512 */
     1513int async_share_out_start(int phoneid, void *src, unsigned int flags)
    13661514{
    13671515        return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
     
    13711519/** Wrapper for receiving the IPC_M_SHARE_OUT calls using the async framework.
    13721520 *
    1373  * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT calls
    1374  * so that the user doesn't have to remember the meaning of each IPC argument.
     1521 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT
     1522 * calls so that the user doesn't have to remember the meaning of each IPC
     1523 * argument.
    13751524 *
    13761525 * So far, this wrapper is to be used from within a connection fibril.
    13771526 *
    1378  * @param callid        Storage where the hash of the IPC_M_SHARE_OUT call will
    1379  *                      be stored.
    1380  * @param size          Storage where the source address space area size will be
    1381  *                      stored.
    1382  * @param flags         Storage where the sharing flags will be stored.
    1383  *
    1384  * @return              Non-zero on success, zero on failure.
    1385  */
    1386 int async_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags)
    1387 {
    1388         ipc_call_t data;
    1389        
     1527 * @param callid Storage for the hash of the IPC_M_SHARE_OUT call.
     1528 * @param size   Storage for the source address space area size.
     1529 * @param flags  Storage for the sharing flags.
     1530 *
     1531 * @return True on success, false on failure.
     1532 *
     1533 */
     1534bool async_share_out_receive(ipc_callid_t *callid, size_t *size, unsigned int *flags)
     1535{
    13901536        assert(callid);
    13911537        assert(size);
    13921538        assert(flags);
    1393 
     1539       
     1540        ipc_call_t data;
    13941541        *callid = async_get_call(&data);
     1542       
    13951543        if (IPC_GET_IMETHOD(data) != IPC_M_SHARE_OUT)
    1396                 return 0;
     1544                return false;
     1545       
    13971546        *size = (size_t) IPC_GET_ARG2(data);
    1398         *flags = (int) IPC_GET_ARG3(data);
    1399         return 1;
     1547        *flags = (unsigned int) IPC_GET_ARG3(data);
     1548        return true;
    14001549}
    14011550
    14021551/** Wrapper for answering the IPC_M_SHARE_OUT calls using the async framework.
    14031552 *
    1404  * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT calls
    1405  * so that the user doesn't have to remember the meaning of each IPC argument.
    1406  *
    1407  * @param callid        Hash of the IPC_M_DATA_WRITE call to answer.
    1408  * @param dst           Destination address space area base address.   
    1409  *
    1410  * @return              Zero on success or a value from @ref errno.h on failure.
     1553 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT
     1554 * calls so that the user doesn't have to remember the meaning of each IPC
     1555 * argument.
     1556 *
     1557 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.
     1558 * @param dst    Destination address space area base address.
     1559 *
     1560 * @return Zero on success or a value from @ref errno.h on failure.
     1561 *
    14111562 */
    14121563int async_share_out_finalize(ipc_callid_t callid, void *dst)
     
    14151566}
    14161567
    1417 
    1418 /** Wrapper for making IPC_M_DATA_READ calls using the async framework.
    1419  *
    1420  * @param phoneid       Phone that will be used to contact the receiving side.
    1421  * @param dst           Address of the beginning of the destination buffer.
    1422  * @param size          Size of the destination buffer.
    1423  *
    1424  * @return              Zero on success or a negative error code from errno.h.
     1568/** Wrapper for IPC_M_DATA_READ calls using the async framework.
     1569 *
     1570 * @param phoneid Phone that will be used to contact the receiving side.
     1571 * @param dst     Address of the beginning of the destination buffer.
     1572 * @param size    Size of the destination buffer.
     1573 *
     1574 * @return Zero on success or a negative error code from errno.h.
     1575 *
    14251576 */
    14261577int async_data_read_start(int phoneid, void *dst, size_t size)
     
    14321583/** Wrapper for receiving the IPC_M_DATA_READ calls using the async framework.
    14331584 *
    1434  * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ calls
    1435  * so that the user doesn't have to remember the meaning of each IPC argument.
     1585 * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ
     1586 * calls so that the user doesn't have to remember the meaning of each IPC
     1587 * argument.
    14361588 *
    14371589 * So far, this wrapper is to be used from within a connection fibril.
    14381590 *
    1439  * @param callid        Storage where the hash of the IPC_M_DATA_READ call will
    1440  *                      be stored.
    1441  * @param size          Storage where the maximum size will be stored. Can be
    1442  *                      NULL.
    1443  *
    1444  * @return              Non-zero on success, zero on failure.
    1445  */
    1446 int async_data_read_receive(ipc_callid_t *callid, size_t *size)
    1447 {
     1591 * @param callid Storage for the hash of the IPC_M_DATA_READ.
     1592 * @param size   Storage for the maximum size. Can be NULL.
     1593 *
     1594 * @return True on success, false on failure.
     1595 *
     1596 */
     1597bool async_data_read_receive(ipc_callid_t *callid, size_t *size)
     1598{
     1599        assert(callid);
     1600       
    14481601        ipc_call_t data;
    1449        
    1450         assert(callid);
    1451 
    14521602        *callid = async_get_call(&data);
     1603       
    14531604        if (IPC_GET_IMETHOD(data) != IPC_M_DATA_READ)
    1454                 return 0;
     1605                return false;
     1606       
    14551607        if (size)
    14561608                *size = (size_t) IPC_GET_ARG2(data);
    1457         return 1;
     1609       
     1610        return true;
    14581611}
    14591612
    14601613/** Wrapper for answering the IPC_M_DATA_READ calls using the async framework.
    14611614 *
    1462  * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
    1463  * so that the user doesn't have to remember the meaning of each IPC argument.
    1464  *
    1465  * @param callid        Hash of the IPC_M_DATA_READ call to answer.
    1466  * @param src           Source address for the IPC_M_DATA_READ call.
    1467  * @param size          Size for the IPC_M_DATA_READ call. Can be smaller than
    1468  *                      the maximum size announced by the sender.
    1469  *
    1470  * @return              Zero on success or a value from @ref errno.h on failure.
     1615 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ
     1616 * calls so that the user doesn't have to remember the meaning of each IPC
     1617 * argument.
     1618 *
     1619 * @param callid Hash of the IPC_M_DATA_READ call to answer.
     1620 * @param src    Source address for the IPC_M_DATA_READ call.
     1621 * @param size   Size for the IPC_M_DATA_READ call. Can be smaller than
     1622 *               the maximum size announced by the sender.
     1623 *
     1624 * @return Zero on success or a value from @ref errno.h on failure.
     1625 *
    14711626 */
    14721627int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
     
    14761631
    14771632/** Wrapper for forwarding any read request
    1478  *
    14791633 *
    14801634 */
     
    15091663}
    15101664
    1511 /** Wrapper for making IPC_M_DATA_WRITE calls using the async framework.
     1665/** Wrapper for IPC_M_DATA_WRITE calls using the async framework.
    15121666 *
    15131667 * @param phoneid Phone that will be used to contact the receiving side.
     
    15261680/** Wrapper for receiving the IPC_M_DATA_WRITE calls using the async framework.
    15271681 *
    1528  * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE calls
    1529  * so that the user doesn't have to remember the meaning of each IPC argument.
     1682 * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE
     1683 * calls so that the user doesn't have to remember the meaning of each IPC
     1684 * argument.
    15301685 *
    15311686 * So far, this wrapper is to be used from within a connection fibril.
    15321687 *
    1533  * @param callid Storage where the hash of the IPC_M_DATA_WRITE call will
    1534  *               be stored.
    1535  * @param size   Storage where the suggested size will be stored. May be
    1536  *               NULL
    1537  *
    1538  * @return Non-zero on success, zero on failure.
    1539  *
    1540  */
    1541 int async_data_write_receive(ipc_callid_t *callid, size_t *size)
    1542 {
     1688 * @param callid Storage for the hash of the IPC_M_DATA_WRITE.
     1689 * @param size   Storage for the suggested size. May be NULL.
     1690 *
     1691 * @return True on success, false on failure.
     1692 *
     1693 */
     1694bool async_data_write_receive(ipc_callid_t *callid, size_t *size)
     1695{
     1696        assert(callid);
     1697       
    15431698        ipc_call_t data;
    1544        
    1545         assert(callid);
    1546        
    15471699        *callid = async_get_call(&data);
     1700       
    15481701        if (IPC_GET_IMETHOD(data) != IPC_M_DATA_WRITE)
    1549                 return 0;
     1702                return false;
    15501703       
    15511704        if (size)
    15521705                *size = (size_t) IPC_GET_ARG2(data);
    15531706       
    1554         return 1;
     1707        return true;
    15551708}
    15561709
    15571710/** Wrapper for answering the IPC_M_DATA_WRITE calls using the async framework.
    15581711 *
    1559  * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE calls
    1560  * so that the user doesn't have to remember the meaning of each IPC argument.
     1712 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE
     1713 * calls so that the user doesn't have to remember the meaning of each IPC
     1714 * argument.
    15611715 *
    15621716 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.
     
    16541808 *
    16551809 */
    1656 void async_data_write_void(const int retval)
     1810void async_data_write_void(sysarg_t retval)
    16571811{
    16581812        ipc_callid_t callid;
     
    16621816
    16631817/** Wrapper for forwarding any data that is about to be received
    1664  *
    16651818 *
    16661819 */
  • uspace/lib/c/generic/async_sess.c

    r4fe94c66 r12573db  
    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. */
     
    138138 *
    139139 * Needs to be called prior to any other interface in this file.
    140  */
    141 void _async_sess_init(void)
     140 *
     141 */
     142void __async_sess_init(void)
    142143{
    143144        fibril_mutex_initialize(&async_sess_mutex);
     
    200201                list_remove(&conn->global_link);
    201202               
    202                 ipc_hangup(conn->data_phone);
     203                async_hangup(conn->data_phone);
    203204                free(conn);
    204205        }
     
    260261                        data_phone = conn->data_phone;
    261262                        free(conn);
    262                         ipc_hangup(data_phone);
     263                        async_hangup(data_phone);
    263264                        goto retry;
    264265                } else {
     
    292293                 * means that we simply hang up.
    293294                 */
    294                 ipc_hangup(data_phone);
     295                async_hangup(data_phone);
    295296                fibril_mutex_unlock(&async_sess_mutex);
    296297                return;
  • uspace/lib/c/generic/clipboard.c

    r4fe94c66 r12573db  
    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

    r4fe94c66 r12573db  
    127127}
    128128
     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
    129158/** @}
    130159 */
  • uspace/lib/c/generic/devman.c

    r4fe94c66 r12573db  
    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>
     
    116115        async_set_client_connection(conn);
    117116       
    118         ipc_connect_to_me(phone, 0, 0, 0, NULL, NULL);
     117        async_connect_to_me(phone, 0, 0, 0, NULL);
    119118        async_wait_for(req, &retval);
    120119       
     
    221220        case DEVMAN_DRIVER:
    222221                if (devman_phone_driver >= 0) {
    223                         ipc_hangup(devman_phone_driver);
     222                        async_hangup(devman_phone_driver);
    224223                        devman_phone_driver = -1;
    225224                }
     
    227226        case DEVMAN_CLIENT:
    228227                if (devman_phone_client >= 0) {
    229                         ipc_hangup(devman_phone_client);
     228                        async_hangup(devman_phone_client);
    230229                        devman_phone_client = -1;
    231230                }
  • uspace/lib/c/generic/devmap.c

    r4fe94c66 r12573db  
    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         ipc_connect_to_me(phone, 0, 0, 0, NULL, NULL);
     118        async_connect_to_me(phone, 0, 0, 0, NULL);
    119119        async_wait_for(req, &retval);
    120120       
  • uspace/lib/c/generic/event.c

    r4fe94c66 r12573db  
    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

    r4fe94c66 r12573db  
    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
     
    105105
    106106        if (fibril_get_sercount() != 0)
    107                 core();
     107                abort();
    108108
    109109        futex_down(&async_futex);
     
    198198       
    199199        if (fibril_get_sercount() != 0)
    200                 core();
     200                abort();
    201201
    202202        futex_down(&async_futex);
     
    226226       
    227227        if (fibril_get_sercount() != 0)
    228                 core();
     228                abort();
    229229
    230230        futex_down(&async_futex);
  • uspace/lib/c/generic/io/io.c

    r4fe94c66 r12573db  
    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

    r4fe94c66 r12573db  
    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 taskhash      Storage where the kernel will store an opaque
    581  *                      identifier of the client task.
    582  * @param phonehash     Storage where the kernel will store an opaque
    583  *                      identifier of the phone that will be used for incoming
    584  *                      calls. This identifier can be used for connection
    585  *                      tracking.
    586  *
    587  * @return              Zero on success or a negative error code.
    588  */
    589 int ipc_connect_to_me(int phoneid, int arg1, int arg2, int arg3,
     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,
    590628    sysarg_t *taskhash, sysarg_t *phonehash)
    591629{
     
    594632}
    595633
    596 /** Ask through phone for a new connection to some service.
    597  *
    598  * @param phoneid       Phone handle used for contacting the other side.
    599  * @param arg1          User defined argument.
    600  * @param arg2          User defined argument.
    601  * @param arg3          User defined argument.
    602  *
    603  * @return              New phone handle on success or a negative error code.
    604  */
    605 int ipc_connect_me_to(int phoneid, int arg1, int arg2, int arg3)
     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)
    606645{
    607646        sysarg_t newphid;
    608         int res;
    609 
    610         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,
    611648            NULL, NULL, NULL, NULL, &newphid);
    612649        if (res)
    613650                return res;
     651       
    614652        return newphid;
    615653}
    616654
    617 /** Ask through phone for a new connection to some service.
     655/** Request new connection (blocking)
    618656 *
    619657 * If the connection is not available at the moment, the
    620  * call will block.
    621  *
    622  * @param phoneid       Phone handle used for contacting the other side.
    623  * @param arg1          User defined argument.
    624  * @param arg2          User defined argument.
    625  * @param arg3          User defined argument.
    626  *
    627  * @return              New phone handle on success or a negative error code.
    628  */
    629 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)
    630671{
    631672        sysarg_t newphid;
    632         int res;
    633 
    634         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,
    635674            IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
    636675        if (res)
    637676                return res;
     677       
    638678        return newphid;
    639679}
     
    641681/** Hang up a phone.
    642682 *
    643  * @param phoneid       Handle of the phone to be hung up.
    644  *
    645  * @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 *
    646687 */
    647688int ipc_hangup(int phoneid)
     
    650691}
    651692
    652 /** Register IRQ notification.
    653  *
    654  * @param inr           IRQ number.
    655  * @param devno         Device number of the device generating inr.
    656  * @param method        Use this method for notifying me.
    657  * @param ucode         Top-half pseudocode handler.
    658  *
    659  * @return              Value returned by the kernel.
    660  */
    661 int ipc_register_irq(int inr, int devno, int method, irq_code_t *ucode)
    662 {
    663         return __SYSCALL4(SYS_IPC_REGISTER_IRQ, inr, devno, method,
    664             (sysarg_t) ucode);
    665 }
    666 
    667 /** Unregister IRQ notification.
    668  *
    669  * @param inr           IRQ number.
    670  * @param devno         Device number of the device generating inr.
    671  *
    672  * @return              Value returned by the kernel.
    673  */
    674 int ipc_unregister_irq(int inr, int devno)
    675 {
    676         return __SYSCALL2(SYS_IPC_UNREGISTER_IRQ, inr, devno);
    677 }
    678 
    679693/** 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.
    680699 *
    681700 * @param callid  Hash of the call to forward.
     
    688707 * @return Zero on success or an error code.
    689708 *
    690  * For non-system methods, the old method, arg1 and arg2 are rewritten by the
    691  * new values. For system methods, the new method, arg1 and arg2 are written
    692  * to the old arg1, arg2 and arg3, respectivelly. Calls with immutable
    693  * methods are forwarded verbatim.
    694  */
    695 int ipc_forward_fast(ipc_callid_t callid, int phoneid, int imethod,
    696     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)
    697712{
    698713        return __SYSCALL6(SYS_IPC_FORWARD_FAST, callid, phoneid, imethod, arg1,
     
    700715}
    701716
    702 
    703 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,
    704718    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
    705     int mode)
     719    unsigned int mode)
    706720{
    707721        ipc_call_t data;
     
    714728        IPC_SET_ARG5(data, arg5);
    715729       
    716         return __SYSCALL4(SYS_IPC_FORWARD_SLOW, callid, phoneid, (sysarg_t) &data, mode);
    717 }
    718 
    719 /** Wrapper for making IPC_M_SHARE_IN calls.
    720  *
    721  * @param phoneid       Phone that will be used to contact the receiving side.
    722  * @param dst           Destination address space area base.
    723  * @param size          Size of the destination address space area.
    724  * @param arg           User defined argument.
    725  * @param flags         Storage where the received flags will be stored. Can be
    726  *                      NULL.
    727  *
    728  * @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 *
    729744 */
    730745int ipc_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg,
    731     int *flags)
     746    unsigned int *flags)
    732747{
    733748        sysarg_t tmp_flags = 0;
     
    736751       
    737752        if (flags)
    738                 *flags = tmp_flags;
     753                *flags = (unsigned int) tmp_flags;
    739754       
    740755        return res;
     
    743758/** Wrapper for answering the IPC_M_SHARE_IN calls.
    744759 *
    745  * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
    746  * so that the user doesn't have to remember the meaning of each IPC argument.
    747  *
    748  * @param callid        Hash of the IPC_M_DATA_READ call to answer.
    749  * @param src           Source address space base.
    750  * @param flags         Flags to be used for sharing. Bits can be only cleared.
    751  *
    752  * @return              Zero on success or a value from @ref errno.h on failure.
    753  */
    754 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)
    755772{
    756773        return ipc_answer_2(callid, EOK, (sysarg_t) src, (sysarg_t) flags);
    757774}
    758775
    759 /** Wrapper for making IPC_M_SHARE_OUT calls.
    760  *
    761  * @param phoneid       Phone that will be used to contact the receiving side.
    762  * @param src           Source address space area base address.
    763  * @param flags         Flags to be used for sharing. Bits can be only cleared.
    764  *
    765  * @return              Zero on success or a negative error code from errno.h.
    766  */
    767 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)
    768786{
    769787        return ipc_call_sync_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
     
    773791/** Wrapper for answering the IPC_M_SHARE_OUT calls.
    774792 *
    775  * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT calls
    776  * so that the user doesn't have to remember the meaning of each IPC argument.
    777  *
    778  * @param callid        Hash of the IPC_M_DATA_WRITE call to answer.
    779  * @param dst           Destination address space area base address.   
    780  *
    781  * @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 *
    782802 */
    783803int ipc_share_out_finalize(ipc_callid_t callid, void *dst)
     
    786806}
    787807
    788 
    789 /** Wrapper for making IPC_M_DATA_READ calls.
    790  *
    791  * @param phoneid       Phone that will be used to contact the receiving side.
    792  * @param dst           Address of the beginning of the destination buffer.
    793  * @param size          Size of the destination buffer.
    794  *
    795  * @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 *
    796816 */
    797817int ipc_data_read_start(int phoneid, void *dst, size_t size)
     
    803823/** Wrapper for answering the IPC_M_DATA_READ calls.
    804824 *
    805  * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
    806  * so that the user doesn't have to remember the meaning of each IPC argument.
    807  *
    808  * @param callid        Hash of the IPC_M_DATA_READ call to answer.
    809  * @param src           Source address for the IPC_M_DATA_READ call.
    810  * @param size          Size for the IPC_M_DATA_READ call. Can be smaller than
    811  *                      the maximum size announced by the sender.
    812  *
    813  * @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 *
    814836 */
    815837int ipc_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
     
    818840}
    819841
    820 /** Wrapper for making IPC_M_DATA_WRITE calls.
    821  *
    822  * @param phoneid       Phone that will be used to contact the receiving side.
    823  * @param src           Address of the beginning of the source buffer.
    824  * @param size          Size of the source buffer.
    825  *
    826  * @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 *
    827850 */
    828851int ipc_data_write_start(int phoneid, const void *src, size_t size)
     
    834857/** Wrapper for answering the IPC_M_DATA_WRITE calls.
    835858 *
    836  * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE calls
    837  * so that the user doesn't have to remember the meaning of each IPC argument.
    838  *
    839  * @param callid        Hash of the IPC_M_DATA_WRITE call to answer.
    840  * @param dst           Final destination address for the IPC_M_DATA_WRITE call.
    841  * @param size          Final size for the IPC_M_DATA_WRITE call.
    842  *
    843  * @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 *
    844869 */
    845870int ipc_data_write_finalize(ipc_callid_t callid, void *dst, size_t size)
  • uspace/lib/c/generic/libc.c

    r4fe94c66 r12573db  
    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

    r4fe94c66 r12573db  
    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

    r4fe94c66 r12573db  
    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

    r4fe94c66 r12573db  
    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/modules.c

    r4fe94c66 r12573db  
    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
     
    6764                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 taskhash;
    146                 sysarg_t phonehash;
    147                
    148                 rc = ipc_connect_to_me(phone, arg1, arg2, arg3, &taskhash,
    149                     &phonehash);
     140                int rc = async_connect_to_me(phone, arg1, arg2, arg3, client_receiver);
    150141                if (rc != EOK) {
    151                         ipc_hangup(phone);
     142                        async_hangup(phone);
    152143                        return rc;
    153144                }
    154                 async_new_connection(taskhash, phonehash, 0, NULL,
    155                     client_receiver);
    156145        }
    157146       
  • uspace/lib/c/generic/net/socket_client.c

    r4fe94c66 r12573db  
    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

    r4fe94c66 r12573db  
    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

    r4fe94c66 r12573db  
    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/stats.c

    r4fe94c66 r12573db  
    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

    r4fe94c66 r12573db  
    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

    r4fe94c66 r12573db  
    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

    r4fe94c66 r12573db  
    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

    r4fe94c66 r12573db  
    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

    r4fe94c66 r12573db  
    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>
    4848#include <fibril_synch.h>
     
    118118static void vfs_connect(void)
    119119{
    120         while (vfs_phone < 0) {
    121                 vfs_phone = async_connect_me_to_blocking(PHONE_NS, SERVICE_VFS,
    122                     0, 0);
    123         }
     120        while (vfs_phone < 0)
     121                vfs_phone = service_connect_blocking(SERVICE_VFS, 0, 0);
    124122       
    125123        async_session_create(&vfs_session, vfs_phone, 0);
Note: See TracChangeset for help on using the changeset viewer.