Changeset c4fb95d3 in mainline for uspace/lib/c


Ignore:
Timestamp:
2011-02-18T20:04:56Z (15 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d011038
Parents:
87e373b (diff), 8b1ea2d4 (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
Files:
6 added
95 edited
2 moved

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/Makefile

    r87e373b rc4fb95d3  
    8383        generic/io/console.c \
    8484        generic/io/screenbuffer.c \
     85        generic/ipc/ns.c \
    8586        generic/malloc.c \
    8687        generic/sysinfo.c \
     
    9697        generic/adt/char_map.c \
    9798        generic/time.c \
    98         generic/err.c \
    9999        generic/stdlib.c \
    100100        generic/mman.c \
  • uspace/lib/c/arch/abs32le/_link.ld.in

    r87e373b rc4fb95d3  
    4444        } :data
    4545       
    46         . = ALIGN(0x1000);
    47        
    48         _heap = .;
    49        
    5046        /DISCARD/ : {
    5147                *(*);
  • uspace/lib/c/arch/abs32le/src/entry.c

    r87e373b rc4fb95d3  
    3030 */
    3131
    32 #include <libc.h>
    3332#include <unistd.h>
    3433#include <libarch/entry.h>
     34#include "../../../generic/private/libc.h"
    3535
    3636void __entry(void)
    3737{
    3838        __main(NULL);
    39         __exit();
    4039}
    4140
  • uspace/lib/c/arch/abs32le/src/thread_entry.c

    r87e373b rc4fb95d3  
    3131
    3232#include <unistd.h>
    33 #include <thread.h>
     33#include "../../../generic/private/thread.h"
    3434
    3535void __thread_entry(void)
  • uspace/lib/c/arch/amd64/_link.ld.in

    r87e373b rc4fb95d3  
    55        text PT_LOAD FLAGS(5);
    66        data PT_LOAD FLAGS(6);
     7        debug PT_NOTE;
    78}
    89
     
    1314                *(.init);
    1415        } :text
     16       
    1517        .text : {
    1618                *(.text);
    1719                *(.rodata*);
    1820        } :text
    19 
     21       
    2022        . = . + 0x1000;
    21 
     23       
    2224        .data : {
    2325                *(.data);
    2426        } :data
     27       
    2528        .tdata : {
    2629                _tdata_start = .;
     
    3134                _tbss_end = .;
    3235        } :data
     36       
    3337        _tls_alignment = ALIGNOF(.tdata);
     38       
    3439        .bss : {
    3540                *(COMMON);
    3641                *(.bss);
    3742        } :data
    38 
    39         . = ALIGN(0x1000);
    40         _heap = .;
     43       
     44#ifdef CONFIG_LINE_DEBUG
     45        .comment 0 : { *(.comment); } :debug
     46        .debug_abbrev 0 : { *(.debug_abbrev); } :debug
     47        .debug_aranges 0 : { *(.debug_aranges); } :debug
     48        .debug_info 0 : { *(.debug_info); } :debug
     49        .debug_line 0 : { *(.debug_line); } :debug
     50        .debug_loc 0 : { *(.debug_loc); } :debug
     51        .debug_pubnames 0 : { *(.debug_pubnames); } :debug
     52        .debug_pubtypes 0 : { *(.debug_pubtypes); } :debug
     53        .debug_ranges 0 : { *(.debug_ranges); } :debug
     54        .debug_str 0 : { *(.debug_str); } :debug
     55#endif
    4156       
    4257        /DISCARD/ : {
    4358                *(*);
    4459        }
    45 
    4660}
  • uspace/lib/c/arch/amd64/src/entry.s

    r87e373b rc4fb95d3  
    4747        # Pass PCB pointer to __main (no operation)
    4848        call __main
    49 
    50         call __exit
  • uspace/lib/c/arch/arm32/_link.ld.in

    r87e373b rc4fb95d3  
    99SECTIONS {
    1010        . = 0x1000 + SIZEOF_HEADERS;
    11 
     11       
    1212        .init : {
    1313                *(.init);
    14         } : text
     14        } :text
     15       
    1516        .text : {
    1617                *(.text);
    17         *(.rodata*);
     18                *(.rodata*);
    1819        } :text
    19 
     20       
    2021        . = . + 0x1000;
    21 
     22       
    2223        .data : {
    2324                *(.opd);
     
    2526                *(.sdata);
    2627        } :data
     28       
    2729        .tdata : {
    2830                _tdata_start = .;
     
    3335                _tbss_end = .;
    3436        } :data
     37       
    3538        _tls_alignment = ALIGNOF(.tdata);
     39       
    3640        .bss : {
    3741                *(.sbss);
    3842                *(.scommon);
    39         *(COMMON);
    40         *(.bss);
     43                *(COMMON);
     44                *(.bss);
    4145        } :data
    42        
    43         . = ALIGN(0x1000);
    44         _heap = .;
    4546       
    4647        /DISCARD/ : {
    4748                *(*);
    4849        }
    49 
    5050}
  • uspace/lib/c/arch/arm32/src/entry.s

    r87e373b rc4fb95d3  
    4242        ldr r0, =ras_page
    4343        str r2, [r0]
    44 
     44       
    4545        #
    4646        # Create the first stack frame.
     
    5050        push {fp, ip, lr, pc}
    5151        sub fp, ip, #4
    52 
     52       
    5353        # Pass pcb_ptr to __main as the first argument (in r0)
    5454        mov r0, r1
    5555        bl __main
    56 
    57         bl __exit
    5856
    5957.data
     
    6260ras_page:
    6361        .long 0
    64 
  • uspace/lib/c/arch/ia32/_link.ld.in

    r87e373b rc4fb95d3  
    55        text PT_LOAD FLAGS(5);
    66        data PT_LOAD FLAGS(6);
     7        debug PT_NOTE;
    78}
    89
     
    4243        } :data
    4344       
    44         . = ALIGN(0x1000);
    45        
    46         _heap = .;
     45#ifdef CONFIG_LINE_DEBUG
     46        .comment 0 : { *(.comment); } :debug
     47        .debug_abbrev 0 : { *(.debug_abbrev); } :debug
     48        .debug_aranges 0 : { *(.debug_aranges); } :debug
     49        .debug_info 0 : { *(.debug_info); } :debug
     50        .debug_line 0 : { *(.debug_line); } :debug
     51        .debug_loc 0 : { *(.debug_loc); } :debug
     52        .debug_pubnames 0 : { *(.debug_pubnames); } :debug
     53        .debug_pubtypes 0 : { *(.debug_pubtypes); } :debug
     54        .debug_ranges 0 : { *(.debug_ranges); } :debug
     55        .debug_str 0 : { *(.debug_str); } :debug
     56#endif
    4757       
    4858        /DISCARD/ : {
  • uspace/lib/c/arch/ia32/src/entry.s

    r87e373b rc4fb95d3  
    4646        mov %ax, %fs
    4747        # Do not set %gs, it contains descriptor that can see TLS
    48 
     48       
    4949        # Detect the mechanism used for making syscalls
    5050        movl $(INTEL_CPUID_STANDARD), %eax
     
    5858        # Create the first stack frame.
    5959        #
    60         pushl $0 
     60        pushl $0
    6161        movl %esp, %ebp
    62 
     62       
    6363        # Pass the PCB pointer to __main as the first argument
    6464        pushl %edi
    6565        call __main
    66 
    67         call __exit
  • uspace/lib/c/arch/ia64/_link.ld.in

    r87e373b rc4fb95d3  
    99SECTIONS {
    1010        . = 0x4000 + SIZEOF_HEADERS;
    11 
     11       
    1212        .init : {
    1313                *(.init);
    14         } : text
     14        } :text
     15       
    1516        .text : {
    1617                *(.text);
    1718                *(.rodata*);
    1819        } :text
    19 
     20       
    2021        . = . + 0x4000;
    21 
     22       
    2223        .got : {
    2324                _gp = .;
    2425                *(.got*);
    25         } :data
     26        } :data
     27       
    2628        .data : {
    2729                *(.opd);
     
    2931                *(.sdata);
    3032        } :data
     33       
    3134        .tdata : {
    3235                _tdata_start = .;
     
    3740                _tbss_end = .;
    3841        } :data
     42       
    3943        _tls_alignment = ALIGNOF(.tdata);
     44       
    4045        .bss : {
    4146                *(.sbss);
     
    4449                *(.bss);
    4550        } :data
    46 
    47         . = ALIGN(0x4000);
    48         _heap = .;
    49  
     51       
    5052        /DISCARD/ : {
    5153                *(*);
    52         }
     54        }
    5355}
  • uspace/lib/c/arch/ia64/src/entry.s

    r87e373b rc4fb95d3  
    4040        alloc loc0 = ar.pfs, 0, 1, 2, 0
    4141        movl gp = _gp
    42 
     42       
    4343        # Pass PCB pointer as the first argument to __main
    4444        mov out0 = r2
    4545        br.call.sptk.many b0 = __main
    46 0:
    47         br.call.sptk.many b0 = __exit
  • uspace/lib/c/arch/mips32/_link.ld.in

    r87e373b rc4fb95d3  
    1313                *(.init);
    1414        } :text
     15       
    1516        .text : {
    16                 *(.text);
     17                *(.text);
    1718                *(.rodata*);
    1819        } :text
    19 
     20       
    2021        . = . + 0x4000;
    21 
     22       
    2223        .data : {
    2324                *(.data);
    2425                *(.data.rel*);
    2526        } :data
    26 
     27       
    2728        .got : {
    2829                _gp = .;
    2930                *(.got);
    3031        } :data
    31 
     32       
    3233        .tdata : {
    3334                _tdata_start = .;
    3435                *(.tdata);
    3536                _tdata_end = .;
     37        } :data
     38       
     39        .tbss : {
    3640                _tbss_start = .;
    3741                *(.tbss);
    3842                _tbss_end = .;
    3943        } :data
    40         _tls_alignment = ALIGNOF(.tdata);
    41 
     44       
     45        _tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss));
     46       
    4247        .sbss : {
    4348                *(.scommon);
    4449                *(.sbss);
    45         }       
     50        }
     51       
    4652        .bss : {
    4753                *(.bss);
    4854                *(COMMON);
    4955        } :data
    50 
    51         . = ALIGN(0x4000);
    52         _heap = .;
    53 
     56       
    5457        /DISCARD/ : {
    5558                *(*);
  • uspace/lib/c/arch/mips32/src/entry.s

    r87e373b rc4fb95d3  
    2929.text
    3030.section .init, "ax"
     31
    3132.global __entry
    32 .global __entry_driver
     33
    3334.set noreorder
    3435.option pic2
     
    5657        jal __main
    5758        nop
    58        
    59         jal __exit
    60         nop
    6159.end
    62 
    63 # Alignment of output section data to 0x4000
    64 .section .data
    65 .align 14
  • uspace/lib/c/arch/ppc32/_link.ld.in

    r87e373b rc4fb95d3  
    99SECTIONS {
    1010        . = 0x1000 + SIZEOF_HEADERS;
    11 
     11       
    1212        .init : {
    1313                *(.init);
    1414        } :text
     15       
    1516        .text : {
    1617                *(.text);
    1718                *(.rodata*);
    1819        } :text
    19 
     20       
    2021        . = . + 0x1000;
    21 
     22       
    2223        .data : {
    2324                *(.data);
    2425                *(.sdata);
    2526        } :data
     27       
    2628        .tdata : {
    2729                _tdata_start = .;
     
    3234                _tbss_end = .;
    3335        } :data
     36       
    3437        _tls_alignment = ALIGNOF(.tdata);
     38       
    3539        .bss : {
    3640                *(.sbss);
     
    3842                *(.bss);
    3943        } :data
    40 
    41         . = ALIGN(0x1000);
    42         _heap = .;
    4344       
    4445        /DISCARD/ : {
    4546                *(*);
    4647        }
    47 
    4848}
  • uspace/lib/c/arch/ppc32/src/entry.s

    r87e373b rc4fb95d3  
    4444        stw %r3, 0(%r1)
    4545        stwu %r1, -16(%r1)
    46 
     46       
    4747        # Pass the PCB pointer to __main() as the first argument.
    4848        # The first argument is passed in r3.
    4949        mr %r3, %r6
    5050        bl __main
    51 
    52         bl __exit
  • uspace/lib/c/arch/sparc64/_link.ld.in

    r87e373b rc4fb95d3  
    99SECTIONS {
    1010        . = 0x4000 + SIZEOF_HEADERS;
    11 
     11       
    1212        .init : {
    1313                *(.init);
    1414        } :text
     15       
    1516        .text : {
    1617                *(.text);
    1718                *(.rodata*);
    1819        } :text
    19 
     20       
    2021        . = . + 0x4000;
    21 
     22       
    2223        .got : {
    2324                 _gp = .;
    2425                 *(.got*);
    2526        } :data
     27       
    2628        .data : {
    2729                *(.data);
    2830                *(.sdata);
    2931        } :data
     32       
    3033        .tdata : {
    3134                _tdata_start = .;
     
    3639                _tbss_end = .;
    3740        } :data
     41       
    3842        _tls_alignment = ALIGNOF(.tdata);
     43       
    3944        .bss : {
    4045                *(.sbss);
     
    4247                *(.bss);
    4348        } :data
    44 
    45         . = ALIGN(0x4000);
    46         _heap = .;
    4749       
    4850        /DISCARD/ : {
    4951                *(*);
    5052        }
    51 
    5253}
  • uspace/lib/c/arch/sparc64/src/entry.s

    r87e373b rc4fb95d3  
    4545        flushw
    4646        add %g0, -0x7ff, %fp
    47 
     47       
    4848        # Pass pcb_ptr as the first argument to __main()
    4949        mov %i1, %o0
     
    5151        call __main
    5252        or %l7, %lo(_gp), %l7
    53 
    54         call __exit
    55         nop
  • uspace/lib/c/generic/as.c

    r87e373b rc4fb95d3  
    4040#include <bitops.h>
    4141#include <malloc.h>
    42 
    43 /** Last position allocated by as_get_mappable_page */
    44 static uintptr_t last_allocated = 0;
     42#include "private/libc.h"
    4543
    4644/** Create address space area.
     
    103101}
    104102
    105 /** Return pointer to some unmapped area, where fits new as_area
     103/** Return pointer to unmapped address space area
    106104 *
    107105 * @param size Requested size of the allocation.
    108106 *
    109  * @return pointer to the beginning
     107 * @return Pointer to the beginning of unmapped address space area.
    110108 *
    111109 */
    112110void *as_get_mappable_page(size_t size)
    113111{
    114         if (size == 0)
    115                 return NULL;
    116        
    117         size_t sz = 1 << (fnzb(size - 1) + 1);
    118         if (last_allocated == 0)
    119                 last_allocated = get_max_heap_addr();
    120        
    121         /*
    122          * Make sure we allocate from naturally aligned address.
    123          */
    124         uintptr_t res = ALIGN_UP(last_allocated, sz);
    125         last_allocated = res + ALIGN_UP(size, PAGE_SIZE);
    126        
    127         return ((void *) res);
     112        return (void *) __SYSCALL2(SYS_AS_GET_UNMAPPED_AREA,
     113            (sysarg_t) __entry, (sysarg_t) size);
    128114}
    129115
  • uspace/lib/c/generic/async.c

    r87e373b rc4fb95d3  
    4343 * framework will automatically take care of most synchronization problems.
    4444 *
    45  * Default semantics:
    46  * - async_send_*(): Send asynchronously. If the kernel refuses to send
    47  *                   more messages, [ try to get responses from kernel, if
    48  *                   nothing found, might try synchronous ]
    49  *
    5045 * Example of use (pseudo C):
    5146 *
     
    5853 *   int fibril1(void *arg)
    5954 *   {
    60  *     conn = ipc_connect_me_to();
     55 *     conn = async_connect_me_to();
    6156 *     c1 = async_send(conn);
    6257 *     c2 = async_send(conn);
     
    7772 *   {
    7873 *     if (want_refuse) {
    79  *       ipc_answer_0(icallid, ELIMIT);
     74 *       async_answer_0(icallid, ELIMIT);
    8075 *       return;
    8176 *     }
    82  *     ipc_answer_0(icallid, EOK);
     77 *     async_answer_0(icallid, EOK);
    8378 *
    8479 *     callid = async_get_call(&call);
    8580 *     somehow_handle_the_call(callid, call);
    86  *     ipc_answer_2(callid, 1, 2, 3);
     81 *     async_answer_2(callid, 1, 2, 3);
    8782 *
    8883 *     callid = async_get_call(&call);
     
    9287 */
    9388
     89#define LIBC_ASYNC_C_
     90#include <ipc/ipc.h>
     91#include <async.h>
     92#undef LIBC_ASYNC_C_
     93
    9494#include <futex.h>
    95 #include <async.h>
    96 #include <async_priv.h>
    9795#include <fibril.h>
    9896#include <stdio.h>
    9997#include <adt/hash_table.h>
    10098#include <adt/list.h>
    101 #include <ipc/ipc.h>
    10299#include <assert.h>
    103100#include <errno.h>
     
    105102#include <arch/barrier.h>
    106103#include <bool.h>
     104#include "private/async.h"
    107105
    108106atomic_t async_futex = FUTEX_INITIALIZER;
     
    124122
    125123/**
    126  * Structures of this type are used to group information about a call and a
    127  * message queue link.
     124 * Structures of this type are used to group information about
     125 * a call and about a message queue link.
    128126 */
    129127typedef struct {
     
    134132
    135133typedef struct {
     134        sysarg_t in_task_hash;
     135        link_t link;
     136        int refcnt;
     137        void *data;
     138} client_t;
     139
     140typedef struct {
    136141        awaiter_t wdata;
    137142       
     
    139144        link_t link;
    140145       
     146        /** Incoming client task hash. */
     147        sysarg_t in_task_hash;
    141148        /** Incoming phone hash. */
    142149        sysarg_t in_phone_hash;
     150       
     151        /** Link to the client tracking structure. */
     152        client_t *client;
    143153       
    144154        /** Messages that should be delivered to this fibril. */
     
    158168
    159169/** Identifier of the incoming connection handled by the current fibril. */
    160 fibril_local connection_t *FIBRIL_connection;
    161 
    162 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call);
    163 static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call);
     170static fibril_local connection_t *FIBRIL_connection;
     171
     172static void *default_client_data_constructor(void)
     173{
     174        return NULL;
     175}
     176
     177static void default_client_data_destructor(void *data)
     178{
     179}
     180
     181static async_client_data_ctor_t async_client_data_create =
     182    default_client_data_constructor;
     183static async_client_data_dtor_t async_client_data_destroy =
     184    default_client_data_destructor;
     185
     186void async_set_client_data_constructor(async_client_data_ctor_t ctor)
     187{
     188        async_client_data_create = ctor;
     189}
     190
     191void async_set_client_data_destructor(async_client_data_dtor_t dtor)
     192{
     193        async_client_data_destroy = dtor;
     194}
     195
     196void *async_client_data_get(void)
     197{
     198        assert(FIBRIL_connection);
     199        return FIBRIL_connection->client->data;
     200}
     201
     202/** Default fibril function that gets called to handle new connection.
     203 *
     204 * This function is defined as a weak symbol - to be redefined in user code.
     205 *
     206 * @param callid Hash of the incoming call.
     207 * @param call   Data of the incoming call.
     208 *
     209 */
     210static void default_client_connection(ipc_callid_t callid, ipc_call_t *call)
     211{
     212        ipc_answer_0(callid, ENOENT);
     213}
    164214
    165215/**
     
    167217 */
    168218static async_client_conn_t client_connection = default_client_connection;
     219
     220/** Default fibril function that gets called to handle interrupt notifications.
     221 *
     222 * This function is defined as a weak symbol - to be redefined in user code.
     223 *
     224 * @param callid Hash of the incoming call.
     225 * @param call   Data of the incoming call.
     226 *
     227 */
     228static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call)
     229{
     230}
    169231
    170232/**
     
    174236static async_client_conn_t interrupt_received = default_interrupt_received;
    175237
     238static hash_table_t client_hash_table;
    176239static hash_table_t conn_hash_table;
    177240static LIST_INITIALIZE(timeout_list);
    178241
    179 #define CONN_HASH_TABLE_CHAINS  32
     242#define CLIENT_HASH_TABLE_BUCKETS  32
     243#define CONN_HASH_TABLE_BUCKETS    32
     244
     245static hash_index_t client_hash(unsigned long key[])
     246{
     247        assert(key);
     248        return (((key[0]) >> 4) % CLIENT_HASH_TABLE_BUCKETS);
     249}
     250
     251static int client_compare(unsigned long key[], hash_count_t keys, link_t *item)
     252{
     253        client_t *client = hash_table_get_instance(item, client_t, link);
     254        return (key[0] == client->in_task_hash);
     255}
     256
     257static void client_remove(link_t *item)
     258{
     259}
     260
     261/** Operations for the client hash table. */
     262static hash_table_operations_t client_hash_table_ops = {
     263        .hash = client_hash,
     264        .compare = client_compare,
     265        .remove_callback = client_remove
     266};
    180267
    181268/** Compute hash into the connection hash table based on the source phone hash.
     
    186273 *
    187274 */
    188 static hash_index_t conn_hash(unsigned long *key)
     275static hash_index_t conn_hash(unsigned long key[])
    189276{
    190277        assert(key);
    191         return (((*key) >> 4) % CONN_HASH_TABLE_CHAINS);
     278        return (((key[0]) >> 4) % CONN_HASH_TABLE_BUCKETS);
    192279}
    193280
     
    203290static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item)
    204291{
    205         connection_t *hs = hash_table_get_instance(item, connection_t, link);
    206         return (key[0] == hs->in_phone_hash);
    207 }
    208 
    209 /** Connection hash table removal callback function.
    210  *
    211  * This function is called whenever a connection is removed from the connection
    212  * hash table.
    213  *
    214  * @param item Connection hash table item being removed.
    215  *
    216  */
     292        connection_t *conn = hash_table_get_instance(item, connection_t, link);
     293        return (key[0] == conn->in_phone_hash);
     294}
     295
    217296static void conn_remove(link_t *item)
    218297{
    219         free(hash_table_get_instance(item, connection_t, link));
    220 }
    221 
     298}
    222299
    223300/** Operations for the connection hash table. */
     
    240317        link_t *tmp = timeout_list.next;
    241318        while (tmp != &timeout_list) {
    242                 awaiter_t *cur;
    243                
    244                 cur = list_get_instance(tmp, awaiter_t, to_event.link);
     319                awaiter_t *cur
     320                    = list_get_instance(tmp, awaiter_t, to_event.link);
     321               
    245322                if (tv_gteq(&cur->to_event.expires, &wd->to_event.expires))
    246323                        break;
     324               
    247325                tmp = tmp->next;
    248326        }
     
    261339 *
    262340 * @return False if the call doesn't match any connection.
    263  *         True if the call was passed to the respective connection fibril.
     341 * @return True if the call was passed to the respective connection fibril.
    264342 *
    265343 */
     
    352430       
    353431        fid_t fid = fibril_create(notification_fibril, msg);
     432        if (fid == 0) {
     433                free(msg);
     434                futex_up(&async_futex);
     435                return false;
     436        }
     437       
    354438        fibril_add_ready(fid);
    355439       
     
    398482                         * the first IPC_M_PHONE_HUNGUP call and continues to
    399483                         * call async_get_call_timeout(). Repeat
    400                          * IPC_M_PHONE_HUNGUP until the caller notices. 
     484                         * IPC_M_PHONE_HUNGUP until the caller notices.
    401485                         */
    402486                        memset(call, 0, sizeof(ipc_call_t));
     
    405489                        return conn->close_callid;
    406490                }
    407 
     491               
    408492                if (usecs)
    409493                        async_insert_timeout(&conn->wdata);
     
    443527}
    444528
    445 /** Default fibril function that gets called to handle new connection.
    446  *
    447  * This function is defined as a weak symbol - to be redefined in user code.
    448  *
    449  * @param callid Hash of the incoming call.
    450  * @param call   Data of the incoming call.
    451  *
    452  */
    453 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call)
    454 {
    455         ipc_answer_0(callid, ENOENT);
    456 }
    457 
    458 /** Default fibril function that gets called to handle interrupt notifications.
    459  *
    460  * This function is defined as a weak symbol - to be redefined in user code.
    461  *
    462  * @param callid Hash of the incoming call.
    463  * @param call   Data of the incoming call.
    464  *
    465  */
    466 static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call)
    467 {
    468 }
    469 
    470529/** Wrapper for client connection fibril.
    471530 *
     
    481540{
    482541        /*
    483          * Setup fibril-local connection pointer and call client_connection().
    484          *
     542         * Setup fibril-local connection pointer.
    485543         */
    486544        FIBRIL_connection = (connection_t *) arg;
     545       
     546        futex_down(&async_futex);
     547       
     548        /*
     549         * Add our reference for the current connection in the client task
     550         * tracking structure. If this is the first reference, create and
     551         * hash in a new tracking structure.
     552         */
     553       
     554        unsigned long key = FIBRIL_connection->in_task_hash;
     555        link_t *lnk = hash_table_find(&client_hash_table, &key);
     556       
     557        client_t *client;
     558       
     559        if (lnk) {
     560                client = hash_table_get_instance(lnk, client_t, link);
     561                client->refcnt++;
     562        } else {
     563                client = malloc(sizeof(client_t));
     564                if (!client) {
     565                        ipc_answer_0(FIBRIL_connection->callid, ENOMEM);
     566                        futex_up(&async_futex);
     567                        return 0;
     568                }
     569               
     570                client->in_task_hash = FIBRIL_connection->in_task_hash;
     571               
     572                async_serialize_start();
     573                client->data = async_client_data_create();
     574                async_serialize_end();
     575               
     576                client->refcnt = 1;
     577                hash_table_insert(&client_hash_table, &key, &client->link);
     578        }
     579       
     580        futex_up(&async_futex);
     581       
     582        FIBRIL_connection->client = client;
     583       
     584        /*
     585         * Call the connection handler function.
     586         */
    487587        FIBRIL_connection->cfibril(FIBRIL_connection->callid,
    488588            &FIBRIL_connection->call);
    489589       
    490         /* Remove myself from the connection hash table */
     590        /*
     591         * Remove the reference for this client task connection.
     592         */
     593        bool destroy;
     594       
    491595        futex_down(&async_futex);
    492         unsigned long key = FIBRIL_connection->in_phone_hash;
     596       
     597        if (--client->refcnt == 0) {
     598                hash_table_remove(&client_hash_table, &key, 1);
     599                destroy = true;
     600        } else
     601                destroy = false;
     602       
     603        futex_up(&async_futex);
     604       
     605        if (destroy) {
     606                if (client->data)
     607                        async_client_data_destroy(client->data);
     608               
     609                free(client);
     610        }
     611       
     612        /*
     613         * Remove myself from the connection hash table.
     614         */
     615        futex_down(&async_futex);
     616        key = FIBRIL_connection->in_phone_hash;
    493617        hash_table_remove(&conn_hash_table, &key, 1);
    494618        futex_up(&async_futex);
    495619       
    496         /* Answer all remaining messages with EHANGUP */
     620        /*
     621         * Answer all remaining messages with EHANGUP.
     622         */
    497623        while (!list_empty(&FIBRIL_connection->msg_queue)) {
    498                 msg_t *msg;
    499                
    500                 msg = list_get_instance(FIBRIL_connection->msg_queue.next,
    501                     msg_t, link);
     624                msg_t *msg =
     625                    list_get_instance(FIBRIL_connection->msg_queue.next, msg_t,
     626                    link);
     627               
    502628                list_remove(&msg->link);
    503629                ipc_answer_0(msg->callid, EHANGUP);
     
    505631        }
    506632       
     633        /*
     634         * If the connection was hung-up, answer the last call,
     635         * i.e. IPC_M_PHONE_HUNGUP.
     636         */
    507637        if (FIBRIL_connection->close_callid)
    508638                ipc_answer_0(FIBRIL_connection->close_callid, EOK);
    509639       
     640        free(FIBRIL_connection);
    510641        return 0;
    511642}
     
    517648 * particular fibrils.
    518649 *
     650 * @param in_task_hash  Identification of the incoming connection.
    519651 * @param in_phone_hash Identification of the incoming connection.
    520652 * @param callid        Hash of the opening IPC_M_CONNECT_ME_TO call.
     
    529661 *
    530662 */
    531 fid_t async_new_connection(sysarg_t in_phone_hash, ipc_callid_t callid,
    532     ipc_call_t *call, void (*cfibril)(ipc_callid_t, ipc_call_t *))
     663fid_t async_new_connection(sysarg_t in_task_hash, sysarg_t in_phone_hash,
     664    ipc_callid_t callid, ipc_call_t *call,
     665    void (*cfibril)(ipc_callid_t, ipc_call_t *))
    533666{
    534667        connection_t *conn = malloc(sizeof(*conn));
     
    536669                if (callid)
    537670                        ipc_answer_0(callid, ENOMEM);
     671               
    538672                return (uintptr_t) NULL;
    539673        }
    540674       
     675        conn->in_task_hash = in_task_hash;
    541676        conn->in_phone_hash = in_phone_hash;
    542677        list_initialize(&conn->msg_queue);
     
    552687        conn->wdata.fid = fibril_create(connection_fibril, conn);
    553688       
    554         if (!conn->wdata.fid) {
     689        if (conn->wdata.fid == 0) {
    555690                free(conn);
     691               
    556692                if (callid)
    557693                        ipc_answer_0(callid, ENOMEM);
     694               
    558695                return (uintptr_t) NULL;
    559696        }
     
    582719static void handle_call(ipc_callid_t callid, ipc_call_t *call)
    583720{
    584         /* Unrouted call - do some default behaviour */
     721        /* Unrouted call - take some default action */
    585722        if ((callid & IPC_CALLID_NOTIFICATION)) {
    586723                process_notification(callid, call);
    587                 goto out;
     724                return;
    588725        }
    589726       
     
    591728        case IPC_M_CONNECT_ME:
    592729        case IPC_M_CONNECT_ME_TO:
    593                 /* Open new connection with fibril etc. */
    594                 async_new_connection(IPC_GET_ARG5(*call), callid, call,
    595                     client_connection);
    596                 goto out;
     730                /* Open new connection with fibril, etc. */
     731                async_new_connection(call->in_task_hash, IPC_GET_ARG5(*call),
     732                    callid, call, client_connection);
     733                return;
    597734        }
    598735       
    599736        /* Try to route the call through the connection hash table */
    600737        if (route_call(callid, call))
    601                 goto out;
     738                return;
    602739       
    603740        /* Unknown call from unknown phone - hang it up */
    604741        ipc_answer_0(callid, EHANGUP);
    605         return;
    606        
    607 out:
    608         ;
    609742}
    610743
     
    619752        link_t *cur = timeout_list.next;
    620753        while (cur != &timeout_list) {
    621                 awaiter_t *waiter;
    622                
    623                 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               
    624757                if (tv_gt(&waiter->to_event.expires, &tv))
    625758                        break;
    626 
     759               
    627760                cur = cur->next;
    628 
     761               
    629762                list_remove(&waiter->to_event.link);
    630763                waiter->to_event.inlist = false;
     
    653786        while (true) {
    654787                if (fibril_switch(FIBRIL_FROM_MANAGER)) {
    655                         futex_up(&async_futex); 
     788                        futex_up(&async_futex);
    656789                        /*
    657790                         * async_futex is always held when entering a manager
     
    676809                                continue;
    677810                        } else
    678                                 timeout = tv_sub(&waiter->to_event.expires,
    679                                     &tv);
     811                                timeout = tv_sub(&waiter->to_event.expires, &tv);
    680812                } else
    681813                        timeout = SYNCH_NO_TIMEOUT;
    682814               
    683815                futex_up(&async_futex);
    684 
     816               
    685817                atomic_inc(&threads_in_ipc_wait);
    686818               
     
    690822               
    691823                atomic_dec(&threads_in_ipc_wait);
    692 
     824               
    693825                if (!callid) {
    694826                        handle_expired_timeouts();
     
    729861{
    730862        fid_t fid = fibril_create(async_manager_fibril, NULL);
    731         fibril_add_manager(fid);
     863        if (fid != 0)
     864                fibril_add_manager(fid);
    732865}
    733866
     
    740873/** Initialize the async framework.
    741874 *
    742  * @return Zero on success or an error code.
    743  */
    744 int __async_init(void)
    745 {
    746         if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_CHAINS, 1,
    747             &conn_hash_table_ops)) {
    748                 printf("%s: Cannot create async hash table\n", "libc");
    749                 return ENOMEM;
    750         }
    751 
    752         _async_sess_init();
    753        
    754         return 0;
     875 */
     876void __async_init(void)
     877{
     878        if (!hash_table_create(&client_hash_table, CLIENT_HASH_TABLE_BUCKETS, 1,
     879            &client_hash_table_ops))
     880                abort();
     881       
     882        if (!hash_table_create(&conn_hash_table, CONN_HASH_TABLE_BUCKETS, 1,
     883            &conn_hash_table_ops))
     884                abort();
    755885}
    756886
     
    765895 * @param retval Value returned in the answer.
    766896 * @param data   Call data of the answer.
     897 *
    767898 */
    768899static void reply_received(void *arg, int retval, ipc_call_t *data)
     
    812943    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr)
    813944{
    814         amsg_t *msg = malloc(sizeof(*msg));
     945        amsg_t *msg = malloc(sizeof(amsg_t));
    815946       
    816947        if (!msg)
     
    821952       
    822953        msg->wdata.to_event.inlist = false;
    823         /* We may sleep in the next method, but it will use its own mechanism */
     954       
     955        /*
     956         * We may sleep in the next method,
     957         * but it will use its own means
     958         */
    824959        msg->wdata.active = true;
    825960       
     
    852987    ipc_call_t *dataptr)
    853988{
    854         amsg_t *msg = malloc(sizeof(*msg));
     989        amsg_t *msg = malloc(sizeof(amsg_t));
    855990       
    856991        if (!msg)
     
    861996       
    862997        msg->wdata.to_event.inlist = false;
    863         /* We may sleep in next method, but it will use its own mechanism */
     998       
     999        /*
     1000         * We may sleep in the next method,
     1001         * but it will use its own means
     1002         */
    8641003        msg->wdata.active = true;
    8651004       
     
    9601099void async_usleep(suseconds_t timeout)
    9611100{
    962         amsg_t *msg = malloc(sizeof(*msg));
     1101        amsg_t *msg = malloc(sizeof(amsg_t));
    9631102       
    9641103        if (!msg)
     
    11031242}
    11041243
     1244void async_msg_0(int phone, sysarg_t imethod)
     1245{
     1246        ipc_call_async_0(phone, imethod, NULL, NULL, true);
     1247}
     1248
     1249void async_msg_1(int phone, sysarg_t imethod, sysarg_t arg1)
     1250{
     1251        ipc_call_async_1(phone, imethod, arg1, NULL, NULL, true);
     1252}
     1253
     1254void async_msg_2(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2)
     1255{
     1256        ipc_call_async_2(phone, imethod, arg1, arg2, NULL, NULL, true);
     1257}
     1258
     1259void async_msg_3(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
     1260    sysarg_t arg3)
     1261{
     1262        ipc_call_async_3(phone, imethod, arg1, arg2, arg3, NULL, NULL, true);
     1263}
     1264
     1265void async_msg_4(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
     1266    sysarg_t arg3, sysarg_t arg4)
     1267{
     1268        ipc_call_async_4(phone, imethod, arg1, arg2, arg3, arg4, NULL, NULL,
     1269            true);
     1270}
     1271
     1272void async_msg_5(int phone, sysarg_t imethod, sysarg_t arg1, sysarg_t arg2,
     1273    sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
     1274{
     1275        ipc_call_async_5(phone, imethod, arg1, arg2, arg3, arg4, arg5, NULL,
     1276            NULL, true);
     1277}
     1278
     1279sysarg_t async_answer_0(ipc_callid_t callid, sysarg_t retval)
     1280{
     1281        return ipc_answer_0(callid, retval);
     1282}
     1283
     1284sysarg_t async_answer_1(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1)
     1285{
     1286        return ipc_answer_1(callid, retval, arg1);
     1287}
     1288
     1289sysarg_t async_answer_2(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     1290    sysarg_t arg2)
     1291{
     1292        return ipc_answer_2(callid, retval, arg1, arg2);
     1293}
     1294
     1295sysarg_t async_answer_3(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     1296    sysarg_t arg2, sysarg_t arg3)
     1297{
     1298        return ipc_answer_3(callid, retval, arg1, arg2, arg3);
     1299}
     1300
     1301sysarg_t async_answer_4(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     1302    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4)
     1303{
     1304        return ipc_answer_4(callid, retval, arg1, arg2, arg3, arg4);
     1305}
     1306
     1307sysarg_t async_answer_5(ipc_callid_t callid, sysarg_t retval, sysarg_t arg1,
     1308    sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5)
     1309{
     1310        return ipc_answer_5(callid, retval, arg1, arg2, arg3, arg4, arg5);
     1311}
     1312
     1313int async_forward_fast(ipc_callid_t callid, int phoneid, sysarg_t imethod,
     1314    sysarg_t arg1, sysarg_t arg2, unsigned int mode)
     1315{
     1316        return ipc_forward_fast(callid, phoneid, imethod, arg1, arg2, mode);
     1317}
     1318
     1319int async_forward_slow(ipc_callid_t callid, int phoneid, sysarg_t imethod,
     1320    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
     1321    unsigned int mode)
     1322{
     1323        return ipc_forward_slow(callid, phoneid, imethod, arg1, arg2, arg3, arg4,
     1324            arg5, mode);
     1325}
     1326
     1327/** Wrapper for making IPC_M_CONNECT_TO_ME calls using the async framework.
     1328 *
     1329 * Ask through phone for a new connection to some service.
     1330 *
     1331 * @param phone           Phone handle used for contacting the other side.
     1332 * @param arg1            User defined argument.
     1333 * @param arg2            User defined argument.
     1334 * @param arg3            User defined argument.
     1335 * @param client_receiver Connection handing routine.
     1336 *
     1337 * @return New phone handle on success or a negative error code.
     1338 *
     1339 */
     1340int async_connect_to_me(int phone, sysarg_t arg1, sysarg_t arg2,
     1341    sysarg_t arg3, async_client_conn_t client_receiver)
     1342{
     1343        sysarg_t task_hash;
     1344        sysarg_t phone_hash;
     1345        int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, arg1, arg2, arg3,
     1346            NULL, NULL, NULL, &task_hash, &phone_hash);
     1347        if (rc != EOK)
     1348                return rc;
     1349       
     1350        if (client_receiver != NULL)
     1351                async_new_connection(task_hash, phone_hash, 0, NULL,
     1352                    client_receiver);
     1353       
     1354        return EOK;
     1355}
     1356
    11051357/** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
    1106  * 
     1358 *
    11071359 * Ask through phone for a new connection to some service.
    11081360 *
    1109  * @param phoneid       Phone handle used for contacting the other side.
    1110  * @param arg1          User defined argument.
    1111  * @param arg2          User defined argument.
    1112  * @param arg3          User defined argument.
    1113  *
    1114  * @return              New phone handle on success or a negative error code.
    1115  */
    1116 int
    1117 async_connect_me_to(int phoneid, sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
    1118 {
    1119         int rc;
     1361 * @param phone Phone handle used for contacting the other side.
     1362 * @param arg1  User defined argument.
     1363 * @param arg2  User defined argument.
     1364 * @param arg3  User defined argument.
     1365 *
     1366 * @return New phone handle on success or a negative error code.
     1367 *
     1368 */
     1369int async_connect_me_to(int phone, sysarg_t arg1, sysarg_t arg2,
     1370    sysarg_t arg3)
     1371{
    11201372        sysarg_t newphid;
    1121 
    1122         rc = async_req_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, NULL,
    1123             NULL, NULL, NULL, &newphid);
    1124        
    1125         if (rc != EOK) 
     1373        int rc = async_req_3_5(phone, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     1374            NULL, NULL, NULL, NULL, &newphid);
     1375       
     1376        if (rc != EOK)
    11261377                return rc;
    1127 
     1378       
    11281379        return newphid;
    11291380}
    11301381
    11311382/** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
    1132  * 
     1383 *
    11331384 * Ask through phone for a new connection to some service and block until
    11341385 * success.
    11351386 *
    1136  * @param phoneid       Phone handle used for contacting the other side.
    1137  * @param arg1          User defined argument.
    1138  * @param arg2          User defined argument.
    1139  * @param arg3          User defined argument.
    1140  *
    1141  * @return              New phone handle on success or a negative error code.
    1142  */
    1143 int
    1144 async_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,
     1387 * @param phoneid Phone handle used for contacting the other side.
     1388 * @param arg1    User defined argument.
     1389 * @param arg2    User defined argument.
     1390 * @param arg3    User defined argument.
     1391 *
     1392 * @return New phone handle on success or a negative error code.
     1393 *
     1394 */
     1395int async_connect_me_to_blocking(int phoneid, sysarg_t arg1, sysarg_t arg2,
    11451396    sysarg_t arg3)
    11461397{
    1147         int rc;
    11481398        sysarg_t newphid;
    1149 
    1150         rc = async_req_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
     1399        int rc = async_req_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3,
    11511400            IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid);
    11521401       
    1153         if (rc != EOK) 
     1402        if (rc != EOK)
    11541403                return rc;
    1155 
     1404       
    11561405        return newphid;
    11571406}
    11581407
    1159 /** Wrapper for making IPC_M_SHARE_IN calls using the async framework.
    1160  *
    1161  * @param phoneid       Phone that will be used to contact the receiving side.
    1162  * @param dst           Destination address space area base.
    1163  * @param size          Size of the destination address space area.
    1164  * @param arg           User defined argument.
    1165  * @param flags         Storage where the received flags will be stored. Can be
    1166  *                      NULL.
    1167  *
    1168  * @return              Zero on success or a negative error code from errno.h.
     1408/** Connect to a task specified by id.
     1409 *
     1410 */
     1411int async_connect_kbox(task_id_t id)
     1412{
     1413        return ipc_connect_kbox(id);
     1414}
     1415
     1416/** Wrapper for ipc_hangup.
     1417 *
     1418 * @param phone Phone handle to hung up.
     1419 *
     1420 * @return Zero on success or a negative error code.
     1421 *
     1422 */
     1423int async_hangup(int phone)
     1424{
     1425        return ipc_hangup(phone);
     1426}
     1427
     1428/** Interrupt one thread of this task from waiting for IPC. */
     1429void async_poke(void)
     1430{
     1431        ipc_poke();
     1432}
     1433
     1434/** Wrapper for IPC_M_SHARE_IN calls using the async framework.
     1435 *
     1436 * @param phoneid Phone that will be used to contact the receiving side.
     1437 * @param dst     Destination address space area base.
     1438 * @param size    Size of the destination address space area.
     1439 * @param arg     User defined argument.
     1440 * @param flags   Storage for the received flags. Can be NULL.
     1441 *
     1442 * @return Zero on success or a negative error code from errno.h.
     1443 *
    11691444 */
    11701445int async_share_in_start(int phoneid, void *dst, size_t size, sysarg_t arg,
    1171     int *flags)
    1172 {
    1173         int res;
     1446    unsigned int *flags)
     1447{
    11741448        sysarg_t tmp_flags;
    1175         res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,
     1449        int res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (sysarg_t) dst,
    11761450            (sysarg_t) size, arg, NULL, &tmp_flags);
     1451       
    11771452        if (flags)
    1178                 *flags = tmp_flags;
     1453                *flags = (unsigned int) tmp_flags;
     1454       
    11791455        return res;
    11801456}
     
    11821458/** Wrapper for receiving the IPC_M_SHARE_IN calls using the async framework.
    11831459 *
    1184  * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN calls
    1185  * so that the user doesn't have to remember the meaning of each IPC argument.
     1460 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_IN
     1461 * calls so that the user doesn't have to remember the meaning of each IPC
     1462 * argument.
    11861463 *
    11871464 * So far, this wrapper is to be used from within a connection fibril.
    11881465 *
    1189  * @param callid        Storage where the hash of the IPC_M_SHARE_IN call will
    1190  *                      be stored.
    1191  * @param size          Destination address space area size.   
    1192  *
    1193  * @return              Non-zero on success, zero on failure.
    1194  */
    1195 int async_share_in_receive(ipc_callid_t *callid, size_t *size)
    1196 {
    1197         ipc_call_t data;
    1198        
     1466 * @param callid Storage for the hash of the IPC_M_SHARE_IN call.
     1467 * @param size   Destination address space area size.
     1468 *
     1469 * @return True on success, false on failure.
     1470 *
     1471 */
     1472bool async_share_in_receive(ipc_callid_t *callid, size_t *size)
     1473{
    11991474        assert(callid);
    12001475        assert(size);
    1201 
     1476       
     1477        ipc_call_t data;
    12021478        *callid = async_get_call(&data);
     1479       
    12031480        if (IPC_GET_IMETHOD(data) != IPC_M_SHARE_IN)
    1204                 return 0;
     1481                return false;
     1482       
    12051483        *size = (size_t) IPC_GET_ARG2(data);
    1206         return 1;
     1484        return true;
    12071485}
    12081486
    12091487/** Wrapper for answering the IPC_M_SHARE_IN calls using the async framework.
    12101488 *
    1211  * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
    1212  * so that the user doesn't have to remember the meaning of each IPC argument.
    1213  *
    1214  * @param callid        Hash of the IPC_M_DATA_READ call to answer.
    1215  * @param src           Source address space base.
    1216  * @param flags         Flags to be used for sharing. Bits can be only cleared.
    1217  *
    1218  * @return              Zero on success or a value from @ref errno.h on failure.
    1219  */
    1220 int async_share_in_finalize(ipc_callid_t callid, void *src, int flags)
     1489 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ
     1490 * calls so that the user doesn't have to remember the meaning of each IPC
     1491 * argument.
     1492 *
     1493 * @param callid Hash of the IPC_M_DATA_READ call to answer.
     1494 * @param src    Source address space base.
     1495 * @param flags  Flags to be used for sharing. Bits can be only cleared.
     1496 *
     1497 * @return Zero on success or a value from @ref errno.h on failure.
     1498 *
     1499 */
     1500int async_share_in_finalize(ipc_callid_t callid, void *src, unsigned int flags)
    12211501{
    12221502        return ipc_share_in_finalize(callid, src, flags);
    12231503}
    12241504
    1225 /** Wrapper for making IPC_M_SHARE_OUT calls using the async framework.
    1226  *
    1227  * @param phoneid       Phone that will be used to contact the receiving side.
    1228  * @param src           Source address space area base address.
    1229  * @param flags         Flags to be used for sharing. Bits can be only cleared.
    1230  *
    1231  * @return              Zero on success or a negative error code from errno.h.
    1232  */
    1233 int async_share_out_start(int phoneid, void *src, int flags)
     1505/** Wrapper for IPC_M_SHARE_OUT calls using the async framework.
     1506 *
     1507 * @param phoneid Phone that will be used to contact the receiving side.
     1508 * @param src     Source address space area base address.
     1509 * @param flags   Flags to be used for sharing. Bits can be only cleared.
     1510 *
     1511 * @return Zero on success or a negative error code from errno.h.
     1512 *
     1513 */
     1514int async_share_out_start(int phoneid, void *src, unsigned int flags)
    12341515{
    12351516        return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (sysarg_t) src, 0,
     
    12391520/** Wrapper for receiving the IPC_M_SHARE_OUT calls using the async framework.
    12401521 *
    1241  * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT calls
    1242  * so that the user doesn't have to remember the meaning of each IPC argument.
     1522 * This wrapper only makes it more comfortable to receive IPC_M_SHARE_OUT
     1523 * calls so that the user doesn't have to remember the meaning of each IPC
     1524 * argument.
    12431525 *
    12441526 * So far, this wrapper is to be used from within a connection fibril.
    12451527 *
    1246  * @param callid        Storage where the hash of the IPC_M_SHARE_OUT call will
    1247  *                      be stored.
    1248  * @param size          Storage where the source address space area size will be
    1249  *                      stored.
    1250  * @param flags         Storage where the sharing flags will be stored.
    1251  *
    1252  * @return              Non-zero on success, zero on failure.
    1253  */
    1254 int async_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags)
    1255 {
    1256         ipc_call_t data;
    1257        
     1528 * @param callid Storage for the hash of the IPC_M_SHARE_OUT call.
     1529 * @param size   Storage for the source address space area size.
     1530 * @param flags  Storage for the sharing flags.
     1531 *
     1532 * @return True on success, false on failure.
     1533 *
     1534 */
     1535bool async_share_out_receive(ipc_callid_t *callid, size_t *size, unsigned int *flags)
     1536{
    12581537        assert(callid);
    12591538        assert(size);
    12601539        assert(flags);
    1261 
     1540       
     1541        ipc_call_t data;
    12621542        *callid = async_get_call(&data);
     1543       
    12631544        if (IPC_GET_IMETHOD(data) != IPC_M_SHARE_OUT)
    1264                 return 0;
     1545                return false;
     1546       
    12651547        *size = (size_t) IPC_GET_ARG2(data);
    1266         *flags = (int) IPC_GET_ARG3(data);
    1267         return 1;
     1548        *flags = (unsigned int) IPC_GET_ARG3(data);
     1549        return true;
    12681550}
    12691551
    12701552/** Wrapper for answering the IPC_M_SHARE_OUT calls using the async framework.
    12711553 *
    1272  * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT calls
    1273  * so that the user doesn't have to remember the meaning of each IPC argument.
    1274  *
    1275  * @param callid        Hash of the IPC_M_DATA_WRITE call to answer.
    1276  * @param dst           Destination address space area base address.   
    1277  *
    1278  * @return              Zero on success or a value from @ref errno.h on failure.
     1554 * This wrapper only makes it more comfortable to answer IPC_M_SHARE_OUT
     1555 * calls so that the user doesn't have to remember the meaning of each IPC
     1556 * argument.
     1557 *
     1558 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.
     1559 * @param dst    Destination address space area base address.
     1560 *
     1561 * @return Zero on success or a value from @ref errno.h on failure.
     1562 *
    12791563 */
    12801564int async_share_out_finalize(ipc_callid_t callid, void *dst)
     
    12831567}
    12841568
    1285 
    1286 /** Wrapper for making IPC_M_DATA_READ calls using the async framework.
    1287  *
    1288  * @param phoneid       Phone that will be used to contact the receiving side.
    1289  * @param dst           Address of the beginning of the destination buffer.
    1290  * @param size          Size of the destination buffer.
    1291  *
    1292  * @return              Zero on success or a negative error code from errno.h.
     1569/** Wrapper for IPC_M_DATA_READ calls using the async framework.
     1570 *
     1571 * @param phoneid Phone that will be used to contact the receiving side.
     1572 * @param dst     Address of the beginning of the destination buffer.
     1573 * @param size    Size of the destination buffer.
     1574 *
     1575 * @return Zero on success or a negative error code from errno.h.
     1576 *
    12931577 */
    12941578int async_data_read_start(int phoneid, void *dst, size_t size)
     
    13001584/** Wrapper for receiving the IPC_M_DATA_READ calls using the async framework.
    13011585 *
    1302  * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ calls
    1303  * so that the user doesn't have to remember the meaning of each IPC argument.
     1586 * This wrapper only makes it more comfortable to receive IPC_M_DATA_READ
     1587 * calls so that the user doesn't have to remember the meaning of each IPC
     1588 * argument.
    13041589 *
    13051590 * So far, this wrapper is to be used from within a connection fibril.
    13061591 *
    1307  * @param callid        Storage where the hash of the IPC_M_DATA_READ call will
    1308  *                      be stored.
    1309  * @param size          Storage where the maximum size will be stored. Can be
    1310  *                      NULL.
    1311  *
    1312  * @return              Non-zero on success, zero on failure.
    1313  */
    1314 int async_data_read_receive(ipc_callid_t *callid, size_t *size)
    1315 {
     1592 * @param callid Storage for the hash of the IPC_M_DATA_READ.
     1593 * @param size   Storage for the maximum size. Can be NULL.
     1594 *
     1595 * @return True on success, false on failure.
     1596 *
     1597 */
     1598bool async_data_read_receive(ipc_callid_t *callid, size_t *size)
     1599{
     1600        assert(callid);
     1601       
    13161602        ipc_call_t data;
    1317        
    1318         assert(callid);
    1319 
    13201603        *callid = async_get_call(&data);
     1604       
    13211605        if (IPC_GET_IMETHOD(data) != IPC_M_DATA_READ)
    1322                 return 0;
     1606                return false;
     1607       
    13231608        if (size)
    13241609                *size = (size_t) IPC_GET_ARG2(data);
    1325         return 1;
     1610       
     1611        return true;
    13261612}
    13271613
    13281614/** Wrapper for answering the IPC_M_DATA_READ calls using the async framework.
    13291615 *
    1330  * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ calls
    1331  * so that the user doesn't have to remember the meaning of each IPC argument.
    1332  *
    1333  * @param callid        Hash of the IPC_M_DATA_READ call to answer.
    1334  * @param src           Source address for the IPC_M_DATA_READ call.
    1335  * @param size          Size for the IPC_M_DATA_READ call. Can be smaller than
    1336  *                      the maximum size announced by the sender.
    1337  *
    1338  * @return              Zero on success or a value from @ref errno.h on failure.
     1616 * This wrapper only makes it more comfortable to answer IPC_M_DATA_READ
     1617 * calls so that the user doesn't have to remember the meaning of each IPC
     1618 * argument.
     1619 *
     1620 * @param callid Hash of the IPC_M_DATA_READ call to answer.
     1621 * @param src    Source address for the IPC_M_DATA_READ call.
     1622 * @param size   Size for the IPC_M_DATA_READ call. Can be smaller than
     1623 *               the maximum size announced by the sender.
     1624 *
     1625 * @return Zero on success or a value from @ref errno.h on failure.
     1626 *
    13391627 */
    13401628int async_data_read_finalize(ipc_callid_t callid, const void *src, size_t size)
     
    13441632
    13451633/** Wrapper for forwarding any read request
    1346  *
    13471634 *
    13481635 */
     
    13771664}
    13781665
    1379 /** Wrapper for making IPC_M_DATA_WRITE calls using the async framework.
     1666/** Wrapper for IPC_M_DATA_WRITE calls using the async framework.
    13801667 *
    13811668 * @param phoneid Phone that will be used to contact the receiving side.
     
    13941681/** Wrapper for receiving the IPC_M_DATA_WRITE calls using the async framework.
    13951682 *
    1396  * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE calls
    1397  * so that the user doesn't have to remember the meaning of each IPC argument.
     1683 * This wrapper only makes it more comfortable to receive IPC_M_DATA_WRITE
     1684 * calls so that the user doesn't have to remember the meaning of each IPC
     1685 * argument.
    13981686 *
    13991687 * So far, this wrapper is to be used from within a connection fibril.
    14001688 *
    1401  * @param callid Storage where the hash of the IPC_M_DATA_WRITE call will
    1402  *               be stored.
    1403  * @param size   Storage where the suggested size will be stored. May be
    1404  *               NULL
    1405  *
    1406  * @return Non-zero on success, zero on failure.
    1407  *
    1408  */
    1409 int async_data_write_receive(ipc_callid_t *callid, size_t *size)
    1410 {
     1689 * @param callid Storage for the hash of the IPC_M_DATA_WRITE.
     1690 * @param size   Storage for the suggested size. May be NULL.
     1691 *
     1692 * @return True on success, false on failure.
     1693 *
     1694 */
     1695bool async_data_write_receive(ipc_callid_t *callid, size_t *size)
     1696{
     1697        assert(callid);
     1698       
    14111699        ipc_call_t data;
    1412        
    1413         assert(callid);
    1414        
    14151700        *callid = async_get_call(&data);
     1701       
    14161702        if (IPC_GET_IMETHOD(data) != IPC_M_DATA_WRITE)
    1417                 return 0;
     1703                return false;
    14181704       
    14191705        if (size)
    14201706                *size = (size_t) IPC_GET_ARG2(data);
    14211707       
    1422         return 1;
     1708        return true;
    14231709}
    14241710
    14251711/** Wrapper for answering the IPC_M_DATA_WRITE calls using the async framework.
    14261712 *
    1427  * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE calls
    1428  * so that the user doesn't have to remember the meaning of each IPC argument.
     1713 * This wrapper only makes it more comfortable to answer IPC_M_DATA_WRITE
     1714 * calls so that the user doesn't have to remember the meaning of each IPC
     1715 * argument.
    14291716 *
    14301717 * @param callid Hash of the IPC_M_DATA_WRITE call to answer.
     
    15221809 *
    15231810 */
    1524 void async_data_write_void(const int retval)
     1811void async_data_write_void(sysarg_t retval)
    15251812{
    15261813        ipc_callid_t callid;
     
    15301817
    15311818/** Wrapper for forwarding any data that is about to be received
    1532  *
    15331819 *
    15341820 */
  • uspace/lib/c/generic/async_sess.c

    r87e373b rc4fb95d3  
    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

    r87e373b rc4fb95d3  
    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

    r87e373b rc4fb95d3  
    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

    r87e373b rc4fb95d3  
    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         sysarg_t callback_phonehash;
    119         ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash);
     117        async_connect_to_me(phone, 0, 0, 0, NULL);
    120118        async_wait_for(req, &retval);
    121119       
     
    125123}
    126124
    127 static int devman_send_match_id(int phone, match_id_t *match_id) \
    128 {
    129         ipc_call_t answer;
    130         aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score, &answer);
    131         int retval = async_data_write_start(phone, match_id->id, str_size(match_id->id));
     125static int devman_send_match_id(int phone, match_id_t *match_id)
     126{
     127        ipc_call_t answer;
     128
     129        aid_t req = async_send_1(phone, DEVMAN_ADD_MATCH_ID, match_id->score,
     130            &answer);
     131        int retval = async_data_write_start(phone, match_id->id,
     132            str_size(match_id->id));
     133
    132134        async_wait_for(req, NULL);
    133135        return retval;
     
    135137
    136138
    137 static int devman_send_match_ids(int phone, match_id_list_t *match_ids) 
     139static int devman_send_match_ids(int phone, match_id_list_t *match_ids)
    138140{
    139141        link_t *link = match_ids->ids.next;
    140142        match_id_t *match_id = NULL;
    141143        int ret = EOK;
    142        
     144
    143145        while (link != &match_ids->ids) {
    144146                match_id = list_get_instance(link, match_id_t, link);
    145                 if (EOK != (ret = devman_send_match_id(phone, match_id)))
    146                 {
    147                         printf("Driver failed to send match id, error number = %d\n", ret);
    148                         return ret;                     
    149                 }
     147                ret = devman_send_match_id(phone, match_id);
     148                if (ret != EOK) {
     149                        printf("Driver failed to send match id, error %d\n",
     150                            ret);
     151                        return ret;
     152                }
     153
    150154                link = link->next;
    151155        }
    152         return ret;     
    153 }
    154 
    155 int devman_child_device_register(
    156         const char *name, match_id_list_t *match_ids, devman_handle_t parent_handle, devman_handle_t *handle)
    157 {               
     156
     157        return ret;
     158}
     159
     160/** Add function to a device.
     161 *
     162 * Request devman to add a new function to the specified device owned by
     163 * this driver task.
     164 *
     165 * @param name          Name of the new function
     166 * @param ftype         Function type, fun_inner or fun_exposed
     167 * @param match_ids     Match IDs (should be empty for fun_exposed)
     168 * @param devh          Devman handle of the device
     169 * @param funh          Place to store handle of the new function
     170 *
     171 * @return              EOK on success or negative error code.
     172 */
     173int devman_add_function(const char *name, fun_type_t ftype,
     174    match_id_list_t *match_ids, devman_handle_t devh, devman_handle_t *funh)
     175{
    158176        int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
     177        int fun_handle;
    159178       
    160179        if (phone < 0)
     
    163182        async_serialize_start();
    164183       
    165         int match_count = list_count(&match_ids->ids); 
    166         ipc_call_t answer;
    167         aid_t req = async_send_2(phone, DEVMAN_ADD_CHILD_DEVICE, parent_handle, match_count, &answer);
     184        int match_count = list_count(&match_ids->ids);
     185        ipc_call_t answer;
     186
     187        aid_t req = async_send_3(phone, DEVMAN_ADD_FUNCTION, (sysarg_t) ftype,
     188            devh, match_count, &answer);
    168189
    169190        sysarg_t retval = async_data_write_start(phone, name, str_size(name));
     
    180201        async_serialize_end();
    181202       
    182         if (retval != EOK) {
    183                 if (handle != NULL) {
    184                         *handle = -1;
    185                 }
    186                 return retval;
    187         }       
    188        
    189         if (handle != NULL)
    190                 *handle = (int) IPC_GET_ARG1(answer);   
    191                
    192         return retval;
    193 }
    194 
    195 int devman_add_device_to_class(devman_handle_t devman_handle, const char *class_name)
     203        if (retval == EOK)
     204                fun_handle = (int) IPC_GET_ARG1(answer);
     205        else
     206                fun_handle = -1;
     207       
     208        *funh = fun_handle;
     209
     210        return retval;
     211}
     212
     213int devman_add_device_to_class(devman_handle_t devman_handle,
     214    const char *class_name)
    196215{
    197216        int phone = devman_get_phone(DEVMAN_DRIVER, IPC_FLAG_BLOCKING);
     
    202221        async_serialize_start();
    203222        ipc_call_t answer;
    204         aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS, devman_handle, &answer);
    205        
    206         sysarg_t retval = async_data_write_start(phone, class_name, str_size(class_name));
     223        aid_t req = async_send_1(phone, DEVMAN_ADD_DEVICE_TO_CLASS,
     224            devman_handle, &answer);
     225       
     226        sysarg_t retval = async_data_write_start(phone, class_name,
     227            str_size(class_name));
    207228        if (retval != EOK) {
    208229                async_wait_for(req, NULL);
     
    214235        async_serialize_end();
    215236       
    216         return retval; 
     237        return retval;
    217238}
    218239
     
    222243        case DEVMAN_DRIVER:
    223244                if (devman_phone_driver >= 0) {
    224                         ipc_hangup(devman_phone_driver);
     245                        async_hangup(devman_phone_driver);
    225246                        devman_phone_driver = -1;
    226247                }
     
    228249        case DEVMAN_CLIENT:
    229250                if (devman_phone_client >= 0) {
    230                         ipc_hangup(devman_phone_client);
     251                        async_hangup(devman_phone_client);
    231252                        devman_phone_client = -1;
    232253                }
     
    267288}
    268289
    269 int devman_device_get_handle(const char *pathname, devman_handle_t *handle, unsigned int flags)
     290int devman_device_get_handle(const char *pathname, devman_handle_t *handle,
     291    unsigned int flags)
    270292{
    271293        int phone = devman_get_phone(DEVMAN_CLIENT, flags);
     
    280302            &answer);
    281303       
    282         sysarg_t retval = async_data_write_start(phone, pathname, str_size(pathname));
     304        sysarg_t retval = async_data_write_start(phone, pathname,
     305            str_size(pathname));
    283306        if (retval != EOK) {
    284307                async_wait_for(req, NULL);
  • uspace/lib/c/generic/devmap.c

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

    r87e373b rc4fb95d3  
    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

    r87e373b rc4fb95d3  
    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

    r87e373b rc4fb95d3  
    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

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

    r87e373b rc4fb95d3  
    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

    r87e373b rc4fb95d3  
    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

    r87e373b rc4fb95d3  
    4545#include <futex.h>
    4646#include <adt/gcdlcm.h>
    47 
    48 /* Magic used in heap headers. */
    49 #define HEAP_BLOCK_HEAD_MAGIC  0xBEEF0101
    50 
    51 /* Magic used in heap footers. */
    52 #define HEAP_BLOCK_FOOT_MAGIC  0xBEEF0202
    53 
    54 /** Allocation alignment (this also covers the alignment of fields
    55     in the heap header and footer) */
     47#include "private/malloc.h"
     48
     49/** Magic used in heap headers. */
     50#define HEAP_BLOCK_HEAD_MAGIC  UINT32_C(0xBEEF0101)
     51
     52/** Magic used in heap footers. */
     53#define HEAP_BLOCK_FOOT_MAGIC  UINT32_C(0xBEEF0202)
     54
     55/** Magic used in heap descriptor. */
     56#define HEAP_AREA_MAGIC  UINT32_C(0xBEEFCAFE)
     57
     58/** Allocation alignment.
     59 *
     60 * This also covers the alignment of fields
     61 * in the heap header and footer.
     62 *
     63 */
    5664#define BASE_ALIGN  16
    5765
    58 /**
    59  * Either 4 * 256M on 32-bit architecures or 16 * 256M on 64-bit architectures
    60  */
    61 #define MAX_HEAP_SIZE  (sizeof(uintptr_t) << 28)
    62 
    63 /**
    64  *
    65  */
    66 #define STRUCT_OVERHEAD  (sizeof(heap_block_head_t) + sizeof(heap_block_foot_t))
    67 
    68 /**
    69  * Calculate real size of a heap block (with header and footer)
     66/** Overhead of each heap block. */
     67#define STRUCT_OVERHEAD \
     68        (sizeof(heap_block_head_t) + sizeof(heap_block_foot_t))
     69
     70/** Calculate real size of a heap block.
     71 *
     72 * Add header and footer size.
     73 *
    7074 */
    7175#define GROSS_SIZE(size)  ((size) + STRUCT_OVERHEAD)
    7276
    73 /**
    74  * Calculate net size of a heap block (without header and footer)
     77/** Calculate net size of a heap block.
     78 *
     79 * Subtract header and footer size.
     80 *
    7581 */
    7682#define NET_SIZE(size)  ((size) - STRUCT_OVERHEAD)
     83
     84/** Get first block in heap area.
     85 *
     86 */
     87#define AREA_FIRST_BLOCK(area) \
     88        (ALIGN_UP(((uintptr_t) (area)) + sizeof(heap_area_t), BASE_ALIGN))
     89
     90/** Get footer in heap block.
     91 *
     92 */
     93#define BLOCK_FOOT(head) \
     94        ((heap_block_foot_t *) \
     95            (((uintptr_t) head) + head->size - sizeof(heap_block_foot_t)))
     96
     97/** Heap area.
     98 *
     99 * The memory managed by the heap allocator is divided into
     100 * multiple discontinuous heaps. Each heap is represented
     101 * by a separate address space area which has this structure
     102 * at its very beginning.
     103 *
     104 */
     105typedef struct heap_area {
     106        /** Start of the heap area (including this structure)
     107         *
     108         * Aligned on page boundary.
     109         *
     110         */
     111        void *start;
     112       
     113        /** End of the heap area (aligned on page boundary) */
     114        void *end;
     115       
     116        /** Next heap area */
     117        struct heap_area *next;
     118       
     119        /** A magic value */
     120        uint32_t magic;
     121} heap_area_t;
    77122
    78123/** Header of a heap block
     
    86131        bool free;
    87132       
     133        /** Heap area this block belongs to */
     134        heap_area_t *area;
     135       
    88136        /* A magic value to detect overwrite of heap header */
    89137        uint32_t magic;
     
    101149} heap_block_foot_t;
    102150
    103 /** Linker heap symbol */
    104 extern char _heap;
     151/** First heap area */
     152static heap_area_t *first_heap_area = NULL;
     153
     154/** Last heap area */
     155static heap_area_t *last_heap_area = NULL;
     156
     157/** Next heap block to examine (next fit algorithm) */
     158static heap_block_head_t *next = NULL;
    105159
    106160/** Futex for thread-safe heap manipulation */
    107161static futex_t malloc_futex = FUTEX_INITIALIZER;
    108162
    109 /** Address of heap start */
    110 static void *heap_start = 0;
    111 
    112 /** Address of heap end */
    113 static void *heap_end = 0;
    114 
    115 /** Maximum heap size */
    116 static size_t max_heap_size = (size_t) -1;
    117 
    118 /** Current number of pages of heap area */
    119 static size_t heap_pages = 0;
    120 
    121163/** Initialize a heap block
    122164 *
    123  * Fills in the structures related to a heap block.
     165 * Fill in the structures related to a heap block.
    124166 * Should be called only inside the critical section.
    125167 *
     
    127169 * @param size Size of the block including the header and the footer.
    128170 * @param free Indication of a free block.
    129  *
    130  */
    131 static void block_init(void *addr, size_t size, bool free)
     171 * @param area Heap area the block belongs to.
     172 *
     173 */
     174static void block_init(void *addr, size_t size, bool free, heap_area_t *area)
    132175{
    133176        /* Calculate the position of the header and the footer */
    134177        heap_block_head_t *head = (heap_block_head_t *) addr;
    135         heap_block_foot_t *foot =
    136             (heap_block_foot_t *) (addr + size - sizeof(heap_block_foot_t));
    137178       
    138179        head->size = size;
    139180        head->free = free;
     181        head->area = area;
    140182        head->magic = HEAP_BLOCK_HEAD_MAGIC;
     183       
     184        heap_block_foot_t *foot = BLOCK_FOOT(head);
    141185       
    142186        foot->size = size;
     
    159203        assert(head->magic == HEAP_BLOCK_HEAD_MAGIC);
    160204       
    161         heap_block_foot_t *foot =
    162             (heap_block_foot_t *) (addr + head->size - sizeof(heap_block_foot_t));
     205        heap_block_foot_t *foot = BLOCK_FOOT(head);
    163206       
    164207        assert(foot->magic == HEAP_BLOCK_FOOT_MAGIC);
     
    166209}
    167210
    168 /** Increase the heap area size
    169  *
    170  * Should be called only inside the critical section.
    171  *
    172  * @param size Number of bytes to grow the heap by.
    173  *
    174  */
    175 static bool grow_heap(size_t size)
     211/** Check a heap area structure
     212 *
     213 * @param addr Address of the heap area.
     214 *
     215 */
     216static void area_check(void *addr)
     217{
     218        heap_area_t *area = (heap_area_t *) addr;
     219       
     220        assert(area->magic == HEAP_AREA_MAGIC);
     221        assert(area->start < area->end);
     222        assert(((uintptr_t) area->start % PAGE_SIZE) == 0);
     223        assert(((uintptr_t) area->end % PAGE_SIZE) == 0);
     224}
     225
     226/** Create new heap area
     227 *
     228 * @param start Preffered starting address of the new area.
     229 * @param size  Size of the area.
     230 *
     231 */
     232static bool area_create(size_t size)
     233{
     234        void *start = as_get_mappable_page(size);
     235        if (start == NULL)
     236                return false;
     237       
     238        /* Align the heap area on page boundary */
     239        void *astart = (void *) ALIGN_UP((uintptr_t) start, PAGE_SIZE);
     240        size_t asize = ALIGN_UP(size, PAGE_SIZE);
     241       
     242        astart = as_area_create(astart, asize, AS_AREA_WRITE | AS_AREA_READ);
     243        if (astart == (void *) -1)
     244                return false;
     245       
     246        heap_area_t *area = (heap_area_t *) astart;
     247       
     248        area->start = astart;
     249        area->end = (void *)
     250            ALIGN_DOWN((uintptr_t) astart + asize, BASE_ALIGN);
     251        area->next = NULL;
     252        area->magic = HEAP_AREA_MAGIC;
     253       
     254        void *block = (void *) AREA_FIRST_BLOCK(area);
     255        size_t bsize = (size_t) (area->end - block);
     256       
     257        block_init(block, bsize, true, area);
     258       
     259        if (last_heap_area == NULL) {
     260                first_heap_area = area;
     261                last_heap_area = area;
     262        } else {
     263                last_heap_area->next = area;
     264                last_heap_area = area;
     265        }
     266       
     267        return true;
     268}
     269
     270/** Try to enlarge a heap area
     271 *
     272 * @param area Heap area to grow.
     273 * @param size Gross size of item to allocate (bytes).
     274 *
     275 */
     276static bool area_grow(heap_area_t *area, size_t size)
    176277{
    177278        if (size == 0)
     279                return true;
     280       
     281        area_check(area);
     282       
     283        size_t asize = ALIGN_UP((size_t) (area->end - area->start) + size,
     284            PAGE_SIZE);
     285       
     286        /* New heap area size */
     287        void *end = (void *)
     288            ALIGN_DOWN((uintptr_t) area->start + asize, BASE_ALIGN);
     289       
     290        /* Check for overflow */
     291        if (end < area->start)
    178292                return false;
    179 
    180         if ((heap_start + size < heap_start) || (heap_end + size < heap_end))
     293       
     294        /* Resize the address space area */
     295        int ret = as_area_resize(area->start, asize, 0);
     296        if (ret != EOK)
    181297                return false;
    182298       
    183         size_t heap_size = (size_t) (heap_end - heap_start);
    184        
    185         if ((max_heap_size != (size_t) -1) && (heap_size + size > max_heap_size))
    186                 return false;
    187        
    188         size_t pages = (size - 1) / PAGE_SIZE + 1;
    189        
    190         if (as_area_resize((void *) &_heap, (heap_pages + pages) * PAGE_SIZE, 0)
    191             == EOK) {
    192                 void *end = (void *) ALIGN_DOWN(((uintptr_t) &_heap) +
    193                     (heap_pages + pages) * PAGE_SIZE, BASE_ALIGN);
    194                 block_init(heap_end, end - heap_end, true);
    195                 heap_pages += pages;
    196                 heap_end = end;
     299        /* Add new free block */
     300        block_init(area->end, (size_t) (end - area->end), true, area);
     301       
     302        /* Update heap area parameters */
     303        area->end = end;
     304       
     305        return true;
     306}
     307
     308/** Try to enlarge any of the heap areas
     309 *
     310 * @param size Gross size of item to allocate (bytes).
     311 *
     312 */
     313static bool heap_grow(size_t size)
     314{
     315        if (size == 0)
    197316                return true;
    198         }
    199        
    200         return false;
    201 }
    202 
    203 /** Decrease the heap area
    204  *
    205  * Should be called only inside the critical section.
    206  *
    207  * @param size Number of bytes to shrink the heap by.
    208  *
    209  */
    210 static void shrink_heap(void)
    211 {
    212         // TODO
     317       
     318        /* First try to enlarge some existing area */
     319        heap_area_t *area;
     320        for (area = first_heap_area; area != NULL; area = area->next) {
     321                if (area_grow(area, size))
     322                        return true;
     323        }
     324       
     325        /* Eventually try to create a new area */
     326        return area_create(AREA_FIRST_BLOCK(size));
     327}
     328
     329/** Try to shrink heap space
     330 *
     331 * In all cases the next pointer is reset.
     332 *
     333 */
     334static void heap_shrink(void)
     335{
     336        next = NULL;
    213337}
    214338
    215339/** Initialize the heap allocator
    216340 *
    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);
    238 }
    239 
    240 /** Get maximum heap address
    241  *
    242  */
    243 uintptr_t get_max_heap_addr(void)
    244 {
    245         futex_down(&malloc_futex);
    246        
    247         if (max_heap_size == (size_t) -1)
    248                 max_heap_size =
    249                     max((size_t) (heap_end - heap_start), MAX_HEAP_SIZE);
    250        
    251         uintptr_t max_heap_addr = (uintptr_t) heap_start + max_heap_size;
    252        
    253         futex_up(&malloc_futex);
    254        
    255         return max_heap_addr;
     341 * Create initial heap memory area. This routine is
     342 * only called from libc initialization, thus we do not
     343 * take any locks.
     344 *
     345 */
     346void __malloc_init(void)
     347{
     348        if (!area_create(PAGE_SIZE))
     349                abort();
    256350}
    257351
     
    275369                /* Block big enough -> split. */
    276370                void *next = ((void *) cur) + size;
    277                 block_init(next, cur->size - size, true);
    278                 block_init(cur, size, false);
     371                block_init(next, cur->size - size, true, cur->area);
     372                block_init(cur, size, false, cur->area);
    279373        } else {
    280374                /* Block too small -> use as is. */
     
    283377}
    284378
    285 /** Allocate a memory block
     379/** Allocate memory from heap area starting from given block
    286380 *
    287381 * Should be called only inside the critical section.
    288  *
    289  * @param size  The size of the block to allocate.
    290  * @param align Memory address alignment.
    291  *
    292  * @return the address of the block or NULL when not enough memory.
    293  *
    294  */
    295 static void *malloc_internal(const size_t size, const size_t align)
    296 {
    297         if (align == 0)
    298                 return NULL;
    299        
    300         size_t falign = lcm(align, BASE_ALIGN);
    301         size_t real_size = GROSS_SIZE(ALIGN_UP(size, falign));
    302        
    303         bool grown = false;
    304         void *result;
    305        
    306 loop:
    307         result = NULL;
    308         heap_block_head_t *cur = (heap_block_head_t *) heap_start;
    309        
    310         while ((result == NULL) && ((void *) cur < heap_end)) {
     382 * As a side effect this function also sets the current
     383 * pointer on successful allocation.
     384 *
     385 * @param area        Heap area where to allocate from.
     386 * @param first_block Starting heap block.
     387 * @param final_block Heap block where to finish the search
     388 *                    (may be NULL).
     389 * @param real_size   Gross number of bytes to allocate.
     390 * @param falign      Physical alignment of the block.
     391 *
     392 * @return Address of the allocated block or NULL on not enough memory.
     393 *
     394 */
     395static void *malloc_area(heap_area_t *area, heap_block_head_t *first_block,
     396    heap_block_head_t *final_block, size_t real_size, size_t falign)
     397{
     398        area_check((void *) area);
     399        assert((void *) first_block >= (void *) AREA_FIRST_BLOCK(area));
     400        assert((void *) first_block < area->end);
     401       
     402        heap_block_head_t *cur;
     403        for (cur = first_block; (void *) cur < area->end;
     404            cur = (heap_block_head_t *) (((void *) cur) + cur->size)) {
    311405                block_check(cur);
     406               
     407                /* Finish searching on the final block */
     408                if ((final_block != NULL) && (cur == final_block))
     409                        break;
    312410               
    313411                /* Try to find a block that is free and large enough. */
    314412                if ((cur->free) && (cur->size >= real_size)) {
    315                         /* We have found a suitable block.
    316                            Check for alignment properties. */
    317                         void *addr = ((void *) cur) + sizeof(heap_block_head_t);
    318                         void *aligned = (void *) ALIGN_UP(addr, falign);
     413                        /*
     414                         * We have found a suitable block.
     415                         * Check for alignment properties.
     416                         */
     417                        void *addr = (void *)
     418                            ((uintptr_t) cur + sizeof(heap_block_head_t));
     419                        void *aligned = (void *)
     420                            ALIGN_UP((uintptr_t) addr, falign);
    319421                       
    320422                        if (addr == aligned) {
    321423                                /* Exact block start including alignment. */
    322424                                split_mark(cur, real_size);
    323                                 result = addr;
     425                               
     426                                next = cur;
     427                                return addr;
    324428                        } else {
    325429                                /* Block start has to be aligned */
     
    327431                               
    328432                                if (cur->size >= real_size + excess) {
    329                                         /* The current block is large enough to fit
    330                                            data in including alignment */
    331                                         if ((void *) cur > heap_start) {
    332                                                 /* There is a block before the current block.
    333                                                    This previous block can be enlarged to compensate
    334                                                    for the alignment excess */
    335                                                 heap_block_foot_t *prev_foot =
    336                                                     ((void *) cur) - sizeof(heap_block_foot_t);
     433                                        /*
     434                                         * The current block is large enough to fit
     435                                         * data in (including alignment).
     436                                         */
     437                                        if ((void *) cur > (void *) AREA_FIRST_BLOCK(area)) {
     438                                                /*
     439                                                 * There is a block before the current block.
     440                                                 * This previous block can be enlarged to
     441                                                 * compensate for the alignment excess.
     442                                                 */
     443                                                heap_block_foot_t *prev_foot = (heap_block_foot_t *)
     444                                                    ((void *) cur - sizeof(heap_block_foot_t));
    337445                                               
    338                                                 heap_block_head_t *prev_head =
    339                                                     (heap_block_head_t *) (((void *) cur) - prev_foot->size);
     446                                                heap_block_head_t *prev_head = (heap_block_head_t *)
     447                                                    ((void *) cur - prev_foot->size);
    340448                                               
    341449                                                block_check(prev_head);
     
    344452                                                heap_block_head_t *next_head = ((void *) cur) + excess;
    345453                                               
    346                                                 if ((!prev_head->free) && (excess >= STRUCT_OVERHEAD)) {
    347                                                         /* The previous block is not free and there is enough
    348                                                            space to fill in a new free block between the previous
    349                                                            and current block */
    350                                                         block_init(cur, excess, true);
     454                                                if ((!prev_head->free) &&
     455                                                    (excess >= STRUCT_OVERHEAD)) {
     456                                                        /*
     457                                                         * The previous block is not free and there
     458                                                         * is enough free space left to fill in
     459                                                         * a new free block between the previous
     460                                                         * and current block.
     461                                                         */
     462                                                        block_init(cur, excess, true, area);
    351463                                                } else {
    352                                                         /* The previous block is free (thus there is no need to
    353                                                            induce additional fragmentation to the heap) or the
    354                                                            excess is small, thus just enlarge the previous block */
    355                                                         block_init(prev_head, prev_head->size + excess, prev_head->free);
     464                                                        /*
     465                                                         * The previous block is free (thus there
     466                                                         * is no need to induce additional
     467                                                         * fragmentation to the heap) or the
     468                                                         * excess is small. Therefore just enlarge
     469                                                         * the previous block.
     470                                                         */
     471                                                        block_init(prev_head, prev_head->size + excess,
     472                                                            prev_head->free, area);
    356473                                                }
    357474                                               
    358                                                 block_init(next_head, reduced_size, true);
     475                                                block_init(next_head, reduced_size, true, area);
    359476                                                split_mark(next_head, real_size);
    360                                                 result = aligned;
    361                                                 cur = next_head;
     477                                               
     478                                                next = next_head;
     479                                                return aligned;
    362480                                        } else {
    363                                                 /* The current block is the first block on the heap.
    364                                                    We have to make sure that the alignment excess
    365                                                    is large enough to fit a new free block just
    366                                                    before the current block */
     481                                                /*
     482                                                 * The current block is the first block
     483                                                 * in the heap area. We have to make sure
     484                                                 * that the alignment excess is large enough
     485                                                 * to fit a new free block just before the
     486                                                 * current block.
     487                                                 */
    367488                                                while (excess < STRUCT_OVERHEAD) {
    368489                                                        aligned += falign;
     
    373494                                                if (cur->size >= real_size + excess) {
    374495                                                        size_t reduced_size = cur->size - excess;
    375                                                         cur = (heap_block_head_t *) (heap_start + excess);
     496                                                        cur = (heap_block_head_t *)
     497                                                            (AREA_FIRST_BLOCK(area) + excess);
    376498                                                       
    377                                                         block_init(heap_start, excess, true);
    378                                                         block_init(cur, reduced_size, true);
     499                                                        block_init((void *) AREA_FIRST_BLOCK(area), excess,
     500                                                            true, area);
     501                                                        block_init(cur, reduced_size, true, area);
    379502                                                        split_mark(cur, real_size);
    380                                                         result = aligned;
     503                                                       
     504                                                        next = cur;
     505                                                        return aligned;
    381506                                                }
    382507                                        }
     
    384509                        }
    385510                }
    386                
    387                 /* Advance to the next block. */
    388                 cur = (heap_block_head_t *) (((void *) cur) + cur->size);
    389         }
    390        
    391         if ((result == NULL) && (!grown)) {
    392                 if (grow_heap(real_size)) {
    393                         grown = true;
     511        }
     512       
     513        return NULL;
     514}
     515
     516/** Allocate a memory block
     517 *
     518 * Should be called only inside the critical section.
     519 *
     520 * @param size  The size of the block to allocate.
     521 * @param align Memory address alignment.
     522 *
     523 * @return Address of the allocated block or NULL on not enough memory.
     524 *
     525 */
     526static void *malloc_internal(const size_t size, const size_t align)
     527{
     528        assert(first_heap_area != NULL);
     529       
     530        if (align == 0)
     531                return NULL;
     532       
     533        size_t falign = lcm(align, BASE_ALIGN);
     534        size_t real_size = GROSS_SIZE(ALIGN_UP(size, falign));
     535       
     536        bool retry = false;
     537        heap_block_head_t *split;
     538       
     539loop:
     540       
     541        /* Try the next fit approach */
     542        split = next;
     543       
     544        if (split != NULL) {
     545                void *addr = malloc_area(split->area, split, NULL, real_size,
     546                    falign);
     547               
     548                if (addr != NULL)
     549                        return addr;
     550        }
     551       
     552        /* Search the entire heap */
     553        heap_area_t *area;
     554        for (area = first_heap_area; area != NULL; area = area->next) {
     555                heap_block_head_t *first = (heap_block_head_t *)
     556                    AREA_FIRST_BLOCK(area);
     557               
     558                void *addr = malloc_area(area, first, split, real_size,
     559                    falign);
     560               
     561                if (addr != NULL)
     562                        return addr;
     563        }
     564       
     565        if (!retry) {
     566                /* Try to grow the heap space */
     567                if (heap_grow(real_size)) {
     568                        retry = true;
    394569                        goto loop;
    395570                }
    396571        }
    397572       
    398         return result;
     573        return NULL;
    399574}
    400575
     
    475650            (heap_block_head_t *) (addr - sizeof(heap_block_head_t));
    476651       
    477         assert((void *) head >= heap_start);
    478         assert((void *) head < heap_end);
    479        
    480652        block_check(head);
    481653        assert(!head->free);
     654       
     655        heap_area_t *area = head->area;
     656       
     657        area_check(area);
     658        assert((void *) head >= (void *) AREA_FIRST_BLOCK(area));
     659        assert((void *) head < area->end);
    482660       
    483661        void *ptr = NULL;
     
    489667                /* Shrink */
    490668                if (orig_size - real_size >= STRUCT_OVERHEAD) {
    491                         /* Split the original block to a full block
    492                            and a trailing free block */
    493                         block_init((void *) head, real_size, false);
     669                        /*
     670                         * Split the original block to a full block
     671                         * and a trailing free block.
     672                         */
     673                        block_init((void *) head, real_size, false, area);
    494674                        block_init((void *) head + real_size,
    495                             orig_size - real_size, true);
    496                         shrink_heap();
     675                            orig_size - real_size, true, area);
     676                        heap_shrink();
    497677                }
    498678               
    499679                ptr = ((void *) head) + sizeof(heap_block_head_t);
    500680        } else {
    501                 /* Look at the next block. If it is free and the size is
    502                    sufficient then merge the two. Otherwise just allocate
    503                    a new block, copy the original data into it and
    504                    free the original block. */
     681                /*
     682                 * Look at the next block. If it is free and the size is
     683                 * sufficient then merge the two. Otherwise just allocate
     684                 * a new block, copy the original data into it and
     685                 * free the original block.
     686                 */
    505687                heap_block_head_t *next_head =
    506688                    (heap_block_head_t *) (((void *) head) + head->size);
    507689               
    508                 if (((void *) next_head < heap_end) &&
     690                if (((void *) next_head < area->end) &&
    509691                    (head->size + next_head->size >= real_size) &&
    510692                    (next_head->free)) {
    511693                        block_check(next_head);
    512                         block_init(head, head->size + next_head->size, false);
     694                        block_init(head, head->size + next_head->size, false, area);
    513695                        split_mark(head, real_size);
    514696                       
    515697                        ptr = ((void *) head) + sizeof(heap_block_head_t);
     698                        next = NULL;
    516699                } else
    517700                        reloc = true;
     
    544727            = (heap_block_head_t *) (addr - sizeof(heap_block_head_t));
    545728       
    546         assert((void *) head >= heap_start);
    547         assert((void *) head < heap_end);
    548        
    549729        block_check(head);
    550730        assert(!head->free);
     731       
     732        heap_area_t *area = head->area;
     733       
     734        area_check(area);
     735        assert((void *) head >= (void *) AREA_FIRST_BLOCK(area));
     736        assert((void *) head < area->end);
    551737       
    552738        /* Mark the block itself as free. */
     
    557743            = (heap_block_head_t *) (((void *) head) + head->size);
    558744       
    559         if ((void *) next_head < heap_end) {
     745        if ((void *) next_head < area->end) {
    560746                block_check(next_head);
    561747                if (next_head->free)
    562                         block_init(head, head->size + next_head->size, true);
     748                        block_init(head, head->size + next_head->size, true, area);
    563749        }
    564750       
    565751        /* Look at the previous block. If it is free, merge the two. */
    566         if ((void *) head > heap_start) {
     752        if ((void *) head > (void *) AREA_FIRST_BLOCK(area)) {
    567753                heap_block_foot_t *prev_foot =
    568754                    (heap_block_foot_t *) (((void *) head) - sizeof(heap_block_foot_t));
     
    574760               
    575761                if (prev_head->free)
    576                         block_init(prev_head, prev_head->size + head->size, true);
    577         }
    578        
    579         shrink_heap();
     762                        block_init(prev_head, prev_head->size + head->size, true,
     763                            area);
     764        }
     765       
     766        heap_shrink();
    580767       
    581768        futex_up(&malloc_futex);
  • uspace/lib/c/generic/net/icmp_api.c

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

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

    r87e373b rc4fb95d3  
    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 phonehash;
    146                
    147                 rc = ipc_connect_to_me(phone, arg1, arg2, arg3, &phonehash);
     140                int rc = async_connect_to_me(phone, arg1, arg2, arg3, client_receiver);
    148141                if (rc != EOK) {
    149                         ipc_hangup(phone);
     142                        async_hangup(phone);
    150143                        return rc;
    151144                }
    152                 async_new_connection(phonehash, 0, NULL, client_receiver);
    153145        }
    154146       
  • uspace/lib/c/generic/net/socket_client.c

    r87e373b rc4fb95d3  
    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

    r87e373b rc4fb95d3  
    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

    r87e373b rc4fb95d3  
    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

    r87e373b rc4fb95d3  
    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

    r87e373b rc4fb95d3  
    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

    r87e373b rc4fb95d3  
    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

    r87e373b rc4fb95d3  
    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

    r87e373b rc4fb95d3  
    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

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

    r87e373b rc4fb95d3  
    4141typedef unsigned long hash_count_t;
    4242typedef unsigned long hash_index_t;
    43 typedef struct hash_table hash_table_t;
    44 typedef struct hash_table_operations hash_table_operations_t;
     43
     44/** Set of operations for hash table. */
     45typedef struct {
     46        /** Hash function.
     47         *
     48         * @param key Array of keys needed to compute hash index.
     49         *            All keys must be passed.
     50         *
     51         * @return Index into hash table.
     52         *
     53         */
     54        hash_index_t (*hash)(unsigned long key[]);
     55       
     56        /** Hash table item comparison function.
     57         *
     58         * @param key Array of keys that will be compared with item. It is
     59         *            not necessary to pass all keys.
     60         *
     61         * @return True if the keys match, false otherwise.
     62         *
     63         */
     64        int (*compare)(unsigned long key[], hash_count_t keys, link_t *item);
     65       
     66        /** Hash table item removal callback.
     67         *
     68         * @param item Item that was removed from the hash table.
     69         *
     70         */
     71        void (*remove_callback)(link_t *item);
     72} hash_table_operations_t;
    4573
    4674/** Hash table structure. */
    47 struct hash_table {
     75typedef struct {
    4876        link_t *entry;
    4977        hash_count_t entries;
    5078        hash_count_t max_keys;
    5179        hash_table_operations_t *op;
    52 };
    53 
    54 /** Set of operations for hash table. */
    55 struct hash_table_operations {
    56         /** Hash function.
    57          *
    58          * @param key   Array of keys needed to compute hash index. All keys
    59          *              must be passed.
    60          *
    61          * @return      Index into hash table.
    62          */
    63         hash_index_t (* hash)(unsigned long key[]);
    64        
    65         /** Hash table item comparison function.
    66          *
    67          * @param key   Array of keys that will be compared with item. It is
    68          *              not necessary to pass all keys.
    69          *
    70          * @return      true if the keys match, false otherwise.
    71          */
    72         int (*compare)(unsigned long key[], hash_count_t keys, link_t *item);
    73 
    74         /** Hash table item removal callback.
    75          *
    76          * @param item  Item that was removed from the hash table.
    77          */
    78         void (*remove_callback)(link_t *item);
    79 };
     80} hash_table_t;
    8081
    8182#define hash_table_get_instance(item, type, member) \
  • uspace/lib/c/include/as.h

    r87e373b rc4fb95d3  
    4141#include <libarch/config.h>
    4242
     43static inline size_t SIZE2PAGES(size_t size)
     44{
     45        if (size == 0)
     46                return 0;
     47       
     48        return (size_t) ((size - 1) >> PAGE_WIDTH) + 1;
     49}
     50
     51static inline size_t PAGES2SIZE(size_t pages)
     52{
     53        return (size_t) (pages << PAGE_WIDTH);
     54}
     55
    4356extern void *as_area_create(void *address, size_t size, int flags);
    4457extern int as_area_resize(void *address, size_t size, int flags);
  • uspace/lib/c/include/async.h

    r87e373b rc4fb95d3  
    3333 */
    3434
     35#if ((defined(LIBC_IPC_H_)) && (!defined(LIBC_ASYNC_C_)))
     36        #error Do not intermix low-level IPC interface and async framework
     37#endif
     38
    3539#ifndef LIBC_ASYNC_H_
    3640#define LIBC_ASYNC_H_
    3741
    38 #include <ipc/ipc.h>
     42#include <ipc/common.h>
    3943#include <async_sess.h>
    4044#include <fibril.h>
     
    4246#include <atomic.h>
    4347#include <bool.h>
     48#include <task.h>
    4449
    4550typedef ipc_callid_t aid_t;
    46 typedef void (*async_client_conn_t)(ipc_callid_t callid, ipc_call_t *call);
    47 
    48 extern atomic_t async_futex;
     51
     52typedef void *(*async_client_data_ctor_t)(void);
     53typedef void (*async_client_data_dtor_t)(void *);
     54
     55typedef void (*async_client_conn_t)(ipc_callid_t, ipc_call_t *);
    4956
    5057extern atomic_t threads_in_ipc_wait;
    5158
    52 extern int __async_init(void);
    53 extern ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs);
    54 
    55 static inline ipc_callid_t async_get_call(ipc_call_t *data)
    56 {
    57         return async_get_call_timeout(data, 0);
    58 }
    59 
    60 static inline void async_manager(void)
    61 {
    62         fibril_switch(FIBRIL_TO_MANAGER);
    63 }
     59#define async_manager() \
     60        fibril_switch(FIBRIL_TO_MANAGER)
     61
     62#define async_get_call(data) \
     63        async_get_call_timeout(data, 0)
     64
     65extern ipc_callid_t async_get_call_timeout(ipc_call_t *, suseconds_t);
    6466
    6567/*
     
    8587            (arg5), (dataptr))
    8688
    87 extern aid_t async_send_fast(int phoneid, sysarg_t method, sysarg_t arg1,
    88     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, ipc_call_t *dataptr);
    89 extern aid_t async_send_slow(int phoneid, sysarg_t method, sysarg_t arg1,
    90     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5,
    91     ipc_call_t *dataptr);
    92 extern void async_wait_for(aid_t amsgid, sysarg_t *result);
    93 extern int async_wait_timeout(aid_t amsgid, sysarg_t *retval,
    94     suseconds_t timeout);
    95 
    96 extern fid_t async_new_connection(sysarg_t in_phone_hash, ipc_callid_t callid,
    97     ipc_call_t *call, void (*cthread)(ipc_callid_t, ipc_call_t *));
    98 extern void async_usleep(suseconds_t timeout);
     89extern aid_t async_send_fast(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
     90    sysarg_t, ipc_call_t *);
     91extern aid_t async_send_slow(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
     92    sysarg_t, sysarg_t, ipc_call_t *);
     93extern void async_wait_for(aid_t, sysarg_t *);
     94extern int async_wait_timeout(aid_t, sysarg_t *, suseconds_t);
     95
     96extern fid_t async_new_connection(sysarg_t, sysarg_t, ipc_callid_t,
     97    ipc_call_t *, void (*)(ipc_callid_t, ipc_call_t *));
     98extern void async_usleep(suseconds_t);
    9999extern void async_create_manager(void);
    100100extern void async_destroy_manager(void);
    101101
    102 extern void async_set_client_connection(async_client_conn_t conn);
    103 extern void async_set_interrupt_received(async_client_conn_t conn);
    104 
    105 /* Wrappers for simple communication */
    106 #define async_msg_0(phone, method) \
    107         ipc_call_async_0((phone), (method), NULL, NULL, true)
    108 #define async_msg_1(phone, method, arg1) \
    109         ipc_call_async_1((phone), (method), (arg1), NULL, NULL, \
    110             true)
    111 #define async_msg_2(phone, method, arg1, arg2) \
    112         ipc_call_async_2((phone), (method), (arg1), (arg2), NULL, NULL, \
    113             true)
    114 #define async_msg_3(phone, method, arg1, arg2, arg3) \
    115         ipc_call_async_3((phone), (method), (arg1), (arg2), (arg3), NULL, NULL, \
    116             true)
    117 #define async_msg_4(phone, method, arg1, arg2, arg3, arg4) \
    118         ipc_call_async_4((phone), (method), (arg1), (arg2), (arg3), (arg4), NULL, \
    119             NULL, true)
    120 #define async_msg_5(phone, method, arg1, arg2, arg3, arg4, arg5) \
    121         ipc_call_async_5((phone), (method), (arg1), (arg2), (arg3), (arg4), \
    122             (arg5), NULL, NULL, true)
     102extern void async_set_client_data_constructor(async_client_data_ctor_t);
     103extern void async_set_client_data_destructor(async_client_data_dtor_t);
     104
     105extern void *async_client_data_get(void);
     106
     107extern void async_set_client_connection(async_client_conn_t);
     108extern void async_set_interrupt_received(async_client_conn_t);
     109
     110/*
     111 * Wrappers for simple communication.
     112 */
     113
     114extern void async_msg_0(int, sysarg_t);
     115extern void async_msg_1(int, sysarg_t, sysarg_t);
     116extern void async_msg_2(int, sysarg_t, sysarg_t, sysarg_t);
     117extern void async_msg_3(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
     118extern void async_msg_4(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t);
     119extern void async_msg_5(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
     120    sysarg_t);
     121
     122/*
     123 * Wrappers for answer routines.
     124 */
     125
     126extern sysarg_t async_answer_0(ipc_callid_t, sysarg_t);
     127extern sysarg_t async_answer_1(ipc_callid_t, sysarg_t, sysarg_t);
     128extern sysarg_t async_answer_2(ipc_callid_t, sysarg_t, sysarg_t, sysarg_t);
     129extern sysarg_t async_answer_3(ipc_callid_t, sysarg_t, sysarg_t, sysarg_t,
     130    sysarg_t);
     131extern sysarg_t async_answer_4(ipc_callid_t, sysarg_t, sysarg_t, sysarg_t,
     132    sysarg_t, sysarg_t);
     133extern sysarg_t async_answer_5(ipc_callid_t, sysarg_t, sysarg_t, sysarg_t,
     134    sysarg_t, sysarg_t, sysarg_t);
     135
     136/*
     137 * Wrappers for forwarding routines.
     138 */
     139
     140extern int async_forward_fast(ipc_callid_t, int, sysarg_t, sysarg_t, sysarg_t,
     141    unsigned int);
     142extern int async_forward_slow(ipc_callid_t, int, sysarg_t, sysarg_t, sysarg_t,
     143    sysarg_t, sysarg_t, sysarg_t, unsigned int);
    123144
    124145/*
     
    128149 * and slow verion based on m.
    129150 */
     151
    130152#define async_req_0_0(phoneid, method) \
    131153        async_req_fast((phoneid), (method), 0, 0, 0, 0, NULL, NULL, NULL, NULL, \
     
    243265            (arg5), (rc1), (rc2), (rc3), (rc4), (rc5))
    244266
    245 extern sysarg_t async_req_fast(int phoneid, sysarg_t method, sysarg_t arg1,
    246     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t *r1, sysarg_t *r2,
    247     sysarg_t *r3, sysarg_t *r4, sysarg_t *r5);
    248 extern sysarg_t async_req_slow(int phoneid, sysarg_t method, sysarg_t arg1,
    249     sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, sysarg_t arg5, sysarg_t *r1,
    250     sysarg_t *r2, sysarg_t *r3, sysarg_t *r4, sysarg_t *r5);
     267extern sysarg_t async_req_fast(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
     268    sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *);
     269extern sysarg_t async_req_slow(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
     270    sysarg_t, sysarg_t, sysarg_t *, sysarg_t *, sysarg_t *, sysarg_t *,
     271    sysarg_t *);
    251272
    252273static inline void async_serialize_start(void)
     
    260281}
    261282
     283extern int async_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t,
     284    async_client_conn_t);
    262285extern int async_connect_me_to(int, sysarg_t, sysarg_t, sysarg_t);
    263286extern int async_connect_me_to_blocking(int, sysarg_t, sysarg_t, sysarg_t);
     287extern int async_connect_kbox(task_id_t);
     288extern int async_hangup(int);
     289extern void async_poke(void);
    264290
    265291/*
    266292 * User-friendly wrappers for async_share_in_start().
    267293 */
     294
    268295#define async_share_in_start_0_0(phoneid, dst, size) \
    269296        async_share_in_start((phoneid), (dst), (size), 0, NULL)
     
    275302        async_share_in_start((phoneid), (dst), (size), (arg), (flags))
    276303
    277 extern int async_share_in_start(int, void *, size_t, sysarg_t, int *);
    278 extern int async_share_in_receive(ipc_callid_t *, size_t *);
    279 extern int async_share_in_finalize(ipc_callid_t, void *, int );
    280 extern int async_share_out_start(int, void *, int);
    281 extern int async_share_out_receive(ipc_callid_t *, size_t *, int *);
     304extern int async_share_in_start(int, void *, size_t, sysarg_t, unsigned int *);
     305extern bool async_share_in_receive(ipc_callid_t *, size_t *);
     306extern int async_share_in_finalize(ipc_callid_t, void *, unsigned int);
     307
     308extern int async_share_out_start(int, void *, unsigned int);
     309extern bool async_share_out_receive(ipc_callid_t *, size_t *, unsigned int *);
    282310extern int async_share_out_finalize(ipc_callid_t, void *);
    283311
     
    285313 * User-friendly wrappers for async_data_read_forward_fast().
    286314 */
     315
    287316#define async_data_read_forward_0_0(phoneid, method, answer) \
    288317        async_data_read_forward_fast((phoneid), (method), 0, 0, 0, 0, NULL)
     
    312341
    313342extern int async_data_read_start(int, void *, size_t);
    314 extern int async_data_read_receive(ipc_callid_t *, size_t *);
     343extern bool async_data_read_receive(ipc_callid_t *, size_t *);
    315344extern int async_data_read_finalize(ipc_callid_t, const void *, size_t);
    316345
     
    321350 * User-friendly wrappers for async_data_write_forward_fast().
    322351 */
     352
    323353#define async_data_write_forward_0_0(phoneid, method, answer) \
    324354        async_data_write_forward_fast((phoneid), (method), 0, 0, 0, 0, NULL)
     
    350380
    351381extern int async_data_write_start(int, const void *, size_t);
    352 extern int async_data_write_receive(ipc_callid_t *, size_t *);
     382extern bool async_data_write_receive(ipc_callid_t *, size_t *);
    353383extern int async_data_write_finalize(ipc_callid_t, void *, size_t);
    354384
    355385extern int async_data_write_accept(void **, const bool, const size_t,
    356386    const size_t, const size_t, size_t *);
    357 extern void async_data_write_void(const int);
     387extern void async_data_write_void(sysarg_t);
    358388
    359389extern int async_data_write_forward_fast(int, sysarg_t, sysarg_t, sysarg_t,
  • uspace/lib/c/include/async_sess.h

    r87e373b rc4fb95d3  
    4545} async_sess_t;
    4646
    47 extern void _async_sess_init(void);
    4847extern void async_session_create(async_sess_t *, int, sysarg_t);
    4948extern void async_session_destroy(async_sess_t *);
  • uspace/lib/c/include/byteorder.h

    r87e373b rc4fb95d3  
    8080#endif
    8181
    82 #define htons(n)        host2uint16_t_be((n))
    83 #define htonl(n)        host2uint32_t_be((n))
    84 #define ntohs(n)        uint16_t_be2host((n))
    85 #define ntohl(n)        uint32_t_be2host((n))
     82#define htons(n)  host2uint16_t_be((n))
     83#define htonl(n)  host2uint32_t_be((n))
     84#define ntohs(n)  uint16_t_be2host((n))
     85#define ntohl(n)  uint32_t_be2host((n))
    8686
    8787static inline uint64_t uint64_t_byteorder_swap(uint64_t n)
  • uspace/lib/c/include/ddi.h

    r87e373b rc4fb95d3  
    3636#define LIBC_DDI_H_
    3737
     38#include <sys/types.h>
     39#include <kernel/ddi/irq.h>
    3840#include <task.h>
    3941
     
    4244extern int iospace_enable(task_id_t, void *, unsigned long);
    4345extern int pio_enable(void *, size_t, void **);
     46extern int register_irq(int, int, int, irq_code_t *);
     47extern int unregister_irq(int, int);
    4448
    4549#endif
  • uspace/lib/c/include/devman.h

    r87e373b rc4fb95d3  
    4141#include <bool.h>
    4242
    43 
    4443extern int devman_get_phone(devman_interface_t, unsigned int);
    4544extern void devman_hangup_phone(devman_interface_t);
    4645
    4746extern int devman_driver_register(const char *, async_client_conn_t);
    48 extern int devman_child_device_register(const char *, match_id_list_t *,
     47extern int devman_add_function(const char *, fun_type_t, match_id_list_t *,
    4948    devman_handle_t, devman_handle_t *);
    5049
  • uspace/lib/c/include/err.h

    r87e373b rc4fb95d3  
    3939
    4040#define errx(status, fmt, ...) \
    41         { \
     41        do { \
    4242                printf((fmt), ##__VA_ARGS__); \
    43                 _exit(status); \
    44         }
     43                exit(status); \
     44        } while (0)
    4545
    4646#endif
  • uspace/lib/c/include/errno.h

    r87e373b rc4fb95d3  
    3939#include <fibril.h>
    4040
     41#define errno _errno
     42
    4143extern int _errno;
    42 
    43 #define errno _errno
    4444
    4545#define EMFILE        (-18)
     
    5757
    5858/** An API function is called while another blocking function is in progress. */
    59 #define EINPROGRESS     (-10036)
     59#define EINPROGRESS  (-10036)
    6060
    6161/** The socket identifier is not valid. */
    62 #define ENOTSOCK        (-10038)
     62#define ENOTSOCK  (-10038)
    6363
    6464/** The destination address required. */
    65 #define EDESTADDRREQ    (-10039)
     65#define EDESTADDRREQ  (-10039)
    6666
    6767/** Protocol is not supported.  */
    68 #define EPROTONOSUPPORT (-10043)
     68#define EPROTONOSUPPORT  (-10043)
    6969
    7070/** Socket type is not supported. */
    71 #define ESOCKTNOSUPPORT (-10044)
     71#define ESOCKTNOSUPPORT  (-10044)
    7272
    7373/** Protocol family is not supported. */
    74 #define EPFNOSUPPORT    (-10046)
     74#define EPFNOSUPPORT  (-10046)
    7575
    7676/** Address family is not supported. */
    77 #define EAFNOSUPPORT    (-10047)
     77#define EAFNOSUPPORT  (-10047)
    7878
    7979/** Address is already in use. */
    80 #define EADDRINUSE      (-10048)
     80#define EADDRINUSE  (-10048)
    8181
    8282/** The socket is not connected or bound. */
    83 #define ENOTCONN        (-10057)
     83#define ENOTCONN  (-10057)
    8484
    8585/** The requested operation was not performed. Try again later. */
    86 #define EAGAIN          (-11002)
     86#define EAGAIN  (-11002)
    8787
    88 /** No data.
    89  */
    90 #define NO_DATA         (-11004)
     88/** No data. */
     89#define NO_DATA (-11004)
    9190
    9291#endif
  • uspace/lib/c/include/event.h

    r87e373b rc4fb95d3  
    3737
    3838#include <kernel/ipc/event_types.h>
    39 #include <ipc/ipc.h>
    4039
    4140extern int event_subscribe(event_type_t, sysarg_t);
  • uspace/lib/c/include/io/console.h

    r87e373b rc4fb95d3  
    3636#define LIBC_IO_CONSOLE_H_
    3737
    38 #include <ipc/ipc.h>
    3938#include <bool.h>
    4039
  • uspace/lib/c/include/io/screenbuffer.h

    r87e373b rc4fb95d3  
    3838#include <stdint.h>
    3939#include <sys/types.h>
    40 #include <ipc/ipc.h>
    4140#include <bool.h>
    4241
  • uspace/lib/c/include/ipc/adb.h

    r87e373b rc4fb95d3  
    3232/** @file
    3333 * @brief ADB device interface.
    34  */ 
     34 */
    3535
    3636#ifndef LIBC_IPC_ADB_H_
    3737#define LIBC_IPC_ADB_H_
    3838
    39 #include <ipc/ipc.h>
     39#include <ipc/common.h>
    4040
    4141typedef enum {
    4242        ADB_REG_WRITE = IPC_FIRST_USER_METHOD
    4343} adb_request_t;
    44 
    4544
    4645typedef enum {
  • uspace/lib/c/include/ipc/arp.h

    r87e373b rc4fb95d3  
    3939#define LIBC_ARP_MESSAGES_
    4040
    41 #include <ipc/ipc.h>
    4241#include <ipc/net.h>
    4342
  • uspace/lib/c/include/ipc/bd.h

    r87e373b rc4fb95d3  
    3131 */
    3232/** @file
    33  */ 
     33 */
    3434
    3535#ifndef LIBC_IPC_BD_H_
    3636#define LIBC_IPC_BD_H_
    3737
    38 #include <ipc/ipc.h>
     38#include <ipc/common.h>
    3939
    4040typedef enum {
  • uspace/lib/c/include/ipc/char.h

    r87e373b rc4fb95d3  
    3232/** @file
    3333 * @brief Character device interface.
    34  */ 
     34 */
    3535
    3636#ifndef LIBC_IPC_CHAR_H_
    3737#define LIBC_IPC_CHAR_H_
    3838
    39 #include <ipc/ipc.h>
     39#include <ipc/common.h>
    4040
    4141typedef enum {
    4242        CHAR_WRITE_BYTE = IPC_FIRST_USER_METHOD
    4343} char_request_t;
    44 
    4544
    4645typedef enum {
  • uspace/lib/c/include/ipc/clipboard.h

    r87e373b rc4fb95d3  
    3636#define LIBC_IPC_CLIPBOARD_H_
    3737
    38 #include <ipc/ipc.h>
    39 
    4038typedef enum {
    4139        CLIPBOARD_PUT_DATA = IPC_FIRST_USER_METHOD,
  • uspace/lib/c/include/ipc/console.h

    r87e373b rc4fb95d3  
    3636#define LIBC_IPC_CONSOLE_H_
    3737
    38 #include <ipc/ipc.h>
    3938#include <ipc/vfs.h>
    4039
  • uspace/lib/c/include/ipc/dev_iface.h

    r87e373b rc4fb95d3  
    3030#define LIBC_IPC_DEV_IFACE_H_
    3131
    32 #include <ipc/ipc.h>
    3332#include <malloc.h>
    3433#include <unistd.h>
  • uspace/lib/c/include/ipc/devman.h

    r87e373b rc4fb95d3  
    3030 * @{
    3131 */
    32  
     32
    3333#ifndef LIBC_IPC_DEVMAN_H_
    3434#define LIBC_IPC_DEVMAN_H_
    3535
     36#include <ipc/common.h>
    3637#include <adt/list.h>
    37 #include <ipc/ipc.h>
    38 #include <stdlib.h>
    39 #include <stdio.h>
    40 #include <str.h>
     38#include <malloc.h>
     39#include <mem.h>
    4140
    42 #define DEVMAN_NAME_MAXLEN 256
     41#define DEVMAN_NAME_MAXLEN  256
    4342
    4443typedef sysarg_t devman_handle_t;
     44
     45typedef enum {
     46        /** Invalid value for debugging purposes */
     47        fun_invalid = 0,
     48        /** Function to which child devices attach */
     49        fun_inner,
     50        /** Fuction exported to external clients (leaf function) */
     51        fun_exposed
     52} fun_type_t;
    4553
    4654/** Ids of device models used for device-to-driver matching.
     
    6775} match_id_list_t;
    6876
    69 
    70 static inline match_id_t * create_match_id()
     77static inline match_id_t *create_match_id(void)
    7178{
    7279        match_id_t *id = malloc(sizeof(match_id_t));
     
    8592}
    8693
    87 static inline void add_match_id(match_id_list_t *ids, match_id_t *id) 
     94static inline void add_match_id(match_id_list_t *ids, match_id_t *id)
    8895{
    8996        match_id_t *mid = NULL;
    90         link_t *link = ids->ids.next;   
     97        link_t *link = ids->ids.next;
    9198       
    9299        while (link != &ids->ids) {
     
    98105        }
    99106       
    100         list_insert_before(&id->link, link);   
     107        list_insert_before(&id->link, link);
    101108}
    102109
     
    129136typedef enum {
    130137        DEVMAN_DRIVER_REGISTER = IPC_FIRST_USER_METHOD,
    131         DEVMAN_ADD_CHILD_DEVICE,
     138        DEVMAN_ADD_FUNCTION,
    132139        DEVMAN_ADD_MATCH_ID,
    133140        DEVMAN_ADD_DEVICE_TO_CLASS
  • uspace/lib/c/include/ipc/devmap.h

    r87e373b rc4fb95d3  
    3434#define DEVMAP_DEVMAP_H_
    3535
    36 #include <atomic.h>
    37 #include <ipc/ipc.h>
    38 #include <adt/list.h>
     36#include <ipc/common.h>
    3937
    4038#define DEVMAP_NAME_MAXLEN  255
  • uspace/lib/c/include/ipc/fb.h

    r87e373b rc4fb95d3  
    3131 */
    3232/** @file
    33  */ 
     33 */
    3434
    3535#ifndef LIBC_FB_H_
    3636#define LIBC_FB_H_
    3737
    38 #include <ipc/ipc.h>
     38#include <ipc/common.h>
    3939
    4040typedef enum {
  • uspace/lib/c/include/ipc/icmp.h

    r87e373b rc4fb95d3  
    3333/** @file
    3434 * ICMP module messages.
    35  * @see icmp_interface.h
     35 * @see icmp_remote.h
    3636 */
    3737
     
    3939#define LIBC_ICMP_MESSAGES_
    4040
    41 #include <ipc/ipc.h>
    4241#include <ipc/net.h>
    4342#include <sys/types.h>
    4443#include <sys/time.h>
    45 
    4644#include <net/icmp_codes.h>
    4745
    4846/** ICMP module messages. */
    4947typedef enum {
    50         /** Sends echo request. @see icmp_echo() */
     48        /** Send echo request. @see icmp_echo() */
    5149        NET_ICMP_ECHO = NET_ICMP_FIRST,
    5250       
    5351        /**
    54          * Sends destination unreachable error message.
     52         * Send destination unreachable error message.
    5553         * @see icmp_destination_unreachable_msg()
    5654         */
     
    5856       
    5957        /**
    60          * Sends source quench error message.
     58         * Send source quench error message.
    6159         * @see icmp_source_quench_msg()
    6260         */
     
    6462       
    6563        /**
    66          * Sends time exceeded error message.
     64         * Send time exceeded error message.
    6765         * @see icmp_time_exceeded_msg()
    6866         */
     
    7068       
    7169        /**
    72          * Sends parameter problem error message.
     70         * Send parameter problem error message.
    7371         * @see icmp_parameter_problem_msg()
    7472         */
    75         NET_ICMP_PARAMETERPROB,
    76        
    77         /** Initializes new connection. */
    78         NET_ICMP_INIT
    79 } icmp_messages;
     73        NET_ICMP_PARAMETERPROB
     74} icmp_messages_t;
    8075
    8176/** @name ICMP specific message parameters definitions */
  • uspace/lib/c/include/ipc/il.h

    r87e373b rc4fb95d3  
    4040#define LIBC_IL_MESSAGES_H_
    4141
    42 #include <ipc/ipc.h>
    4342#include <ipc/net.h>
    4443
  • uspace/lib/c/include/ipc/ip.h

    r87e373b rc4fb95d3  
    3939#define LIBC_IP_MESSAGES_H_
    4040
    41 #include <ipc/ipc.h>
    4241#include <ipc/net.h>
    43 
    4442#include <net/in.h>
    4543#include <net/ip_codes.h>
  • uspace/lib/c/include/ipc/ipc.h

    r87e373b rc4fb95d3  
    3333 */
    3434
    35 #ifndef LIBIPC_IPC_H_
    36 #define LIBIPC_IPC_H_
    37 
     35#if ((defined(LIBC_ASYNC_H_)) && (!defined(LIBC_ASYNC_C_)))
     36        #error Do not intermix low-level IPC interface and async framework
     37#endif
     38
     39#ifndef LIBC_IPC_H_
     40#define LIBC_IPC_H_
     41
     42#include <sys/types.h>
     43#include <ipc/common.h>
     44#include <kernel/synch/synch.h>
    3845#include <task.h>
    39 #include <kernel/ipc/ipc.h>
    40 #include <kernel/ddi/irq.h>
    41 #include <sys/types.h>
    42 #include <kernel/synch/synch.h>
    43 
    44 #define IPC_FLAG_BLOCKING  0x01
    45 
    46 typedef struct {
    47         sysarg_t args[IPC_CALL_LEN];
    48         sysarg_t in_phone_hash;
    49 } ipc_call_t;
    50 
    51 typedef sysarg_t ipc_callid_t;
    52 
    53 typedef void (* ipc_async_callback_t)(void *, int, ipc_call_t *);
     46
     47typedef void (*ipc_async_callback_t)(void *, int, ipc_call_t *);
    5448
    5549/*
     
    5953 * possible, the fast version is used.
    6054 */
     55
    6156#define ipc_call_sync_0_0(phoneid, method) \
    6257        ipc_call_sync_fast((phoneid), (method), 0, 0, 0, 0, 0, 0, 0, 0)
     
    188183    sysarg_t *);
    189184
    190 extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, uint32_t, int);
    191 extern ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *, uint32_t);
     185extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, sysarg_t, unsigned int);
    192186extern void ipc_poke(void);
    193187
    194 static inline ipc_callid_t ipc_wait_for_call(ipc_call_t *data)
    195 {
    196         return ipc_wait_for_call_timeout(data, SYNCH_NO_TIMEOUT);
    197 }
    198 
     188#define ipc_wait_for_call(data) \
     189        ipc_wait_for_call_timeout(data, SYNCH_NO_TIMEOUT);
     190
     191extern ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *, sysarg_t);
    199192extern ipc_callid_t ipc_trywait_for_call(ipc_call_t *);
    200193
     
    205198 * to m.
    206199 */
     200
    207201#define ipc_answer_0(callid, retval) \
    208202        ipc_answer_fast((callid), (retval), 0, 0, 0, 0)
     
    229223 * to m.
    230224 */
     225
    231226#define ipc_call_async_0(phoneid, method, private, callback, can_preempt) \
    232227        ipc_call_async_fast((phoneid), (method), 0, 0, 0, 0, (private), \
     
    254249
    255250extern void ipc_call_async_fast(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
    256     sysarg_t, void *, ipc_async_callback_t, int);
     251    sysarg_t, void *, ipc_async_callback_t, bool);
    257252extern void ipc_call_async_slow(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t,
    258     sysarg_t, sysarg_t, void *, ipc_async_callback_t, int);
    259 
    260 extern int ipc_connect_to_me(int, int, int, int, sysarg_t *);
    261 extern int ipc_connect_me_to(int, int, int, int);
    262 extern int ipc_connect_me_to_blocking(int, int, int, int);
     253    sysarg_t, sysarg_t, void *, ipc_async_callback_t, bool);
     254
     255extern int ipc_connect_to_me(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t *,
     256    sysarg_t *);
     257extern int ipc_connect_me_to(int, sysarg_t, sysarg_t, sysarg_t);
     258extern int ipc_connect_me_to_blocking(int, sysarg_t, sysarg_t, sysarg_t);
     259
    263260extern int ipc_hangup(int);
    264 extern int ipc_register_irq(int, int, int, irq_code_t *);
    265 extern int ipc_unregister_irq(int, int);
    266 extern int ipc_forward_fast(ipc_callid_t, int, int, sysarg_t, sysarg_t, int);
    267 extern int ipc_forward_slow(ipc_callid_t, int, int, sysarg_t, sysarg_t,
    268     sysarg_t, sysarg_t, sysarg_t, int);
     261
     262extern int ipc_forward_fast(ipc_callid_t, int, sysarg_t, sysarg_t, sysarg_t,
     263    unsigned int);
     264extern int ipc_forward_slow(ipc_callid_t, int, sysarg_t, sysarg_t, sysarg_t,
     265    sysarg_t, sysarg_t, sysarg_t, unsigned int);
    269266
    270267/*
    271268 * User-friendly wrappers for ipc_share_in_start().
    272269 */
     270
    273271#define ipc_share_in_start_0_0(phoneid, dst, size) \
    274272        ipc_share_in_start((phoneid), (dst), (size), 0, NULL)
     
    280278        ipc_share_in_start((phoneid), (dst), (size), (arg), (flags))
    281279
    282 extern int ipc_share_in_start(int, void *, size_t, sysarg_t, int *);
    283 extern int ipc_share_in_finalize(ipc_callid_t, void *, int );
    284 extern int ipc_share_out_start(int, void *, int);
     280extern int ipc_share_in_start(int, void *, size_t, sysarg_t, unsigned int *);
     281extern int ipc_share_in_finalize(ipc_callid_t, void *, unsigned int);
     282extern int ipc_share_out_start(int, void *, unsigned int);
    285283extern int ipc_share_out_finalize(ipc_callid_t, void *);
    286284extern int ipc_data_read_start(int, void *, size_t);
  • uspace/lib/c/include/ipc/irc.h

    r87e373b rc4fb95d3  
    3636#define LIBC_IRC_H_
    3737
    38 #include <ipc/ipc.h>
     38#include <ipc/common.h>
    3939
    4040typedef enum {
  • uspace/lib/c/include/ipc/kbd.h

    r87e373b rc4fb95d3  
    3838#define LIBC_IPC_KBD_H_
    3939
    40 #include <ipc/ipc.h>
     40#include <ipc/common.h>
    4141
    4242typedef enum {
  • uspace/lib/c/include/ipc/loader.h

    r87e373b rc4fb95d3  
    3131 */
    3232/** @file
    33  */ 
     33 */
    3434
    3535#ifndef LIBC_IPC_LOADER_H_
    3636#define LIBC_IPC_LOADER_H_
    3737
    38 #include <ipc/ipc.h>
     38#include <ipc/common.h>
    3939
    4040typedef enum {
  • uspace/lib/c/include/ipc/mouse.h

    r87e373b rc4fb95d3  
    3737#define LIBC_IPC_MOUSE_H_
    3838
    39 #include <ipc/ipc.h>
     39#include <ipc/common.h>
    4040
    4141typedef enum {
  • uspace/lib/c/include/ipc/net.h

    r87e373b rc4fb95d3  
    3838#define LIBC_NET_MESSAGES_H_
    3939
    40 #include <ipc/ipc.h>
    4140#include <ipc/services.h>
    42 
    4341#include <net/device.h>
    4442#include <net/packet.h>
  • uspace/lib/c/include/ipc/net_net.h

    r87e373b rc4fb95d3  
    3939#define LIBC_NET_NET_MESSAGES_H_
    4040
    41 #include <ipc/ipc.h>
    4241#include <ipc/net.h>
    4342
  • uspace/lib/c/include/ipc/netif.h

    r87e373b rc4fb95d3  
    3838#define LIBC_NETIF_MESSAGES_H_
    3939
    40 #include <ipc/ipc.h>
    4140#include <ipc/net.h>
    4241
  • uspace/lib/c/include/ipc/nil.h

    r87e373b rc4fb95d3  
    3838#define LIBC_NIL_MESSAGES_H_
    3939
    40 #include <ipc/ipc.h>
    4140#include <ipc/net.h>
    4241
  • uspace/lib/c/include/ipc/ns.h

    r87e373b rc4fb95d3  
    3333 */
    3434
    35 #ifndef LIBIPC_NS_H_
    36 #define LIBIPC_NS_H_
     35#ifndef LIBC_NS_H_
     36#define LIBC_NS_H_
    3737
    38 #include <ipc/ipc.h>
     38#include <sys/types.h>
     39#include <ipc/common.h>
    3940
    4041typedef enum {
     
    4546} ns_request_t;
    4647
     48extern int service_register(sysarg_t);
     49extern int service_connect(sysarg_t, sysarg_t, sysarg_t);
     50extern int service_connect_blocking(sysarg_t, sysarg_t, sysarg_t);
     51
    4752#endif
    4853
  • uspace/lib/c/include/ipc/packet.h

    r87e373b rc4fb95d3  
    3838#define LIBC_PACKET_MESSAGES_
    3939
    40 #include <ipc/ipc.h>
    4140#include <ipc/net.h>
    4241
  • uspace/lib/c/include/ipc/services.h

    r87e373b rc4fb95d3  
    3535 */
    3636
    37 #ifndef LIBIPC_SERVICES_H_
    38 #define LIBIPC_SERVICES_H_
     37#ifndef LIBC_SERVICES_H_
     38#define LIBC_SERVICES_H_
    3939
    4040typedef enum {
     
    6666} services_t;
    6767
    68 /* Memory area to be received from NS */
    69 #define SERVICE_MEM_REALTIME    1
    70 #define SERVICE_MEM_KLOG        2
    71 
    7268#endif
    7369
  • uspace/lib/c/include/ipc/socket.h

    r87e373b rc4fb95d3  
    3838#define LIBC_SOCKET_MESSAGES_H_
    3939
    40 #include <ipc/ipc.h>
    4140#include <ipc/net.h>
    4241
  • uspace/lib/c/include/ipc/tl.h

    r87e373b rc4fb95d3  
    3939#define LIBC_TL_MESSAGES_H_
    4040
    41 #include <ipc/ipc.h>
    4241#include <ipc/net.h>
    4342
  • uspace/lib/c/include/ipc/vfs.h

    r87e373b rc4fb95d3  
    3636#define LIBC_IPC_VFS_H_
    3737
    38 #include <ipc/ipc.h>
     38#include <ipc/common.h>
    3939#include <sys/types.h>
    4040#include <bool.h>
  • uspace/lib/c/include/libc.h

    r87e373b rc4fb95d3  
    6262        __syscall6(p1, p2, p3, p4, p5, p6, id)
    6363
    64 extern void __main(void *pcb_ptr);
    65 extern void __exit(void);
    66 
    6764#endif
    6865
  • uspace/lib/c/include/loader/pcb.h

    r87e373b rc4fb95d3  
    5252        /** Program entry point. */
    5353        entry_point_t entry;
    54 
     54       
    5555        /** Current working directory. */
    5656        char *cwd;
  • uspace/lib/c/include/malloc.h

    r87e373b rc4fb95d3  
    3838#include <sys/types.h>
    3939
    40 extern void __heap_init(void);
    41 extern uintptr_t get_max_heap_addr(void);
    42 
    4340extern void *malloc(const size_t size)
    4441    __attribute__((malloc));
  • uspace/lib/c/include/net/icmp_common.h

    r87e373b rc4fb95d3  
    4141#include <sys/time.h>
    4242
    43 /** Default timeout for incoming connections in microseconds. */
    44 #define ICMP_CONNECT_TIMEOUT    (1 * 1000 * 1000)
     43/** Default timeout for incoming connections in microseconds (1 sec). */
     44#define ICMP_CONNECT_TIMEOUT  1000000
    4545
    46 extern int icmp_connect_module(services_t, suseconds_t);
     46extern int icmp_connect_module(suseconds_t);
    4747
    4848#endif
  • uspace/lib/c/include/net/modules.h

    r87e373b rc4fb95d3  
    4343
    4444#include <async.h>
    45 
    46 #include <ipc/ipc.h>
    4745#include <ipc/services.h>
    48 
    4946#include <sys/time.h>
    5047
  • uspace/lib/c/include/setjmp.h

    r87e373b rc4fb95d3  
    4141
    4242extern int setjmp(jmp_buf env);
    43 extern void longjmp(jmp_buf env,int val) __attribute__((__noreturn__));
     43extern void longjmp(jmp_buf env, int val) __attribute__((noreturn));
    4444
    4545#endif
  • uspace/lib/c/include/stdlib.h

    r87e373b rc4fb95d3  
    4040#include <stacktrace.h>
    4141
    42 #define abort() \
    43         do { \
    44                 stacktrace_print(); \
    45                 _exit(1); \
    46         } while (0)
     42#define RAND_MAX  714025
    4743
    48 #define core() \
    49         *((int *) 0) = 0xbadbad;
    50 
    51 #define exit(status)  _exit((status))
    52 
    53 #define RAND_MAX  714025
     44#define rand()       random()
     45#define srand(seed)  srandom(seed)
    5446
    5547extern long int random(void);
    5648extern void srandom(unsigned int seed);
    5749
    58 static inline int rand(void)
    59 {
    60         return random();
    61 }
    62 
    63 static inline void srand(unsigned int seed)
    64 {
    65         srandom(seed);
    66 }
     50extern void abort(void) __attribute__((noreturn));
    6751
    6852#endif
  • uspace/lib/c/include/syscall.h

    r87e373b rc4fb95d3  
    3232/**
    3333 * @file
    34  * @brief       Syscall function declaration for architectures that don't
    35  *              inline syscalls or architectures that handle syscalls
    36  *              according to the number of arguments.
     34 * @brief Syscall function declaration for architectures that don't
     35 *        inline syscalls or architectures that handle syscalls
     36 *        according to the number of arguments.
    3737 */
    3838
     
    4040#define LIBC_SYSCALL_H_
    4141
    42 #ifndef LIBARCH_SYSCALL_GENERIC
    43 #error "You can't include this file directly."
     42#ifndef LIBARCH_SYSCALL_GENERIC
     43        #error You cannot include this file directly
    4444#endif
    4545
     
    4747#include <kernel/syscall/syscall.h>
    4848
    49 #define __syscall0      __syscall
    50 #define __syscall1      __syscall
    51 #define __syscall2      __syscall
    52 #define __syscall3      __syscall
    53 #define __syscall4      __syscall
    54 #define __syscall5      __syscall
    55 #define __syscall6      __syscall
     49#define __syscall0  __syscall
     50#define __syscall1  __syscall
     51#define __syscall2  __syscall
     52#define __syscall3  __syscall
     53#define __syscall4  __syscall
     54#define __syscall5  __syscall
     55#define __syscall6  __syscall
    5656
    5757extern sysarg_t __syscall(const sysarg_t p1, const sysarg_t p2,
  • uspace/lib/c/include/thread.h

    r87e373b rc4fb95d3  
    3636#define LIBC_THREAD_H_
    3737
    38 #include <kernel/proc/uarg.h>
    3938#include <libarch/thread.h>
    4039#include <sys/types.h>
     
    4241typedef uint64_t thread_id_t;
    4342
    44 extern void __thread_entry(void);
    45 extern void __thread_main(uspace_arg_t *);
    46 
    4743extern int thread_create(void (*)(void *), void *, const char *, thread_id_t *);
    48 extern void thread_exit(int) __attribute__ ((noreturn));
     44extern void thread_exit(int) __attribute__((noreturn));
    4945extern void thread_detach(thread_id_t);
    5046extern int thread_join(thread_id_t);
  • uspace/lib/c/include/tls.h

    r87e373b rc4fb95d3  
    5757extern void tls_free_variant_1(tcb_t *, size_t);
    5858#endif
     59
    5960#ifdef CONFIG_TLS_VARIANT_2
    6061extern tcb_t *tls_alloc_variant_2(void **, size_t);
  • uspace/lib/c/include/udebug.h

    r87e373b rc4fb95d3  
    3838#include <kernel/udebug/udebug.h>
    3939#include <sys/types.h>
    40 #include <libarch/types.h>
    4140
    4241typedef sysarg_t thash_t;
    4342
    44 int udebug_begin(int phoneid);
    45 int udebug_end(int phoneid);
    46 int udebug_set_evmask(int phoneid, udebug_evmask_t mask);
    47 int udebug_thread_read(int phoneid, void *buffer, size_t n,
    48         size_t *copied, size_t *needed);
    49 int udebug_name_read(int phoneid, void *buffer, size_t n,
    50         size_t *copied, size_t *needed);
    51 int udebug_areas_read(int phoneid, void *buffer, size_t n,
    52         size_t *copied, size_t *needed);
    53 int udebug_mem_read(int phoneid, void *buffer, uintptr_t addr, size_t n);
    54 int udebug_args_read(int phoneid, thash_t tid, sysarg_t *buffer);
    55 int udebug_regs_read(int phoneid, thash_t tid, void *buffer);
    56 int udebug_go(int phoneid, thash_t tid, udebug_event_t *ev_type,
    57         sysarg_t *val0, sysarg_t *val1);
    58 int udebug_stop(int phoneid, thash_t tid);
     43int udebug_begin(int);
     44int udebug_end(int);
     45int udebug_set_evmask(int, udebug_evmask_t);
     46int udebug_thread_read(int, void *, size_t , size_t *, size_t *);
     47int udebug_name_read(int, void *, size_t, size_t *, size_t *);
     48int udebug_areas_read(int, void *, size_t, size_t *, size_t *);
     49int udebug_mem_read(int, void *, uintptr_t, size_t);
     50int udebug_args_read(int, thash_t, sysarg_t *);
     51int udebug_regs_read(int, thash_t, void *);
     52int udebug_go(int, thash_t, udebug_event_t *, sysarg_t *, sysarg_t *);
     53int udebug_stop(int, thash_t);
    5954
    6055#endif
  • uspace/lib/c/include/unistd.h

    r87e373b rc4fb95d3  
    4141
    4242#ifndef NULL
    43         #define NULL    ((void *) 0)
     43        #define NULL  ((void *) 0)
    4444#endif
    45 
    46 #define getpagesize()  (PAGE_SIZE)
    4745
    4846#ifndef SEEK_SET
     
    5755        #define SEEK_END  2
    5856#endif
     57
     58#define getpagesize()  (PAGE_SIZE)
    5959
    6060extern int dup2(int oldfd, int newfd);
     
    7474extern int chdir(const char *);
    7575
    76 extern void _exit(int) __attribute__((noreturn));
     76extern void exit(int) __attribute__((noreturn));
    7777extern int usleep(useconds_t);
    7878extern unsigned int sleep(unsigned int);
  • uspace/lib/c/include/vfs/vfs.h

    r87e373b rc4fb95d3  
    5757extern int unmount(const char *);
    5858
    59 extern void __stdio_init(int filc, fdi_node_t *filv[]);
    60 extern void __stdio_done(void);
    61 
    6259extern int open_node(fdi_node_t *, int);
    6360extern int fd_phone(int);
Note: See TracChangeset for help on using the changeset viewer.