Changeset 01ff41c in mainline
- 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
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
init/init.c
r7f9cd77 r01ff41c 44 44 #include <kbd.h> 45 45 #include <ipc/fb.h> 46 #include <async.h> 46 47 47 48 int a; … … 319 320 } 320 321 322 static void test_async_kbd() 323 { 324 int res; 325 ipcarg_t result; 326 ipc_call_t kbddata; 327 int phoneid; 328 aid_t aid; 329 330 printf("Test: Starting connect...\n"); 331 while ((phoneid = ipc_connect_me_to(PHONE_NS, SERVICE_KEYBOARD, 0)) < 0) { 332 }; 333 334 printf("Test: Connected: %d\n", res); 335 printf("Test: pinging.\n"); 336 while (1) { 337 aid = async_send_2(phoneid, KBD_GETCHAR, 0, 0, &kbddata); 338 async_wait_for(aid, NULL); 339 printf("%c", IPC_GET_ARG1(kbddata)); 340 } 341 342 printf("Test: Hangin up\n"); 343 ipc_hangup(phoneid); 344 } 345 321 346 static void test_pci() 322 347 { … … 393 418 // test_hangup(); 394 419 // test_slam(); 395 test_as_area_send();420 // test_as_area_send(); 396 421 // test_pci(); 397 test_kbd(); 422 // test_kbd(); 423 test_async_kbd(); 398 424 // test_fb(); 399 425 -
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 } -
libc/generic/psthread.c
r7f9cd77 r01ff41c 118 118 /** Schedule next userspace pseudo thread. 119 119 * 120 * If calling with PS_TO_MANAGER parameter, the async_futex should be 121 * held. 122 * 120 123 * @param tomanager If true, we are switching to next ready manager thread 121 124 * (if none is found, thread is exited) … … 137 140 } 138 141 /* If we are going to manager and none exists, create it */ 139 if (ctype == PS_TO_MANAGER && list_empty(&manager_list)) 142 while (ctype == PS_TO_MANAGER && list_empty(&manager_list)) { 143 futex_up(&psthread_futex); 140 144 async_create_manager(); 145 futex_down(&psthread_futex); 146 } 141 147 142 148 pt = __tcb_get()->pst_data; … … 260 266 futex_up(&psthread_futex); 261 267 } 268 269 /** Return thread id of current running thread */ 270 pstid_t psthread_get_id(void) 271 { 272 return (pstid_t)__tcb_get()->pst_data; 273 } -
libc/generic/thread.c
r7f9cd77 r01ff41c 43 43 #endif 44 44 45 static LIST_INITIALIZE(thread_garbage); 45 46 46 47 extern char _tdata_start; … … 146 147 __SYSCALL1(SYS_THREAD_EXIT, (sysarg_t) status); 147 148 } 149 -
libc/include/async.h
r7f9cd77 r01ff41c 4 4 #include <ipc/ipc.h> 5 5 #include <psthread.h> 6 7 typedef ipc_callid_t aid_t; 6 8 7 9 int async_manager(void); … … 11 13 ipc_callid_t async_get_call(ipc_call_t *data); 12 14 13 /* Should be defined by application */14 15 pstid_t async_new_connection(ipc_callid_t callid, ipc_call_t *call, 15 16 void (*cthread)(ipc_callid_t,ipc_call_t *)); 17 aid_t async_send_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2, 18 ipc_call_t *dataptr); 19 void async_wait_for(aid_t amsgid, ipcarg_t *result); 20 21 22 /* Should be defined by application */ 16 23 void client_connection(ipc_callid_t callid, ipc_call_t *call) __attribute__((weak)); 17 24 -
libc/include/psthread.h
r7f9cd77 r01ff41c 75 75 void psthread_add_manager(pstid_t psthrid); 76 76 void psthread_remove_manager(void); 77 pstid_t psthread_get_id(void); 77 78 78 79 static inline int psthread_schedule_next() { -
libc/include/thread.h
r7f9cd77 r01ff41c 39 39 extern int thread_create(void (* function)(void *arg), void *arg, char *name); 40 40 extern void thread_exit(int status); 41 tcb_t * __make_tls(void);42 tcb_t * __alloc_tls(void **data, size_t size);43 void __free_tls(tcb_t *);44 void __free_tls_arch(tcb_t *, size_t size);41 extern tcb_t * __make_tls(void); 42 extern tcb_t * __alloc_tls(void **data, size_t size); 43 extern void __free_tls(tcb_t *); 44 extern void __free_tls_arch(tcb_t *, size_t size); 45 45 46 46 #endif
Note:
See TracChangeset
for help on using the changeset viewer.