Changeset 01ff41c in mainline for libc/generic/async.c
- Timestamp:
- 2006-05-27T22:28:25Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7f5b37a
- Parents:
- 7f9cd77
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libc/generic/async.c
r7f9cd77 r01ff41c 92 92 #include <errno.h> 93 93 94 static atomic_t conn_futex = FUTEX_INITIALIZER;94 static atomic_t async_futex = FUTEX_INITIALIZER; 95 95 static hash_table_t conn_hash_table; 96 97 typedef struct { 98 pstid_t ptid; /**< Thread waiting for this message */ 99 int active; /**< If this thread is currently active */ 100 int done; /**< If reply was received */ 101 ipc_call_t *dataptr; /**< Pointer where the answer data 102 * should be stored */ 103 ipcarg_t retval; 104 } amsg_t; 96 105 97 106 typedef struct { … … 116 125 117 126 /* Hash table functions */ 118 119 127 #define CONN_HASH_TABLE_CHAINS 32 120 128 … … 147 155 }; 148 156 157 /*************************************************/ 158 149 159 /** Try to route a call to an appropriate connection thread 150 160 * … … 157 167 unsigned long key; 158 168 159 futex_down(& conn_futex);169 futex_down(&async_futex); 160 170 161 171 key = call->in_phone_hash; 162 172 hlp = hash_table_find(&conn_hash_table, &key); 163 173 if (!hlp) { 164 futex_up(& conn_futex);174 futex_up(&async_futex); 165 175 return 0; 166 176 } … … 177 187 } 178 188 179 futex_up(& conn_futex);189 futex_up(&async_futex); 180 190 181 191 return 1; … … 189 199 connection_t *conn; 190 200 191 futex_down(& conn_futex);201 futex_down(&async_futex); 192 202 193 203 conn = PS_connection; … … 204 214 free(msg); 205 215 206 futex_up(& conn_futex);216 futex_up(&async_futex); 207 217 return callid; 208 218 } … … 237 247 238 248 /* Remove myself from connection hash table */ 239 futex_down(& conn_futex);249 futex_down(&async_futex); 240 250 key = conn->in_phone_hash; 241 251 hash_table_remove(&conn_hash_table, &key, 1); 242 futex_up(& conn_futex);252 futex_up(&async_futex); 243 253 /* Answer all remaining messages with ehangup */ 244 254 while (!list_empty(&conn->msg_queue)) { … … 289 299 } 290 300 key = conn->in_phone_hash; 291 futex_down(& conn_futex);301 futex_down(&async_futex); 292 302 /* Add connection to hash table */ 293 303 hash_table_insert(&conn_hash_table, &key, &conn->link); 294 futex_up(& conn_futex);304 futex_up(&async_futex); 295 305 296 306 psthread_add_ready(conn->ptid); … … 299 309 } 300 310 301 /** Handle call t o a task*/311 /** Handle call that was received */ 302 312 static void handle_call(ipc_callid_t callid, ipc_call_t *call) 303 313 { … … 325 335 while (1) { 326 336 if (psthread_schedule_next_adv(PS_FROM_MANAGER)) { 327 futex_up(& conn_futex); /* conn_futex is always held337 futex_up(&async_futex); /* async_futex is always held 328 338 * when entering manager thread 329 339 */ … … 334 344 if (callid & IPC_CALLID_ANSWERED) 335 345 continue; 346 336 347 handle_call(callid, &call); 337 348 } … … 347 358 static int async_manager_thread(void *arg) 348 359 { 349 futex_up(& conn_futex); /* conn_futex is always locked when entering360 futex_up(&async_futex); /* async_futex is always locked when entering 350 361 * manager */ 351 362 async_manager(); … … 376 387 377 388 } 389 390 /** IPC handler for messages in async framework 391 * 392 * Notify thread that is waiting for this message, that it arrived 393 */ 394 static void reply_received(void *private, int retval, 395 ipc_call_t *data) 396 { 397 amsg_t *msg = (amsg_t *) private; 398 399 msg->retval = retval; 400 401 futex_down(&async_futex); 402 /* Copy data after futex_down, just in case the 403 * call was detached 404 */ 405 if (msg->dataptr) 406 *msg->dataptr = *data; 407 408 msg->done = 1; 409 if (! msg->active) { 410 msg->active = 1; 411 psthread_add_ready(msg->ptid); 412 } 413 futex_up(&async_futex); 414 } 415 416 /** Send message and return id of the sent message 417 * 418 * The return value can be used as input for async_wait() to wait 419 * for completion. 420 */ 421 aid_t async_send_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2, 422 ipc_call_t *dataptr) 423 { 424 amsg_t *msg; 425 426 msg = malloc(sizeof(*msg)); 427 msg->active = 1; 428 msg->done = 0; 429 msg->dataptr = dataptr; 430 ipc_call_async_2(phoneid,method,arg1,arg2,msg,reply_received); 431 432 return (aid_t) msg; 433 } 434 435 /** Wait for a message sent by async framework 436 * 437 * @param amsgid Message ID to wait for 438 * @param retval Pointer to variable where will be stored retval 439 * of the answered message. If NULL, it is ignored. 440 * 441 */ 442 void async_wait_for(aid_t amsgid, ipcarg_t *retval) 443 { 444 amsg_t *msg = (amsg_t *) amsgid; 445 connection_t *conn; 446 447 futex_down(&async_futex); 448 if (msg->done) { 449 futex_up(&async_futex); 450 goto done; 451 } 452 453 msg->ptid = psthread_get_id(); 454 msg->active = 0; 455 /* Leave locked async_futex when entering this function */ 456 psthread_schedule_next_adv(PS_TO_MANAGER); 457 /* futex is up automatically after psthread_schedule_next...*/ 458 done: 459 if (retval) 460 *retval = msg->retval; 461 free(msg); 462 }
Note:
See TracChangeset
for help on using the changeset viewer.