Changeset 085bd54 in mainline
- Timestamp:
- 2006-06-06T15:16:08Z (18 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 63bb83e
- Parents:
- d7eafd8
- Files:
-
- 1 deleted
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
console/console.c
rd7eafd8 r085bd54 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 /* TODO: remove */ 29 #include <stdio.h> 28 30 29 31 … … 92 94 static void clrscr(void) 93 95 { 94 nsend_call(fb_info.phone, FB_CLEAR, 0);96 async_msg(fb_info.phone, FB_CLEAR, 0); 95 97 } 96 98 97 99 static void curs_visibility(int v) 98 100 { 99 send_call(fb_info.phone, FB_CURSOR_VISIBILITY, v);101 async_msg(fb_info.phone, FB_CURSOR_VISIBILITY, v); 100 102 } 101 103 102 104 static void curs_goto(int row, int col) 103 105 { 104 nsend_call_2(fb_info.phone, FB_CURSOR_GOTO, row, col);106 async_msg_2(fb_info.phone, FB_CURSOR_GOTO, row, col); 105 107 106 108 } … … 108 110 static void set_style(style_t *style) 109 111 { 110 nsend_call_2(fb_info.phone, FB_SET_STYLE, style->fg_color, style->bg_color);112 async_msg_2(fb_info.phone, FB_SET_STYLE, style->fg_color, style->bg_color); 111 113 } 112 114 113 115 static void set_style_col(int fgcolor, int bgcolor) 114 116 { 115 nsend_call_2(fb_info.phone, FB_SET_STYLE, fgcolor, bgcolor);117 async_msg_2(fb_info.phone, FB_SET_STYLE, fgcolor, bgcolor); 116 118 } 117 119 118 120 static void prtchr(char c, int row, int col) 119 121 { 120 nsend_call_3(fb_info.phone, FB_PUTCHAR, c, row, col);122 async_msg_3(fb_info.phone, FB_PUTCHAR, c, row, col); 121 123 122 124 } … … 166 168 screenbuffer_clear_line(scr, scr->top_line++); 167 169 if (console == active_console) 168 nsend_call(fb_info.phone, FB_SCROLL, 1);170 async_msg(fb_info.phone, FB_SCROLL, 1); 169 171 } 170 172 … … 186 188 187 189 /* Save screen */ 188 newpmap = sync_send(fb_info.phone, FB_VP2PIXMAP, 0, NULL);190 newpmap = async_req(fb_info.phone, FB_VP2PIXMAP, 0, NULL); 189 191 if (newpmap < 0) 190 192 return -1; … … 192 194 if (oldpixmap != -1) { 193 195 /* Show old screen */ 194 nsend_call_2(fb_info.phone, FB_VP_DRAW_PIXMAP, 0, oldpixmap);196 async_msg_2(fb_info.phone, FB_VP_DRAW_PIXMAP, 0, oldpixmap); 195 197 /* Drop old pixmap */ 196 nsend_call(fb_info.phone, FB_DROP_PIXMAP, oldpixmap);198 async_msg(fb_info.phone, FB_DROP_PIXMAP, oldpixmap); 197 199 } 198 200 … … 237 239 console_pixmap = -1; 238 240 } 239 240 241 active_console = newcons; 241 242 gcons_change_console(newcons); … … 245 246 curs_goto(conn->screenbuffer.position_y, conn->screenbuffer.position_x); 246 247 curs_visibility(0); 247 248 248 if (interbuffer) { 249 249 for (i = 0; i < conn->screenbuffer.size_x; i++) … … 251 251 interbuffer[i + j*conn->screenbuffer.size_x] = *get_field_at(&(conn->screenbuffer),i, j); 252 252 /* This call can preempt, but we are already at the end */ 253 j = sync_send_2(fb_info.phone, FB_DRAW_TEXT_DATA, 0, 0, NULL, NULL);253 j = async_req_2(fb_info.phone, FB_DRAW_TEXT_DATA, 0, 0, NULL, NULL); 254 254 }; 255 255 … … 302 302 // if ((c >= KBD_KEY_F1) && (c < KBD_KEY_F1 + CONSOLE_COUNT)) { 303 303 if ((c >= 0x101) && (c < 0x101 + CONSOLE_COUNT)) { 304 async_serialize_start(); 304 305 if (c == 0x112) 305 306 change_console(KERNEL_CONSOLE); 306 307 else 307 308 change_console(c - 0x101); 309 async_serialize_end(); 308 310 break; 309 311 } … … 322 324 default: 323 325 retval = ENOENT; 324 } 326 } 325 327 ipc_answer_fast(callid, retval, 0, 0); 326 328 } … … 341 343 } 342 344 conn = &connections[consnum]; 343 345 conn->used = 1; 346 347 async_serialize_start(); 344 348 gcons_notify_connect(consnum); 345 conn->used = 1;346 349 conn->client_phone = IPC_GET_ARG3(call); 347 350 screenbuffer_clear(&conn->screenbuffer); … … 349 352 /* Accept the connection */ 350 353 ipc_answer_fast(iid,0,0,0); 351 354 352 355 while (1) { 356 async_serialize_end(); 353 357 callid = async_get_call(&call); 358 async_serialize_start(); 359 354 360 arg1 = arg2 = 0; 355 361 switch (IPC_GET_METHOD(call)) { 356 362 case IPC_M_PHONE_HUNGUP: 357 363 gcons_notify_disconnect(consnum); 364 358 365 /* Answer all pending requests */ 359 366 while (conn->keyrequest_counter > 0) { … … 365 372 /* Commit hangup */ 366 373 ipc_answer_fast(callid, 0,0,0); 374 async_serialize_end(); 367 375 return; 368 376 case CONSOLE_PUTCHAR: … … 373 381 /* Send message to fb */ 374 382 if (consnum == active_console) { 375 send_call(fb_info.phone, FB_CLEAR, 0);383 async_msg(fb_info.phone, FB_CLEAR, 0); 376 384 } 377 385 … … 392 400 break; 393 401 case CONSOLE_FLUSH: 394 sync_send_2(fb_info.phone, FB_FLUSH, 0, 0, NULL, NULL);402 async_req_2(fb_info.phone, FB_FLUSH, 0, 0, NULL, NULL); 395 403 break; 396 404 case CONSOLE_SET_STYLE: … … 460 468 gcons_init(fb_info.phone); 461 469 /* Synchronize, the gcons can have something in queue */ 462 sync_send(fb_info.phone, FB_FLUSH, 0, NULL);470 async_req(fb_info.phone, FB_FLUSH, 0, NULL); 463 471 464 472 -
console/gcons.c
rd7eafd8 r085bd54 76 76 static void vp_switch(int vp) 77 77 { 78 nsend_call(fbphone,FB_VIEWPORT_SWITCH, vp);78 async_msg(fbphone,FB_VIEWPORT_SWITCH, vp); 79 79 } 80 80 … … 91 91 static void clear(void) 92 92 { 93 nsend_call(fbphone, FB_CLEAR, 0);93 async_msg(fbphone, FB_CLEAR, 0); 94 94 95 95 } … … 97 97 static void set_style(int fgcolor, int bgcolor) 98 98 { 99 nsend_call_2(fbphone, FB_SET_STYLE, fgcolor, bgcolor);99 async_msg_2(fbphone, FB_SET_STYLE, fgcolor, bgcolor); 100 100 } 101 101 … … 103 103 static void tran_putch(char c, int row, int col) 104 104 { 105 nsend_call_3(fbphone, FB_TRANS_PUTCHAR, c, row, col);105 async_msg_3(fbphone, FB_TRANS_PUTCHAR, c, row, col); 106 106 } 107 107 … … 115 115 vp_switch(cstatus_vp[consnum]); 116 116 if (ic_pixmaps[state] != -1) 117 nsend_call_2(fbphone, FB_VP_DRAW_PIXMAP, cstatus_vp[consnum], ic_pixmaps[state]);117 async_msg_2(fbphone, FB_VP_DRAW_PIXMAP, cstatus_vp[consnum], ic_pixmaps[state]); 118 118 119 119 if (state != CONS_DISCONNECTED && state != CONS_KERNEL && state != CONS_DISCONNECTED_SEL) { … … 239 239 memcpy(shm, logo, size); 240 240 /* Send area */ 241 rc = sync_send_2(fbphone, FB_PREPARE_SHM, (ipcarg_t)shm, 0, NULL, NULL);241 rc = async_req_2(fbphone, FB_PREPARE_SHM, (ipcarg_t)shm, 0, NULL, NULL); 242 242 if (rc) 243 243 goto exit; 244 rc = sync_send_3(fbphone, IPC_M_AS_AREA_SEND, (ipcarg_t)shm, 0, PROTO_READ, NULL, NULL, NULL);244 rc = async_req_3(fbphone, IPC_M_AS_AREA_SEND, (ipcarg_t)shm, 0, PROTO_READ, NULL, NULL, NULL); 245 245 if (rc) 246 246 goto drop; 247 247 /* Draw logo */ 248 nsend_call_2(fbphone, FB_DRAW_PPM, x, y);248 async_msg_2(fbphone, FB_DRAW_PPM, x, y); 249 249 drop: 250 250 /* Drop area */ 251 nsend_call(fbphone, FB_DROP_SHM, 0);251 async_msg(fbphone, FB_DROP_SHM, 0); 252 252 exit: 253 253 /* Remove area */ … … 298 298 memcpy(shm, data, size); 299 299 /* Send area */ 300 rc = sync_send_2(fbphone, FB_PREPARE_SHM, (ipcarg_t)shm, 0, NULL, NULL);300 rc = async_req_2(fbphone, FB_PREPARE_SHM, (ipcarg_t)shm, 0, NULL, NULL); 301 301 if (rc) 302 302 goto exit; 303 rc = sync_send_3(fbphone, IPC_M_AS_AREA_SEND, (ipcarg_t)shm, 0, PROTO_READ, NULL, NULL, NULL);303 rc = async_req_3(fbphone, IPC_M_AS_AREA_SEND, (ipcarg_t)shm, 0, PROTO_READ, NULL, NULL, NULL); 304 304 if (rc) 305 305 goto drop; 306 306 307 307 /* Obtain pixmap */ 308 rc = sync_send(fbphone, FB_SHM2PIXMAP, 0, NULL);308 rc = async_req(fbphone, FB_SHM2PIXMAP, 0, NULL); 309 309 if (rc < 0) 310 310 goto drop; … … 312 312 drop: 313 313 /* Drop area */ 314 nsend_call(fbphone, FB_DROP_SHM, 0);314 async_msg(fbphone, FB_DROP_SHM, 0); 315 315 exit: 316 316 /* Remove area */ -
fb/fb.c
rd7eafd8 r085bd54 43 43 44 44 #include "font-8x16.h" 45 #include "helenos.xbm"46 45 #include "fb.h" 47 46 #include "main.h" -
kbd/generic/kbd.c
rd7eafd8 r085bd54 39 39 #include <libadt/fifo.h> 40 40 #include <key_buffer.h> 41 #include <async.h> 41 42 42 43 #define NAME "KBD" 44 45 int cons_connected = 0; 46 int phone2cons = -1; 47 keybuffer_t keybuffer; 48 49 static void irq_handler(ipc_callid_t iid, ipc_call_t *call) 50 { 51 int chr; 52 53 if (cons_connected && phone2cons != -1) { 54 /* recode to ASCII - one interrupt can produce more than one code so result is stored in fifo */ 55 kbd_arch_process(&keybuffer, IPC_GET_ARG2(*call)); 56 57 while (!keybuffer_empty(&keybuffer)) { 58 if (!keybuffer_pop(&keybuffer, (int *)&chr)) 59 break; 60 61 async_msg(phone2cons, KBD_PUSHCHAR, chr); 62 } 63 } 64 } 65 66 static void console_connection(ipc_callid_t iid, ipc_call_t *icall) 67 { 68 ipc_callid_t callid; 69 ipc_call_t call; 70 int retval; 71 72 if (cons_connected) { 73 ipc_answer_fast(iid, ELIMIT, 0, 0); 74 return; 75 } 76 cons_connected = 1; 77 ipc_answer_fast(iid, 0, 0, 0); 78 79 while (1) { 80 callid = async_get_call(&call); 81 switch (IPC_GET_METHOD(call)) { 82 case IPC_M_PHONE_HUNGUP: 83 cons_connected = 0; 84 ipc_hangup(phone2cons); 85 phone2cons = -1; 86 ipc_answer_fast(callid, 0,0,0); 87 return; 88 case IPC_M_CONNECT_TO_ME: 89 if (phone2cons != -1) { 90 retval = ELIMIT; 91 break; 92 } 93 phone2cons = IPC_GET_ARG3(call); 94 retval = 0; 95 break; 96 } 97 ipc_answer_fast(callid, retval, 0, 0); 98 } 99 } 100 43 101 44 102 int main(int argc, char **argv) … … 50 108 ipcarg_t phoneid; 51 109 char connected = 0; 52 keybuffer_t keybuffer;53 110 ipcarg_t retval, arg1, arg2; 54 55 //open("null",0);56 //open("stdout",0);57 111 58 112 /* Initialize arch dependent parts */ … … 68 122 if ((res = ipc_connect_to_me(PHONE_NS, SERVICE_KEYBOARD, 0, &phonead)) != 0) { 69 123 return -1; 70 }; 71 while (1) { 72 callid = ipc_wait_for_call(&call); 73 switch (IPC_GET_METHOD(call)) { 74 case IPC_M_PHONE_HUNGUP: 75 connected = 0; 76 retval = 0; 77 break; 78 case IPC_M_CONNECT_ME_TO: 79 /* Only one connected client allowed */ 80 if (connected) { 81 retval = ELIMIT; 82 } else { 83 retval = 0; 84 connected = 1; 85 } 86 break; 87 case IPC_M_CONNECT_TO_ME: 88 phoneid = IPC_GET_ARG3(call); 89 retval = 0; 90 break; 124 } 91 125 92 case IPC_M_INTERRUPT: 93 if (connected) { 94 int chr; 95 /* recode to ASCII - one interrupt can produce more than one code so result is stored in fifo */ 96 kbd_arch_process(&keybuffer, IPC_GET_ARG2(call)); 126 async_set_client_connection(console_connection); 127 async_set_interrupt_received(irq_handler); 128 async_manager(); 97 129 98 retval = 0;99 100 101 while (!keybuffer_empty(&keybuffer)) {102 if (!keybuffer_pop(&keybuffer, (int *)&chr)) {103 break;104 }105 {106 arg1=chr;107 send_call(phoneid, KBD_PUSHCHAR, arg1);108 }109 }110 111 }112 break;113 default:114 retval = ENOENT;115 break;116 }117 118 if (! (callid & IPC_CALLID_NOTIFICATION)) {119 ipc_answer_fast(callid, retval, arg1, arg2);120 }121 }122 130 } 123 -
klog/klog.c
rd7eafd8 r085bd54 41 41 int i; 42 42 43 // psthread_serialize_start();43 async_serialize_start(); 44 44 /* TODO: remove workaround around non-functional vsnprintf */ 45 45 for (i=0; klog[i + IPC_GET_ARG2(*call)] && i < IPC_GET_ARG3(*call); i++) 46 46 putchar(klog[i + IPC_GET_ARG2(*call)]); 47 47 putchar('\n'); 48 // psthread_serialize_done();48 async_serialize_end(); 49 49 } 50 50 -
libc/generic/async.c
rd7eafd8 r085bd54 135 135 } connection_t; 136 136 137 137 /** Identifier of incoming connection handled by current thread */ 138 138 __thread connection_t *PS_connection; 139 /** If true, it is forbidden to use async_req functions and 140 * all preemption is disabled */ 141 __thread int in_interrupt_handler; 139 142 140 143 static void default_client_connection(ipc_callid_t callid, ipc_call_t *call); … … 226 229 227 230 wd->timedout = 0; 231 wd->inlist = 1; 228 232 229 233 tmp = timeout_list.next; … … 295 299 conn = PS_connection; 296 300 297 if (usecs < 0) /* TODO: let it get through the ipc_call once */298 return 0;299 300 301 futex_down(&async_futex); 301 302 … … 308 309 /* If nothing in queue, wait until something appears */ 309 310 while (list_empty(&conn->msg_queue)) { 310 if (usecs) { 311 conn->wdata.inlist = 1; 311 if (usecs) 312 312 insert_timeout(&conn->wdata); 313 } 313 314 314 conn->wdata.active = 0; 315 315 psthread_schedule_next_adv(PS_TO_MANAGER); … … 363 363 PS_connection = (connection_t *)arg; 364 364 PS_connection->cthread(PS_connection->callid, &PS_connection->call); 365 366 365 /* Remove myself from connection hash table */ 367 366 futex_down(&async_futex); … … 436 435 switch (IPC_GET_METHOD(*call)) { 437 436 case IPC_M_INTERRUPT: 437 in_interrupt_handler = 1; 438 438 (*interrupt_received)(callid,call); 439 in_interrupt_handler = 0; 439 440 return; 440 441 case IPC_M_CONNECT_ME_TO: … … 486 487 487 488 /** Endless loop dispatching incoming calls and answers */ 488 int async_manager(void)489 static int async_manager_worker(void) 489 490 { 490 491 ipc_call_t call; … … 522 523 } 523 524 524 if (callid & IPC_CALLID_ANSWERED) 525 if (callid & IPC_CALLID_ANSWERED) { 525 526 continue; 527 } 526 528 527 529 handle_call(callid, &call); … … 538 540 static int async_manager_thread(void *arg) 539 541 { 542 in_interrupt_handler = 0; // TODO: Handle TLS better 540 543 futex_up(&async_futex); /* async_futex is always locked when entering 541 544 * manager */ 542 async_manager ();545 async_manager_worker(); 543 546 } 544 547 … … 608 611 amsg_t *msg; 609 612 613 if (in_interrupt_handler) { 614 printf("Cannot send asynchronou request in interrupt handler.\n"); 615 _exit(1); 616 } 617 610 618 msg = malloc(sizeof(*msg)); 611 619 msg->done = 0; … … 628 636 { 629 637 amsg_t *msg; 638 639 if (in_interrupt_handler) { 640 printf("Cannot send asynchronou request in interrupt handler.\n"); 641 _exit(1); 642 } 630 643 631 644 msg = malloc(sizeof(*msg)); … … 699 712 msg->wdata.ptid = psthread_get_id(); 700 713 msg->wdata.active = 0; 701 msg->wdata.inlist = 1;702 703 714 insert_timeout(&msg->wdata); 704 715 … … 726 737 amsg_t *msg; 727 738 739 if (in_interrupt_handler) { 740 printf("Cannot call async_usleep in interrupt handler.\n"); 741 _exit(1); 742 } 743 728 744 msg = malloc(sizeof(*msg)); 729 745 if (!msg) … … 731 747 732 748 msg->wdata.ptid = psthread_get_id(); 733 msg->wdata.inlist = 1;734 749 msg->wdata.active = 0; 735 750 … … 757 772 interrupt_received = conn; 758 773 } 774 775 /* Primitive functions for simple communication */ 776 void async_msg_3(int phoneid, ipcarg_t method, ipcarg_t arg1, 777 ipcarg_t arg2, ipcarg_t arg3) 778 { 779 ipc_call_async_3(phoneid, method, arg1, arg2, arg3, NULL, NULL, !in_interrupt_handler); 780 } 781 782 void async_msg_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2) 783 { 784 ipc_call_async_2(phoneid, method, arg1, arg2, NULL, NULL, !in_interrupt_handler); 785 } -
libc/generic/io/stream.c
rd7eafd8 r085bd54 65 65 66 66 while (i < count) { 67 if ( sync_send_2(streams[0].phone, CONSOLE_GETCHAR, 0, 0, &r0, &r1) < 0) {67 if (async_req_2(streams[0].phone, CONSOLE_GETCHAR, 0, 0, &r0, &r1) < 0) { 68 68 return -1; 69 69 } … … 79 79 80 80 for (i = 0; i < count; i++) 81 send_call(streams[1].phone, CONSOLE_PUTCHAR, ((const char *)buf)[i]);81 async_msg(streams[1].phone, CONSOLE_PUTCHAR, ((const char *)buf)[i]); 82 82 83 83 return count; … … 131 131 { 132 132 int c = 0; 133 133 134 134 while (((streams[c].w) || (streams[c].r)) && (c < FDS)) 135 135 c++; … … 160 160 ssize_t write(int fd, const void *buf, size_t count) 161 161 { 162 // __SYSCALL3(SYS_IO, 1, (sysarg_t)buf, (sysarg_t) count); 163 // return count; 162 164 if (fd < FDS) 163 165 return streams[fd].w(streams[fd].param, buf, count); -
libc/generic/ipc.c
rd7eafd8 r085bd54 438 438 } 439 439 440 /* Primitive functions for simple communication */441 void send_call_3(int phoneid, ipcarg_t method, ipcarg_t arg1,442 ipcarg_t arg2, ipcarg_t arg3)443 {444 ipc_call_async_3(phoneid, method, arg1, arg2, arg3, NULL, NULL, 1);445 }446 447 void send_call_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2)448 {449 ipc_call_async_2(phoneid, method, arg1, arg2, NULL, NULL, 1);450 }451 452 void nsend_call_3(int phoneid, ipcarg_t method, ipcarg_t arg1,453 ipcarg_t arg2, ipcarg_t arg3)454 {455 ipc_call_async_3(phoneid, method, arg1, arg2, arg3, NULL, NULL, 0);456 }457 458 void nsend_call_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2)459 {460 ipc_call_async_2(phoneid, method, arg1, arg2, NULL, NULL, 0);461 }462 -
libc/generic/psthread.c
rd7eafd8 r085bd54 43 43 44 44 static LIST_INITIALIZE(ready_list); 45 static LIST_INITIALIZE(serialized_list); 45 46 static LIST_INITIALIZE(manager_list); 46 47 … … 49 50 50 51 static atomic_t psthread_futex = FUTEX_INITIALIZER; 52 /** Count of real threads that are in async_serialized mode */ 53 static int serialized_threads; /* Protected by async_futex */ 54 /** Thread-local count of serialization. If >0, we must not preempt */ 55 static __thread serialization_count; 56 /** Counter of threads residing in async_manager */ 57 static int threads_in_manager; 51 58 52 59 /** Setup PSthread information into TCB structure */ … … 78 85 } 79 86 80 /** Function to preempt to other pseudo thread without adding81 * currently running pseudo thread to ready_list.82 */83 void psthread_exit(void)84 {85 psthread_data_t *pt;86 87 futex_down(&psthread_futex);88 89 if (!list_empty(&ready_list))90 pt = list_get_instance(ready_list.next, psthread_data_t, link);91 else if (!list_empty(&manager_list))92 pt = list_get_instance(manager_list.next, psthread_data_t, link);93 else {94 printf("Cannot find suitable psthread to run.\n");95 _exit(0);96 }97 list_remove(&pt->link);98 futex_up(&psthread_futex);99 100 context_restore(&pt->ctx);101 /* Never reached */102 }103 104 87 /** Function that is called on entry to new uspace thread */ 105 88 void psthread_main(void) … … 107 90 psthread_data_t *pt = __tcb_get()->pst_data; 108 91 92 serialization_count = 0; // TODO: WHY HERE? 109 93 pt->retval = pt->func(pt->arg); 110 94 … … 113 97 list_append(&pt->waiter->link, &ready_list); 114 98 115 psthread_ exit();99 psthread_schedule_next_adv(PS_FROM_DEAD); 116 100 } 117 101 … … 128 112 int psthread_schedule_next_adv(pschange_type ctype) 129 113 { 130 psthread_data_t * pt;114 psthread_data_t *srcpt, *dstpt; 131 115 int retval = 0; 132 116 … … 136 120 goto ret_0; 137 121 138 if (ctype == PS_FROM_MANAGER && list_empty(&ready_list)) { 139 goto ret_0; 122 if (ctype == PS_FROM_MANAGER) { 123 if (list_empty(&ready_list) && list_empty(&serialized_list)) 124 goto ret_0; 125 /* Do not preempt if there is not sufficient count of thread managers */ 126 if (list_empty(&serialized_list) && threads_in_manager <= serialized_threads) { 127 goto ret_0; 128 } 140 129 } 141 130 /* If we are going to manager and none exists, create it */ 142 while (ctype == PS_TO_MANAGER && list_empty(&manager_list)) { 143 futex_up(&psthread_futex); 144 async_create_manager(); 145 futex_down(&psthread_futex); 146 } 147 148 pt = __tcb_get()->pst_data; 149 if (!context_save(&pt->ctx)) 150 return 1; // futex_up already done here 151 152 if (ctype == PS_PREEMPT) 153 list_append(&pt->link, &ready_list); 154 else if (ctype == PS_FROM_MANAGER) 155 list_append(&pt->link, &manager_list); 131 if (ctype == PS_TO_MANAGER || ctype == PS_FROM_DEAD) { 132 while (list_empty(&manager_list)) { 133 futex_up(&psthread_futex); 134 async_create_manager(); 135 futex_down(&psthread_futex); 136 } 137 } 156 138 157 if (ctype == PS_TO_MANAGER) 158 pt = list_get_instance(manager_list.next,psthread_data_t, link); 159 else 160 pt = list_get_instance(ready_list.next, psthread_data_t, link); 161 list_remove(&pt->link); 162 163 futex_up(&psthread_futex); 164 context_restore(&pt->ctx); 139 if (ctype != PS_FROM_DEAD) { 140 /* Save current state */ 141 srcpt = __tcb_get()->pst_data; 142 if (!context_save(&srcpt->ctx)) { 143 if (serialization_count) 144 srcpt->flags &= ~PSTHREAD_SERIALIZED; 145 return 1; // futex_up already done here 146 } 147 148 /* Save myself to correct run list */ 149 if (ctype == PS_PREEMPT) 150 list_append(&srcpt->link, &ready_list); 151 else if (ctype == PS_FROM_MANAGER) { 152 list_append(&srcpt->link, &manager_list); 153 threads_in_manager--; 154 } /* If ctype == PS_TO_MANAGER, don't save ourselves to any list, we should 155 * already be somewhere, or we will be lost */ 156 } 157 158 /* Choose new thread to run */ 159 if (ctype == PS_TO_MANAGER || ctype == PS_FROM_DEAD) { 160 dstpt = list_get_instance(manager_list.next,psthread_data_t, link); 161 if (serialization_count && ctype == PS_TO_MANAGER) { 162 serialized_threads++; 163 srcpt->flags |= PSTHREAD_SERIALIZED; 164 } 165 threads_in_manager++; 166 } else { 167 if (!list_empty(&serialized_list)) { 168 dstpt = list_get_instance(serialized_list.next, psthread_data_t, link); 169 serialized_threads--; 170 } else 171 dstpt = list_get_instance(ready_list.next, psthread_data_t, link); 172 } 173 list_remove(&dstpt->link); 174 175 futex_up(&psthread_futex); 176 context_restore(&dstpt->ctx); 165 177 166 178 ret_0: … … 183 195 pt = (psthread_data_t *) psthrid; 184 196 185 if (!pt->finished) { 186 mypt = __tcb_get()->pst_data; 187 if (context_save(&((psthread_data_t *) mypt)->ctx)) { 188 pt->waiter = (psthread_data_t *) mypt; 189 psthread_exit(); 190 } 191 } 197 /* TODO */ 198 printf("join unsupported\n"); 199 _exit(1); 200 192 201 retval = pt->retval; 193 202 … … 224 233 pt->finished = 0; 225 234 pt->waiter = NULL; 235 pt->flags = 0; 226 236 227 237 context_save(&pt->ctx); … … 239 249 pt = (psthread_data_t *) psthrid; 240 250 futex_down(&psthread_futex); 241 list_append(&pt->link, &ready_list); 251 if ((pt->flags & PSTHREAD_SERIALIZED)) 252 list_append(&pt->link, &serialized_list); 253 else 254 list_append(&pt->link, &ready_list); 242 255 futex_up(&psthread_futex); 243 256 } … … 272 285 return (pstid_t)__tcb_get()->pst_data; 273 286 } 287 288 /** Disable preemption 289 * 290 * If the thread wants to send several message in row and does not want 291 * to be preempted, it should start async_serialize_start() in the beginning 292 * of communication and async_serialize_end() in the end. If it is a 293 * true multithreaded application, it should protect the communication channel 294 * by a futex as well. Interrupt messages will can still be preempted. 295 */ 296 void psthread_inc_sercount(void) 297 { 298 serialization_count++; 299 } 300 301 void psthread_dec_sercount(void) 302 { 303 serialization_count--; 304 } -
libc/include/async.h
rd7eafd8 r085bd54 38 38 typedef void (*async_client_conn_t)(ipc_callid_t callid, ipc_call_t *call); 39 39 40 int async_manager(void); 40 static inline void async_manager(void) 41 { 42 psthread_schedule_next_adv(PS_TO_MANAGER); 43 } 44 41 45 ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs); 42 46 static inline ipc_callid_t async_get_call(ipc_call_t *data) … … 58 62 * @return Return code of message 59 63 */ 60 static inline ipcarg_t sync_send_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t *r1, ipcarg_t *r2)64 static inline ipcarg_t async_req_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t *r1, ipcarg_t *r2) 61 65 { 62 66 ipc_call_t result; … … 71 75 return rc; 72 76 } 73 #define sync_send(phoneid, method, arg1, r1) sync_send_2(phoneid, method, arg1, 0, r1, 0)77 #define async_req(phoneid, method, arg1, r1) async_req_2(phoneid, method, arg1, 0, r1, 0) 74 78 75 static inline ipcarg_t sync_send_3(int phoneid, ipcarg_t method, ipcarg_t arg1,79 static inline ipcarg_t async_req_3(int phoneid, ipcarg_t method, ipcarg_t arg1, 76 80 ipcarg_t arg2, ipcarg_t arg3, ipcarg_t *r1, 77 81 ipcarg_t *r2, ipcarg_t *r3) … … 103 107 104 108 109 /* Primitve functions for IPC communication */ 110 void async_msg_3(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2, 111 ipcarg_t arg3); 112 void async_msg_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2); 113 #define async_msg(ph,m,a1) async_msg_2(ph,m,a1,0) 114 115 static inline void async_serialize_start(void) 116 { 117 psthread_inc_sercount(); 118 } 119 static inline void async_serialize_end(void) 120 { 121 psthread_dec_sercount(); 122 } 123 105 124 extern atomic_t async_futex; 106 107 125 #endif -
libc/include/ipc/ipc.h
rd7eafd8 r085bd54 82 82 extern int ipc_forward_fast(ipc_callid_t callid, int phoneid, int method, ipcarg_t arg1); 83 83 84 85 /* Primitve functions for IPC communication */86 void send_call_3(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2,87 ipcarg_t arg3);88 void send_call_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2);89 #define send_call(ph,m,a1) send_call_2(ph,m,a1,0)90 /* These functions never preempt */91 void nsend_call_3(int phoneid, ipcarg_t method, ipcarg_t arg1,92 ipcarg_t arg2, ipcarg_t arg3);93 void nsend_call_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2);94 #define nsend_call(ph,m,a1) nsend_call_2(ph,m,a1,0)95 96 84 #endif -
libc/include/psthread.h
rd7eafd8 r085bd54 41 41 #endif /* context_set */ 42 42 43 #define PSTHREAD_SERIALIZED 1 44 43 45 typedef enum { 44 46 PS_TO_MANAGER, 45 47 PS_FROM_MANAGER, 46 PS_PREEMPT 48 PS_PREEMPT, 49 PS_FROM_DEAD 47 50 } pschange_type; 48 51 … … 76 79 void psthread_remove_manager(void); 77 80 pstid_t psthread_get_id(void); 81 void psthread_inc_sercount(void); 82 void psthread_dec_sercount(void); 78 83 79 84 static inline int psthread_schedule_next() { -
tetris/screen.c
rd7eafd8 r085bd54 81 81 static void set_style(int fgcolor, int bgcolor) 82 82 { 83 send_call_2(con_phone, CONSOLE_SET_STYLE, fgcolor, bgcolor);83 async_msg_2(con_phone, CONSOLE_SET_STYLE, fgcolor, bgcolor); 84 84 } 85 85 … … 97 97 void clear_screen(void) 98 98 { 99 send_call(con_phone, CONSOLE_CLEAR, 0);99 async_msg(con_phone, CONSOLE_CLEAR, 0); 100 100 moveto(0,0); 101 101 } … … 109 109 110 110 resume_normal(); 111 send_call(con_phone, CONSOLE_CLEAR, 0);111 async_msg(con_phone, CONSOLE_CLEAR, 0); 112 112 curscore = -1; 113 113 memset((char *)curscreen, 0, sizeof(curscreen)); … … 121 121 { 122 122 con_phone = get_fd_phone(1); 123 send_call(con_phone, CONSOLE_CURSOR_VISIBILITY, 0);123 async_msg(con_phone, CONSOLE_CURSOR_VISIBILITY, 0); 124 124 resume_normal(); 125 125 scr_clear(); … … 128 128 void moveto(int r, int c) 129 129 { 130 send_call_2(con_phone, CONSOLE_GOTO, r, c);130 async_msg_2(con_phone, CONSOLE_GOTO, r, c); 131 131 } 132 132 133 133 static void fflush(void) 134 134 { 135 send_call(con_phone, CONSOLE_FLUSH, 0);135 async_msg(con_phone, CONSOLE_FLUSH, 0); 136 136 } 137 137 … … 140 140 static int get_display_size(winsize_t *ws) 141 141 { 142 return sync_send_2(con_phone, CONSOLE_GETSIZE, 0, 0, &ws->ws_row, &ws->ws_col);142 return async_req_2(con_phone, CONSOLE_GETSIZE, 0, 0, &ws->ws_row, &ws->ws_col); 143 143 } 144 144
Note:
See TracChangeset
for help on using the changeset viewer.