Subversion Repositories HelenOS

Rev

Rev 4327 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2006 Ondrej Palkovsky
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup libc
  30.  * @{
  31.  */
  32. /** @file
  33.  */
  34.  
  35. #ifndef LIBC_ASYNC_H_
  36. #define LIBC_ASYNC_H_
  37.  
  38. #include <ipc/ipc.h>
  39. #include <fibril.h>
  40. #include <sys/time.h>
  41. #include <atomic.h>
  42. #include <bool.h>
  43.  
  44. typedef ipc_callid_t aid_t;
  45. typedef void (*async_client_conn_t)(ipc_callid_t callid, ipc_call_t *call);
  46.  
  47. extern atomic_t async_futex;
  48.  
  49. static inline void async_manager(void)
  50. {
  51.     fibril_switch(FIBRIL_TO_MANAGER);
  52. }
  53.  
  54. extern ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs);
  55.  
  56. static inline ipc_callid_t async_get_call(ipc_call_t *data)
  57. {
  58.     return async_get_call_timeout(data, 0);
  59. }
  60.  
  61. /*
  62.  * User-friendly wrappers for async_send_fast() and async_send_slow(). The
  63.  * macros are in the form async_send_m(), where m denotes the number of payload
  64.  * arguments.  Each macros chooses between the fast and the slow version based
  65.  * on m.
  66.  */
  67.  
  68. #define async_send_0(phoneid, method, dataptr) \
  69.     async_send_fast((phoneid), (method), 0, 0, 0, 0, (dataptr))
  70. #define async_send_1(phoneid, method, arg1, dataptr) \
  71.     async_send_fast((phoneid), (method), (arg1), 0, 0, 0, (dataptr))
  72. #define async_send_2(phoneid, method, arg1, arg2, dataptr) \
  73.     async_send_fast((phoneid), (method), (arg1), (arg2), 0, 0, (dataptr))
  74. #define async_send_3(phoneid, method, arg1, arg2, arg3, dataptr) \
  75.     async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (dataptr))
  76. #define async_send_4(phoneid, method, arg1, arg2, arg3, arg4, dataptr) \
  77.     async_send_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
  78.         (dataptr))
  79. #define async_send_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, dataptr) \
  80.     async_send_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
  81.         (arg5), (dataptr))
  82.  
  83. extern aid_t async_send_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
  84.     ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr);
  85. extern aid_t async_send_slow(int phoneid, ipcarg_t method, ipcarg_t arg1,
  86.     ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5,
  87.     ipc_call_t *dataptr);
  88. extern void async_wait_for(aid_t amsgid, ipcarg_t *result);
  89. extern int async_wait_timeout(aid_t amsgid, ipcarg_t *retval,
  90.     suseconds_t timeout);
  91.  
  92. extern fid_t async_new_connection(ipcarg_t in_phone_hash, ipc_callid_t callid,
  93.     ipc_call_t *call, void (*cthread)(ipc_callid_t, ipc_call_t *));
  94. extern void async_usleep(suseconds_t timeout);
  95. extern void async_create_manager(void);
  96. extern void async_destroy_manager(void);
  97. extern int _async_init(void);
  98.  
  99. extern void async_set_client_connection(async_client_conn_t conn);
  100. extern void async_set_interrupt_received(async_client_conn_t conn);
  101.  
  102. /* Wrappers for simple communication */
  103. #define async_msg_0(phone, method) \
  104.     ipc_call_async_0((phone), (method), NULL, NULL, true)
  105. #define async_msg_1(phone, method, arg1) \
  106.     ipc_call_async_1((phone), (method), (arg1), NULL, NULL, \
  107.         true)
  108. #define async_msg_2(phone, method, arg1, arg2) \
  109.     ipc_call_async_2((phone), (method), (arg1), (arg2), NULL, NULL, \
  110.         true)
  111. #define async_msg_3(phone, method, arg1, arg2, arg3) \
  112.     ipc_call_async_3((phone), (method), (arg1), (arg2), (arg3), NULL, NULL, \
  113.         true)
  114. #define async_msg_4(phone, method, arg1, arg2, arg3, arg4) \
  115.     ipc_call_async_4((phone), (method), (arg1), (arg2), (arg3), (arg4), NULL, \
  116.         NULL, true)
  117. #define async_msg_5(phone, method, arg1, arg2, arg3, arg4, arg5) \
  118.     ipc_call_async_5((phone), (method), (arg1), (arg2), (arg3), (arg4), \
  119.         (arg5), NULL, NULL, true)
  120.  
  121. /*
  122.  * User-friendly wrappers for async_req_fast() and async_req_slow(). The macros
  123.  * are in the form async_req_m_n(), where m is the number of payload arguments
  124.  * and n is the number of return arguments. The macros decide between the fast
  125.  * and slow verion based on m.
  126.  */
  127. #define async_req_0_0(phoneid, method) \
  128.     async_req_fast((phoneid), (method), 0, 0, 0, 0, NULL, NULL, NULL, NULL, \
  129.         NULL)
  130. #define async_req_0_1(phoneid, method, r1) \
  131.     async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), NULL, NULL, NULL, \
  132.         NULL)
  133. #define async_req_0_2(phoneid, method, r1, r2) \
  134.     async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), NULL, NULL, \
  135.         NULL)
  136. #define async_req_0_3(phoneid, method, r1, r2, r3) \
  137.     async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), NULL, \
  138.         NULL)
  139. #define async_req_0_4(phoneid, method, r1, r2, r3, r4) \
  140.     async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
  141.         NULL)
  142. #define async_req_0_5(phoneid, method, r1, r2, r3, r4, r5) \
  143.     async_req_fast((phoneid), (method), 0, 0, 0, 0, (r1), (r2), (r3), (r4), \
  144.         (r5))
  145. #define async_req_1_0(phoneid, method, arg1) \
  146.     async_req_fast((phoneid), (method), (arg1), 0, 0, 0, NULL, NULL, NULL, \
  147.         NULL, NULL)
  148. #define async_req_1_1(phoneid, method, arg1, rc1) \
  149.     async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), NULL, NULL, \
  150.         NULL, NULL)
  151. #define async_req_1_2(phoneid, method, arg1, rc1, rc2) \
  152.     async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), NULL, \
  153.         NULL, NULL)
  154. #define async_req_1_3(phoneid, method, arg1, rc1, rc2, rc3) \
  155.     async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
  156.         NULL, NULL)
  157. #define async_req_1_4(phoneid, method, arg1, rc1, rc2, rc3, rc4) \
  158.     async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
  159.         (rc4), NULL)
  160. #define async_req_1_5(phoneid, method, arg1, rc1, rc2, rc3, rc4, rc5) \
  161.     async_req_fast((phoneid), (method), (arg1), 0, 0, 0, (rc1), (rc2), (rc3), \
  162.         (rc4), (rc5))
  163. #define async_req_2_0(phoneid, method, arg1, arg2) \
  164.     async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, NULL, NULL, \
  165.         NULL, NULL, NULL)
  166. #define async_req_2_1(phoneid, method, arg1, arg2, rc1) \
  167.     async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), NULL, \
  168.         NULL, NULL, NULL)
  169. #define async_req_2_2(phoneid, method, arg1, arg2, rc1, rc2) \
  170.     async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
  171.         NULL, NULL, NULL)
  172. #define async_req_2_3(phoneid, method, arg1, arg2, rc1, rc2, rc3) \
  173.     async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
  174.         (rc3), NULL, NULL)
  175. #define async_req_2_4(phoneid, method, arg1, arg2, rc1, rc2, rc3, rc4) \
  176.     async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
  177.         (rc3), (rc4), NULL)
  178. #define async_req_2_5(phoneid, method, arg1, arg2, rc1, rc2, rc3, rc4, rc5) \
  179.     async_req_fast((phoneid), (method), (arg1), (arg2), 0, 0, (rc1), (rc2), \
  180.         (rc3), (rc4), (rc5))
  181. #define async_req_3_0(phoneid, method, arg1, arg2, arg3) \
  182.     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, NULL, NULL, \
  183.         NULL, NULL, NULL)
  184. #define async_req_3_1(phoneid, method, arg1, arg2, arg3, rc1) \
  185.     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
  186.         NULL, NULL, NULL, NULL)
  187. #define async_req_3_2(phoneid, method, arg1, arg2, arg3, rc1, rc2) \
  188.     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
  189.         (rc2), NULL, NULL, NULL)
  190. #define async_req_3_3(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3) \
  191.     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
  192.         (rc2), (rc3), NULL, NULL)
  193. #define async_req_3_4(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4) \
  194.     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
  195.         (rc2), (rc3), (rc4), NULL)
  196. #define async_req_3_5(phoneid, method, arg1, arg2, arg3, rc1, rc2, rc3, rc4, \
  197.     rc5) \
  198.     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, (rc1), \
  199.         (rc2), (rc3), (rc4), (rc5))
  200. #define async_req_4_0(phoneid, method, arg1, arg2, arg3, arg4) \
  201.     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), NULL, \
  202.         NULL, NULL, NULL, NULL)
  203. #define async_req_4_1(phoneid, method, arg1, arg2, arg3, arg4, rc1) \
  204.     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
  205.         NULL, NULL, NULL, NULL)
  206. #define async_req_4_2(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2) \
  207.     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
  208.         (rc2), NULL, NULL, NULL)
  209. #define async_req_4_3(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3) \
  210.     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), (rc1), \
  211.         (rc2), (rc3), NULL, NULL)
  212. #define async_req_4_4(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
  213.     rc4) \
  214.     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
  215.         (rc1), (rc2), (rc3), (rc4), NULL)
  216. #define async_req_4_5(phoneid, method, arg1, arg2, arg3, arg4, rc1, rc2, rc3, \
  217.     rc4, rc5) \
  218.     async_req_fast((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
  219.         (rc1), (rc2), (rc3), (rc4), (rc5))
  220. #define async_req_5_0(phoneid, method, arg1, arg2, arg3, arg4, arg5) \
  221.     async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
  222.         (arg5), NULL, NULL, NULL, NULL, NULL)
  223. #define async_req_5_1(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1) \
  224.     async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
  225.         (arg5), (rc1), NULL, NULL, NULL, NULL)
  226. #define async_req_5_2(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2) \
  227.     async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
  228.         (arg5), (rc1), (rc2), NULL, NULL, NULL)
  229. #define async_req_5_3(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
  230.     rc3) \
  231.     async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
  232.         (arg5), (rc1), (rc2), (rc3), NULL, NULL)
  233. #define async_req_5_4(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
  234.     rc3, rc4) \
  235.     async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
  236.         (arg5), (rc1), (rc2), (rc3), (rc4), NULL)
  237. #define async_req_5_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, rc1, rc2, \
  238.     rc3, rc4, rc5) \
  239.     async_req_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \
  240.         (arg5), (rc1), (rc2), (rc3), (rc4), (rc5))
  241.  
  242. extern ipcarg_t async_req_fast(int phoneid, ipcarg_t method, ipcarg_t arg1,
  243.     ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t *r1, ipcarg_t *r2,
  244.     ipcarg_t *r3, ipcarg_t *r4, ipcarg_t *r5);
  245. extern ipcarg_t async_req_slow(int phoneid, ipcarg_t method, ipcarg_t arg1,
  246.     ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, ipcarg_t *r1,
  247.     ipcarg_t *r2, ipcarg_t *r3, ipcarg_t *r4, ipcarg_t *r5);
  248.  
  249. static inline void async_serialize_start(void)
  250. {
  251.     fibril_inc_sercount();
  252. }
  253.  
  254. static inline void async_serialize_end(void)
  255. {
  256.     fibril_dec_sercount();
  257. }
  258.  
  259. #endif
  260.  
  261. /** @}
  262.  */
  263.