Changes in / [ac307b2:0851a3d] in mainline
- Files:
-
- 1 deleted
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
abi/include/abi/ipc/methods.h
rac307b2 r0851a3d 36 36 #define ABI_IPC_METHODS_H_ 37 37 38 #include <abi/cap.h>39 40 38 /* Well known phone descriptors */ 41 #define PHONE_NS (CAP_NIL + 1)39 #define PHONE_NS 0 42 40 43 41 /** Kernel IPC interfaces -
kernel/generic/include/cap/cap.h
rac307b2 r0851a3d 53 53 54 54 typedef enum { 55 KOBJECT_TYPE_ CALL,55 KOBJECT_TYPE_PHONE, 56 56 KOBJECT_TYPE_IRQ, 57 KOBJECT_TYPE_PHONE,58 57 KOBJECT_TYPE_MAX 59 58 } kobject_type_t; 60 59 61 60 struct task; 62 63 struct call; 61 struct phone; 64 62 struct irq; 65 struct phone;66 63 67 64 struct kobject; … … 82 79 union { 83 80 void *raw; 84 struct call *call;81 struct phone *phone; 85 82 struct irq *irq; 86 struct phone *phone;87 83 }; 88 84 } kobject_t; -
kernel/generic/include/ipc/ipc.h
rac307b2 r0851a3d 106 106 /** Phone which made or last masqueraded this call. */ 107 107 phone_t *phone; 108 /** Flags */109 unsigned flags;110 /** User-defined label */111 sysarg_t label;112 108 } ipc_data_t; 113 109 114 110 typedef struct { 115 kobject_t *kobject;116 117 111 /** 118 112 * Task link. … … 121 115 */ 122 116 link_t ta_link; 117 118 atomic_t refcnt; 123 119 124 120 /** Answerbox link. */ -
kernel/generic/include/ipc/sysipc.h
rac307b2 r0851a3d 44 44 extern sysarg_t sys_ipc_call_async_fast(sysarg_t, sysarg_t, sysarg_t, 45 45 sysarg_t, sysarg_t, sysarg_t); 46 extern sysarg_t sys_ipc_call_async_slow(sysarg_t, ipc_data_t * , sysarg_t);46 extern sysarg_t sys_ipc_call_async_slow(sysarg_t, ipc_data_t *); 47 47 extern sysarg_t sys_ipc_answer_fast(sysarg_t, sysarg_t, sysarg_t, sysarg_t, 48 48 sysarg_t, sysarg_t); -
kernel/generic/src/cap/cap.c
rac307b2 r0851a3d 73 73 74 74 #include <cap/cap.h> 75 #include <abi/cap.h>76 75 #include <proc/task.h> 77 76 #include <synch/mutex.h> … … 82 81 #include <stdint.h> 83 82 84 #define CAPS_START (CAP_NIL + 1) 85 #define CAPS_SIZE (INT_MAX - CAPS_START) 86 #define CAPS_LAST (CAPS_SIZE - 1) 83 #define MAX_CAPS INT_MAX 87 84 88 85 static slab_cache_t *cap_slab; … … 132 129 if (!task->cap_info->handles) 133 130 goto error_handles; 134 if (!ra_span_add(task->cap_info->handles, CAPS_START, CAPS_SIZE))131 if (!ra_span_add(task->cap_info->handles, 0, MAX_CAPS)) 135 132 goto error_span; 136 133 if (!hash_table_create(&task->cap_info->caps, 0, 0, &caps_ops)) … … 223 220 assert(mutex_locked(&task->cap_info->lock)); 224 221 225 if ((handle < CAPS_START) || (handle > CAPS_LAST))222 if ((handle < 0) || (handle >= MAX_CAPS)) 226 223 return NULL; 227 224 ht_link_t *link = hash_table_find(&task->cap_info->caps, &handle); … … 360 357 void cap_free(task_t *task, cap_handle_t handle) 361 358 { 362 assert(handle >= CAPS_START);363 assert(handle < = CAPS_LAST);359 assert(handle >= 0); 360 assert(handle < MAX_CAPS); 364 361 365 362 mutex_lock(&task->cap_info->lock); -
kernel/generic/src/ipc/ipc.c
rac307b2 r0851a3d 87 87 } 88 88 89 static void call_destroy(void *arg) 90 { 91 call_t *call = (call_t *) arg; 92 93 if (call->buffer) 94 free(call->buffer); 95 if (call->caller_phone) 96 kobject_put(call->caller_phone->kobject); 97 slab_free(call_slab, call); 98 } 99 100 static kobject_ops_t call_kobject_ops = { 101 .destroy = call_destroy 102 }; 89 void ipc_call_hold(call_t *call) 90 { 91 atomic_inc(&call->refcnt); 92 } 93 94 void ipc_call_release(call_t *call) 95 { 96 if (atomic_predec(&call->refcnt) == 0) { 97 if (call->buffer) 98 free(call->buffer); 99 if (call->caller_phone) 100 kobject_put(call->caller_phone->kobject); 101 slab_free(call_slab, call); 102 } 103 } 103 104 104 105 /** Allocate and initialize a call structure. … … 116 117 { 117 118 call_t *call = slab_alloc(call_slab, flags); 118 if (!call) 119 return NULL; 120 kobject_t *kobj = (kobject_t *) malloc(sizeof(kobject_t), flags); 121 if (!kobj) { 122 slab_free(call_slab, call); 123 return NULL; 124 } 125 126 _ipc_call_init(call); 127 kobject_initialize(kobj, KOBJECT_TYPE_CALL, call, &call_kobject_ops); 128 call->kobject = kobj; 119 if (call) { 120 _ipc_call_init(call); 121 ipc_call_hold(call); 122 } 129 123 130 124 return call; 125 } 126 127 /** Deallocate a call structure. 128 * 129 * @param call Call structure to be freed. 130 * 131 */ 132 void ipc_call_free(call_t *call) 133 { 134 ipc_call_release(call); 131 135 } 132 136 … … 286 290 /* This is a forgotten call and call->sender is not valid. */ 287 291 spinlock_unlock(&call->forget_lock); 288 kobject_put(call->kobject);292 ipc_call_free(call); 289 293 return; 290 294 } else { … … 701 705 * must hold a reference to it. 702 706 */ 703 kobject_add_ref(call->kobject);707 ipc_call_hold(call); 704 708 705 709 spinlock_unlock(&call->forget_lock); … … 710 714 SYSIPC_OP(request_forget, call); 711 715 712 kobject_put(call->kobject);716 ipc_call_release(call); 713 717 } 714 718 … … 818 822 SYSIPC_OP(answer_process, call); 819 823 820 kobject_put(call->kobject);824 ipc_call_free(call); 821 825 goto restart; 822 826 } -
kernel/generic/src/ipc/sysipc.c
rac307b2 r0851a3d 286 286 #endif 287 287 288 kobject_add_ref(call->kobject);288 ipc_call_hold(call); 289 289 rc = ipc_call_sync(kobj->phone, call); 290 290 spinlock_lock(&call->forget_lock); 291 291 bool forgotten = call->forget; 292 292 spinlock_unlock(&call->forget_lock); 293 kobject_put(call->kobject);293 ipc_call_release(call); 294 294 295 295 #ifdef CONFIG_UDEBUG … … 306 306 * deallocation. 307 307 */ 308 kobject_put(call->kobject);308 ipc_call_free(call); 309 309 } else { 310 310 /* … … 323 323 324 324 memcpy(data->args, call->data.args, sizeof(data->args)); 325 kobject_put(call->kobject);325 ipc_call_free(call); 326 326 kobject_put(kobj); 327 327 … … 347 347 /** Make a fast asynchronous call over IPC. 348 348 * 349 * This function can only handle threearguments of payload, but is faster than349 * This function can only handle four arguments of payload, but is faster than 350 350 * the generic function sys_ipc_call_async_slow(). 351 351 * … … 355 355 * @param arg2 Service-defined payload argument. 356 356 * @param arg3 Service-defined payload argument. 357 * @param label User-defined label.357 * @param arg4 Service-defined payload argument. 358 358 * 359 359 * @return Call hash on success. … … 362 362 */ 363 363 sysarg_t sys_ipc_call_async_fast(sysarg_t handle, sysarg_t imethod, 364 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t label)364 sysarg_t arg1, sysarg_t arg2, sysarg_t arg3, sysarg_t arg4) 365 365 { 366 366 kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE); … … 378 378 IPC_SET_ARG2(call->data, arg2); 379 379 IPC_SET_ARG3(call->data, arg3); 380 IPC_SET_ARG4(call->data, arg4); 380 381 381 382 /* … … 384 385 */ 385 386 IPC_SET_ARG5(call->data, 0); 386 387 /* Set the user-defined label */388 call->data.label = label;389 387 390 388 int res = request_preprocess(call, kobj->phone); … … 403 401 * @param handle Phone capability for the call. 404 402 * @param data Userspace address of call data with the request. 405 * @param label User-defined label.406 403 * 407 404 * @return See sys_ipc_call_async_fast(). 408 405 * 409 406 */ 410 sysarg_t sys_ipc_call_async_slow(sysarg_t handle, ipc_data_t *data, 411 sysarg_t label) 407 sysarg_t sys_ipc_call_async_slow(sysarg_t handle, ipc_data_t *data) 412 408 { 413 409 kobject_t *kobj = kobject_get(TASK, handle, KOBJECT_TYPE_PHONE); … … 424 420 sizeof(call->data.args)); 425 421 if (rc != 0) { 426 kobject_put(call->kobject);422 ipc_call_free(call); 427 423 kobject_put(kobj); 428 424 return (sysarg_t) rc; 429 425 } 430 431 /* Set the user-defined label */432 call->data.label = label;433 426 434 427 int res = request_preprocess(call, kobj->phone); … … 728 721 * 729 722 * @return Hash of the call. 723 * If IPC_CALLID_NOTIFICATION bit is set in the hash, the 724 * call is a notification. IPC_CALLID_ANSWERED denotes an 725 * answer. 726 * 730 727 */ 731 728 sysarg_t sys_ipc_wait_for_call(ipc_data_t *calldata, uint32_t usec, … … 754 751 call->data.phone = (void *) call->priv; 755 752 756 call->data.flags = IPC_CALLID_NOTIFICATION;757 758 753 STRUCT_TO_USPACE(calldata, &call->data); 759 kobject_put(call->kobject);760 754 761 return (sysarg_t) call; 755 ipc_call_free(call); 756 757 return ((sysarg_t) call) | IPC_CALLID_NOTIFICATION; 762 758 } 763 759 … … 766 762 767 763 if (call->flags & IPC_CALL_DISCARD_ANSWER) { 768 kobject_put(call->kobject);764 ipc_call_free(call); 769 765 goto restart; 770 766 } 771 772 call->data.flags = IPC_CALLID_ANSWERED;773 767 774 768 STRUCT_TO_USPACE(calldata, &call->data); 775 kobject_put(call->kobject);769 ipc_call_free(call); 776 770 777 return ( sysarg_t) call;771 return ((sysarg_t) call) | IPC_CALLID_ANSWERED; 778 772 } 779 773 -
uspace/app/trace/ipcp.c
rac307b2 r0851a3d 323 323 pending_call_t *pcall; 324 324 325 if ((call->flags & IPC_CALLID_ANSWERED) == 0 && 326 hash != IPCP_CALLID_SYNC) { 325 if ((hash & IPC_CALLID_ANSWERED) == 0 && hash != IPCP_CALLID_SYNC) { 327 326 /* Not a response */ 328 327 if ((display_mask & DM_IPC) != 0) { … … 332 331 } 333 332 333 hash = hash & ~IPC_CALLID_ANSWERED; 334 334 335 item = hash_table_find(&pending_calls, &hash); 335 336 if (item == NULL) -
uspace/app/trace/syscalls.c
rac307b2 r0851a3d 54 54 55 55 [SYS_IPC_CALL_ASYNC_FAST] = { "ipc_call_async_fast", 6, V_HASH }, 56 [SYS_IPC_CALL_ASYNC_SLOW] = { "ipc_call_async_slow", 3, V_HASH },56 [SYS_IPC_CALL_ASYNC_SLOW] = { "ipc_call_async_slow", 2, V_HASH }, 57 57 58 58 [SYS_IPC_ANSWER_FAST] = { "ipc_answer_fast", 6, V_ERRNO }, -
uspace/lib/c/generic/async.c
rac307b2 r0851a3d 1341 1341 1342 1342 /* Kernel notification */ 1343 if ( call->flags & IPC_CALLID_NOTIFICATION) {1343 if ((callid & IPC_CALLID_NOTIFICATION)) { 1344 1344 fibril_t *fibril = (fibril_t *) __tcb_get()->fibril_data; 1345 1345 unsigned oldsw = fibril->switches; … … 1495 1495 } 1496 1496 1497 if (call .flags& IPC_CALLID_ANSWERED)1497 if (callid & IPC_CALLID_ANSWERED) 1498 1498 continue; 1499 1499 -
uspace/lib/c/generic/ipc.c
rac307b2 r0851a3d 1 1 /* 2 2 * Copyright (c) 2006 Ondrej Palkovsky 3 * Copyright (c) 2017 Jakub Jermar4 3 * All rights reserved. 5 4 * … … 51 50 52 51 /** 53 * Structures of this type are used for keeping track of sent asynchronous calls. 54 */ 55 typedef struct async_call { 52 * Structures of this type are used for keeping track 53 * of sent asynchronous calls and queing unsent calls. 54 */ 55 typedef struct { 56 link_t list; 57 56 58 ipc_async_callback_t callback; 57 59 void *private; 58 60 59 struct { 60 ipc_call_t data; 61 int phoneid; 62 } msg; 61 union { 62 ipc_callid_t callid; 63 struct { 64 ipc_call_t data; 65 int phoneid; 66 } msg; 67 } u; 68 69 /** Fibril waiting for sending this call. */ 70 fid_t fid; 63 71 } async_call_t; 72 73 LIST_INITIALIZE(dispatched_calls); 74 75 /** List of asynchronous calls that were not accepted by kernel. 76 * 77 * Protected by async_futex, because if the call is not accepted 78 * by the kernel, the async framework is used automatically. 79 * 80 */ 81 LIST_INITIALIZE(queued_calls); 82 83 static futex_t ipc_futex = FUTEX_INITIALIZER; 84 85 /** Send asynchronous message via syscall. 86 * 87 * @param phoneid Phone handle for the call. 88 * @param data Call data with the request. 89 * 90 * @return Hash of the call or an error code. 91 * 92 */ 93 static ipc_callid_t ipc_call_async_internal(int phoneid, ipc_call_t *data) 94 { 95 return __SYSCALL2(SYS_IPC_CALL_ASYNC_SLOW, phoneid, (sysarg_t) data); 96 } 64 97 65 98 /** Prologue for ipc_call_async_*() functions. … … 100 133 if (!call) { 101 134 /* Nothing to do regardless if failed or not */ 135 futex_unlock(&ipc_futex); 102 136 return; 103 137 } 104 138 105 139 if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) { 140 futex_unlock(&ipc_futex); 141 106 142 /* Call asynchronous handler with error code */ 107 143 if (call->callback) … … 111 147 return; 112 148 } 149 150 call->u.callid = callid; 151 152 /* Add call to the list of dispatched calls */ 153 list_append(&call->list, &dispatched_calls); 154 futex_unlock(&ipc_futex); 113 155 } 114 156 115 157 /** Fast asynchronous call. 116 158 * 117 * This function can only handle threearguments of payload. It is, however,159 * This function can only handle four arguments of payload. It is, however, 118 160 * faster than the more generic ipc_call_async_slow(). 119 161 * … … 129 171 * @param arg2 Service-defined payload argument. 130 172 * @param arg3 Service-defined payload argument. 173 * @param arg4 Service-defined payload argument. 131 174 * @param private Argument to be passed to the answer/error callback. 132 175 * @param callback Answer or error callback. 133 176 */ 134 177 void ipc_call_async_fast(int phoneid, sysarg_t imethod, sysarg_t arg1, 135 sysarg_t arg2, sysarg_t arg3, void *private, ipc_async_callback_t callback) 136 { 137 async_call_t *call = ipc_prepare_async(private, callback); 138 if (!call) 139 return; 140 178 sysarg_t arg2, sysarg_t arg3, sysarg_t arg4, void *private, 179 ipc_async_callback_t callback) 180 { 181 async_call_t *call = NULL; 182 183 if (callback) { 184 call = ipc_prepare_async(private, callback); 185 if (!call) 186 return; 187 } 188 189 /* 190 * We need to make sure that we get callid 191 * before another thread accesses the queue again. 192 */ 193 194 futex_lock(&ipc_futex); 141 195 ipc_callid_t callid = __SYSCALL6(SYS_IPC_CALL_ASYNC_FAST, phoneid, 142 imethod, arg1, arg2, arg3, (sysarg_t) call);196 imethod, arg1, arg2, arg3, arg4); 143 197 144 198 ipc_finish_async(callid, phoneid, call); … … 171 225 return; 172 226 173 IPC_SET_IMETHOD(call->msg.data, imethod); 174 IPC_SET_ARG1(call->msg.data, arg1); 175 IPC_SET_ARG2(call->msg.data, arg2); 176 IPC_SET_ARG3(call->msg.data, arg3); 177 IPC_SET_ARG4(call->msg.data, arg4); 178 IPC_SET_ARG5(call->msg.data, arg5); 179 180 ipc_callid_t callid = __SYSCALL3(SYS_IPC_CALL_ASYNC_SLOW, phoneid, 181 (sysarg_t) &call->msg.data, (sysarg_t) call); 227 IPC_SET_IMETHOD(call->u.msg.data, imethod); 228 IPC_SET_ARG1(call->u.msg.data, arg1); 229 IPC_SET_ARG2(call->u.msg.data, arg2); 230 IPC_SET_ARG3(call->u.msg.data, arg3); 231 IPC_SET_ARG4(call->u.msg.data, arg4); 232 IPC_SET_ARG5(call->u.msg.data, arg5); 233 234 /* 235 * We need to make sure that we get callid 236 * before another threadaccesses the queue again. 237 */ 238 239 futex_lock(&ipc_futex); 240 ipc_callid_t callid = 241 ipc_call_async_internal(phoneid, &call->u.msg.data); 182 242 183 243 ipc_finish_async(callid, phoneid, call); … … 236 296 } 237 297 298 /** Try to dispatch queued calls from the async queue. 299 * 300 */ 301 static void dispatch_queued_calls(void) 302 { 303 /** @todo 304 * Integrate intelligently ipc_futex so that it is locked during 305 * ipc_call_async_*() until it is added to dispatched_calls. 306 */ 307 308 futex_down(&async_futex); 309 310 while (!list_empty(&queued_calls)) { 311 async_call_t *call = 312 list_get_instance(list_first(&queued_calls), async_call_t, list); 313 ipc_callid_t callid = 314 ipc_call_async_internal(call->u.msg.phoneid, &call->u.msg.data); 315 316 list_remove(&call->list); 317 318 futex_up(&async_futex); 319 320 assert(call->fid); 321 fibril_add_ready(call->fid); 322 323 if (callid == (ipc_callid_t) IPC_CALLRET_FATAL) { 324 if (call->callback) 325 call->callback(call->private, ENOENT, NULL); 326 327 free(call); 328 } else { 329 call->u.callid = callid; 330 331 futex_lock(&ipc_futex); 332 list_append(&call->list, &dispatched_calls); 333 futex_unlock(&ipc_futex); 334 } 335 336 futex_down(&async_futex); 337 } 338 339 futex_up(&async_futex); 340 } 341 238 342 /** Handle received answer. 343 * 344 * Find the hash of the answer and call the answer callback. 345 * 346 * The answer has the same hash as the request OR'ed with 347 * the IPC_CALLID_ANSWERED bit. 348 * 349 * @todo Use hash table. 239 350 * 240 351 * @param callid Hash of the received answer. 241 352 * @param data Call data of the answer. 353 * 242 354 */ 243 355 static void handle_answer(ipc_callid_t callid, ipc_call_t *data) 244 356 { 245 async_call_t *call = data->label; 246 247 if (!call) 248 return; 249 250 if (call->callback) 251 call->callback(call->private, IPC_GET_RETVAL(*data), data); 252 free(call); 357 callid &= ~IPC_CALLID_ANSWERED; 358 359 futex_lock(&ipc_futex); 360 361 link_t *item; 362 for (item = dispatched_calls.head.next; item != &dispatched_calls.head; 363 item = item->next) { 364 async_call_t *call = 365 list_get_instance(item, async_call_t, list); 366 367 if (call->u.callid == callid) { 368 list_remove(&call->list); 369 370 futex_unlock(&ipc_futex); 371 372 if (call->callback) 373 call->callback(call->private, 374 IPC_GET_RETVAL(*data), data); 375 376 free(call); 377 return; 378 } 379 } 380 381 futex_unlock(&ipc_futex); 253 382 } 254 383 … … 259 388 * @param flags Flags passed to SYS_IPC_WAIT (blocking, nonblocking). 260 389 * 261 * @return Hash of the call. 390 * @return Hash of the call. Note that certain bits have special 391 * meaning: IPC_CALLID_ANSWERED is set in an answer 392 * and IPC_CALLID_NOTIFICATION is used for notifications. 393 * 262 394 */ 263 395 ipc_callid_t ipc_wait_cycle(ipc_call_t *call, sysarg_t usec, … … 268 400 269 401 /* Handle received answers */ 270 if (callid & & (call->flags & IPC_CALLID_ANSWERED))402 if (callid & IPC_CALLID_ANSWERED) { 271 403 handle_answer(callid, call); 404 dispatch_queued_calls(); 405 } 272 406 273 407 return callid; … … 298 432 do { 299 433 callid = ipc_wait_cycle(call, usec, SYNCH_FLAGS_NONE); 300 } while (callid & & (call->flags & IPC_CALLID_ANSWERED));434 } while (callid & IPC_CALLID_ANSWERED); 301 435 302 436 return callid; … … 319 453 callid = ipc_wait_cycle(call, SYNCH_NO_TIMEOUT, 320 454 SYNCH_FLAGS_NON_BLOCKING); 321 } while (callid & & (call->flags & IPC_CALLID_ANSWERED));455 } while (callid & IPC_CALLID_ANSWERED); 322 456 323 457 return callid; -
uspace/lib/c/include/ipc/common.h
rac307b2 r0851a3d 43 43 #define IPC_FLAG_BLOCKING 0x01 44 44 45 struct async_call;46 47 45 typedef struct { 48 46 sysarg_t args[IPC_CALL_LEN]; 49 47 task_id_t in_task_id; 50 48 sysarg_t in_phone_hash; 51 unsigned flags;52 struct async_call *label;53 49 } ipc_call_t; 54 50 -
uspace/lib/c/include/ipc/ipc.h
rac307b2 r0851a3d 89 89 90 90 #define ipc_call_async_0(phoneid, method, private, callback) \ 91 ipc_call_async_fast((phoneid), (method), 0, 0, 0, (private), (callback)) 91 ipc_call_async_fast((phoneid), (method), 0, 0, 0, 0, (private), \ 92 (callback)) 92 93 #define ipc_call_async_1(phoneid, method, arg1, private, callback) \ 93 ipc_call_async_fast((phoneid), (method), (arg1), 0, 0, (private), \94 ipc_call_async_fast((phoneid), (method), (arg1), 0, 0, 0, (private), \ 94 95 (callback)) 95 96 #define ipc_call_async_2(phoneid, method, arg1, arg2, private, callback) \ 96 ipc_call_async_fast((phoneid), (method), (arg1), (arg2), 0, \97 ipc_call_async_fast((phoneid), (method), (arg1), (arg2), 0, 0, \ 97 98 (private), (callback)) 98 99 #define ipc_call_async_3(phoneid, method, arg1, arg2, arg3, private, callback) \ 99 ipc_call_async_fast((phoneid), (method), (arg1), (arg2), (arg3), \100 ipc_call_async_fast((phoneid), (method), (arg1), (arg2), (arg3), 0, \ 100 101 (private), (callback)) 101 102 #define ipc_call_async_4(phoneid, method, arg1, arg2, arg3, arg4, private, \ 102 103 callback) \ 103 ipc_call_async_ slow((phoneid), (method), (arg1), (arg2), (arg3), \104 (arg4), 0,(private), (callback))104 ipc_call_async_fast((phoneid), (method), (arg1), (arg2), (arg3), \ 105 (arg4), (private), (callback)) 105 106 #define ipc_call_async_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, \ 106 107 private, callback) \ … … 109 110 110 111 extern void ipc_call_async_fast(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t, 111 void *, ipc_async_callback_t);112 sysarg_t, void *, ipc_async_callback_t); 112 113 extern void ipc_call_async_slow(int, sysarg_t, sysarg_t, sysarg_t, sysarg_t, 113 114 sysarg_t, sysarg_t, void *, ipc_async_callback_t);
Note:
See TracChangeset
for help on using the changeset viewer.