Changeset 085bd54 in mainline


Ignore:
Timestamp:
2006-06-06T15:16:08Z (18 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
63bb83e
Parents:
d7eafd8
Message:

Revised ipc. Now it is preferrable to use only functions from async.h, they
take care of correct buffering, waiting for answers etc.

Files:
1 deleted
13 edited

Legend:

Unmodified
Added
Removed
  • console/console.c

    rd7eafd8 r085bd54  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
     28/* TODO: remove */
     29#include <stdio.h>
    2830
    2931
     
    9294static void clrscr(void)
    9395{
    94         nsend_call(fb_info.phone, FB_CLEAR, 0);
     96        async_msg(fb_info.phone, FB_CLEAR, 0);
    9597}
    9698
    9799static void curs_visibility(int v)
    98100{
    99         send_call(fb_info.phone, FB_CURSOR_VISIBILITY, v);
     101        async_msg(fb_info.phone, FB_CURSOR_VISIBILITY, v);
    100102}
    101103
    102104static void curs_goto(int row, int col)
    103105{
    104         nsend_call_2(fb_info.phone, FB_CURSOR_GOTO, row, col);
     106        async_msg_2(fb_info.phone, FB_CURSOR_GOTO, row, col);
    105107       
    106108}
     
    108110static void set_style(style_t *style)
    109111{
    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);
    111113}
    112114
    113115static void set_style_col(int fgcolor, int bgcolor)
    114116{
    115         nsend_call_2(fb_info.phone, FB_SET_STYLE, fgcolor, bgcolor);
     117        async_msg_2(fb_info.phone, FB_SET_STYLE, fgcolor, bgcolor);
    116118}
    117119
    118120static void prtchr(char c, int row, int col)
    119121{
    120         nsend_call_3(fb_info.phone, FB_PUTCHAR, c, row, col);
     122        async_msg_3(fb_info.phone, FB_PUTCHAR, c, row, col);
    121123       
    122124}
     
    166168                screenbuffer_clear_line(scr, scr->top_line++);
    167169                if (console == active_console)
    168                         nsend_call(fb_info.phone, FB_SCROLL, 1);
     170                        async_msg(fb_info.phone, FB_SCROLL, 1);
    169171        }
    170172       
     
    186188       
    187189        /* Save screen */
    188         newpmap = sync_send(fb_info.phone, FB_VP2PIXMAP, 0, NULL);
     190        newpmap = async_req(fb_info.phone, FB_VP2PIXMAP, 0, NULL);
    189191        if (newpmap < 0)
    190192                return -1;
     
    192194        if (oldpixmap != -1) {
    193195                /* 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);
    195197                /* Drop old pixmap */
    196                 nsend_call(fb_info.phone, FB_DROP_PIXMAP, oldpixmap);
     198                async_msg(fb_info.phone, FB_DROP_PIXMAP, oldpixmap);
    197199        }
    198200       
     
    237239                console_pixmap = -1;
    238240        }
    239        
    240241        active_console = newcons;
    241242        gcons_change_console(newcons);
     
    245246        curs_goto(conn->screenbuffer.position_y, conn->screenbuffer.position_x);
    246247        curs_visibility(0);
    247        
    248248        if (interbuffer) {
    249249                for (i = 0; i < conn->screenbuffer.size_x; i++)
     
    251251                                interbuffer[i + j*conn->screenbuffer.size_x] = *get_field_at(&(conn->screenbuffer),i, j);
    252252                /* 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);           
    254254        };
    255255       
     
    302302//                      if ((c >= KBD_KEY_F1) && (c < KBD_KEY_F1 + CONSOLE_COUNT)) {
    303303                        if ((c >= 0x101) && (c < 0x101 + CONSOLE_COUNT)) {
     304                                async_serialize_start();
    304305                                if (c == 0x112)
    305306                                        change_console(KERNEL_CONSOLE);
    306307                                else
    307308                                        change_console(c - 0x101);
     309                                async_serialize_end();
    308310                                break;
    309311                        }
     
    322324                default:
    323325                        retval = ENOENT;
    324                 }               
     326                }
    325327                ipc_answer_fast(callid, retval, 0, 0);
    326328        }
     
    341343        }
    342344        conn = &connections[consnum];
    343        
     345        conn->used = 1;
     346       
     347        async_serialize_start();
    344348        gcons_notify_connect(consnum);
    345         conn->used = 1;
    346349        conn->client_phone = IPC_GET_ARG3(call);
    347350        screenbuffer_clear(&conn->screenbuffer);
     
    349352        /* Accept the connection */
    350353        ipc_answer_fast(iid,0,0,0);
    351        
     354
    352355        while (1) {
     356                async_serialize_end();
    353357                callid = async_get_call(&call);
     358                async_serialize_start();
     359
    354360                arg1 = arg2 = 0;
    355361                switch (IPC_GET_METHOD(call)) {
    356362                case IPC_M_PHONE_HUNGUP:
    357363                        gcons_notify_disconnect(consnum);
     364                       
    358365                        /* Answer all pending requests */
    359366                        while (conn->keyrequest_counter > 0) {         
     
    365372                        /* Commit hangup */
    366373                        ipc_answer_fast(callid, 0,0,0);
     374                        async_serialize_end();
    367375                        return;
    368376                case CONSOLE_PUTCHAR:
     
    373381                        /* Send message to fb */
    374382                        if (consnum == active_console) {
    375                                 send_call(fb_info.phone, FB_CLEAR, 0);
     383                                async_msg(fb_info.phone, FB_CLEAR, 0);
    376384                        }
    377385                       
     
    392400                        break;
    393401                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);         
    395403                        break;
    396404                case CONSOLE_SET_STYLE:
     
    460468        gcons_init(fb_info.phone);
    461469        /* 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);
    463471
    464472       
  • console/gcons.c

    rd7eafd8 r085bd54  
    7676static void vp_switch(int vp)
    7777{
    78         nsend_call(fbphone,FB_VIEWPORT_SWITCH, vp);
     78        async_msg(fbphone,FB_VIEWPORT_SWITCH, vp);
    7979}
    8080
     
    9191static void clear(void)
    9292{
    93         nsend_call(fbphone, FB_CLEAR, 0);
     93        async_msg(fbphone, FB_CLEAR, 0);
    9494       
    9595}
     
    9797static void set_style(int fgcolor, int bgcolor)
    9898{
    99         nsend_call_2(fbphone, FB_SET_STYLE, fgcolor, bgcolor);
     99        async_msg_2(fbphone, FB_SET_STYLE, fgcolor, bgcolor);
    100100}
    101101
     
    103103static void tran_putch(char c, int row, int col)
    104104{
    105         nsend_call_3(fbphone, FB_TRANS_PUTCHAR, c, row, col);
     105        async_msg_3(fbphone, FB_TRANS_PUTCHAR, c, row, col);
    106106}
    107107
     
    115115        vp_switch(cstatus_vp[consnum]);
    116116        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]);
    118118
    119119        if (state != CONS_DISCONNECTED && state != CONS_KERNEL && state != CONS_DISCONNECTED_SEL) {
     
    239239        memcpy(shm, logo, size);
    240240        /* 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);
    242242        if (rc)
    243243                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);
    245245        if (rc)
    246246                goto drop;
    247247        /* Draw logo */
    248         nsend_call_2(fbphone, FB_DRAW_PPM, x, y);
     248        async_msg_2(fbphone, FB_DRAW_PPM, x, y);
    249249drop:
    250250        /* Drop area */
    251         nsend_call(fbphone, FB_DROP_SHM, 0);
     251        async_msg(fbphone, FB_DROP_SHM, 0);
    252252exit:       
    253253        /* Remove area */
     
    298298        memcpy(shm, data, size);
    299299        /* 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);
    301301        if (rc)
    302302                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);
    304304        if (rc)
    305305                goto drop;
    306306
    307307        /* Obtain pixmap */
    308         rc = sync_send(fbphone, FB_SHM2PIXMAP, 0, NULL);
     308        rc = async_req(fbphone, FB_SHM2PIXMAP, 0, NULL);
    309309        if (rc < 0)
    310310                goto drop;
     
    312312drop:
    313313        /* Drop area */
    314         nsend_call(fbphone, FB_DROP_SHM, 0);
     314        async_msg(fbphone, FB_DROP_SHM, 0);
    315315exit:       
    316316        /* Remove area */
  • fb/fb.c

    rd7eafd8 r085bd54  
    4343
    4444#include "font-8x16.h"
    45 #include "helenos.xbm"
    4645#include "fb.h"
    4746#include "main.h"
  • kbd/generic/kbd.c

    rd7eafd8 r085bd54  
    3939#include <libadt/fifo.h>
    4040#include <key_buffer.h>
     41#include <async.h>
    4142
    4243#define NAME "KBD"
     44
     45int cons_connected = 0;
     46int phone2cons = -1;
     47keybuffer_t keybuffer; 
     48
     49static 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
     66static 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
    43101
    44102int main(int argc, char **argv)
     
    50108        ipcarg_t phoneid;
    51109        char connected = 0;
    52         keybuffer_t keybuffer; 
    53110        ipcarg_t retval, arg1, arg2;
    54        
    55         //open("null",0);
    56         //open("stdout",0);
    57111       
    58112        /* Initialize arch dependent parts */
     
    68122        if ((res = ipc_connect_to_me(PHONE_NS, SERVICE_KEYBOARD, 0, &phonead)) != 0) {
    69123                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        }
    91125
    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();
    97129
    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         }
    122130}
    123 
  • klog/klog.c

    rd7eafd8 r085bd54  
    4141        int i;
    4242       
    43 //      psthread_serialize_start();
     43        async_serialize_start();
    4444        /* TODO: remove workaround around non-functional vsnprintf */
    4545        for (i=0; klog[i + IPC_GET_ARG2(*call)] && i < IPC_GET_ARG3(*call); i++)
    4646                putchar(klog[i + IPC_GET_ARG2(*call)]);
    4747        putchar('\n');
    48 //      psthread_serialize_done();
     48        async_serialize_end();
    4949}
    5050
  • libc/generic/async.c

    rd7eafd8 r085bd54  
    135135} connection_t;
    136136
    137 
     137/** Identifier of incoming connection handled by current thread */
    138138__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;
    139142
    140143static void default_client_connection(ipc_callid_t callid, ipc_call_t *call);
     
    226229
    227230        wd->timedout = 0;
     231        wd->inlist = 1;
    228232
    229233        tmp = timeout_list.next;
     
    295299        conn = PS_connection;
    296300
    297         if (usecs < 0) /* TODO: let it get through the ipc_call once */
    298                 return 0;
    299 
    300301        futex_down(&async_futex);
    301302
     
    308309        /* If nothing in queue, wait until something appears */
    309310        while (list_empty(&conn->msg_queue)) {
    310                 if (usecs) {
    311                         conn->wdata.inlist = 1;
     311                if (usecs)
    312312                        insert_timeout(&conn->wdata);
    313                 }
     313
    314314                conn->wdata.active = 0;
    315315                psthread_schedule_next_adv(PS_TO_MANAGER);
     
    363363        PS_connection = (connection_t *)arg;
    364364        PS_connection->cthread(PS_connection->callid, &PS_connection->call);
    365 
    366365        /* Remove myself from connection hash table */
    367366        futex_down(&async_futex);
     
    436435        switch (IPC_GET_METHOD(*call)) {
    437436        case IPC_M_INTERRUPT:
     437                in_interrupt_handler = 1;
    438438                (*interrupt_received)(callid,call);
     439                in_interrupt_handler = 0;
    439440                return;
    440441        case IPC_M_CONNECT_ME_TO:
     
    486487
    487488/** Endless loop dispatching incoming calls and answers */
    488 int async_manager(void)
     489static int async_manager_worker(void)
    489490{
    490491        ipc_call_t call;
     
    522523                }
    523524
    524                 if (callid & IPC_CALLID_ANSWERED)
     525                if (callid & IPC_CALLID_ANSWERED) {
    525526                        continue;
     527                }
    526528
    527529                handle_call(callid, &call);
     
    538540static int async_manager_thread(void *arg)
    539541{
     542        in_interrupt_handler = 0; // TODO: Handle TLS better
    540543        futex_up(&async_futex); /* async_futex is always locked when entering
    541544                                * manager */
    542         async_manager();
     545        async_manager_worker();
    543546}
    544547
     
    608611        amsg_t *msg;
    609612
     613        if (in_interrupt_handler) {
     614                printf("Cannot send asynchronou request in interrupt handler.\n");
     615                _exit(1);
     616        }
     617
    610618        msg = malloc(sizeof(*msg));
    611619        msg->done = 0;
     
    628636{
    629637        amsg_t *msg;
     638
     639        if (in_interrupt_handler) {
     640                printf("Cannot send asynchronou request in interrupt handler.\n");
     641                _exit(1);
     642        }
    630643
    631644        msg = malloc(sizeof(*msg));
     
    699712        msg->wdata.ptid = psthread_get_id();
    700713        msg->wdata.active = 0;
    701         msg->wdata.inlist = 1;
    702 
    703714        insert_timeout(&msg->wdata);
    704715
     
    726737        amsg_t *msg;
    727738       
     739        if (in_interrupt_handler) {
     740                printf("Cannot call async_usleep in interrupt handler.\n");
     741                _exit(1);
     742        }
     743
    728744        msg = malloc(sizeof(*msg));
    729745        if (!msg)
     
    731747
    732748        msg->wdata.ptid = psthread_get_id();
    733         msg->wdata.inlist = 1;
    734749        msg->wdata.active = 0;
    735750
     
    757772        interrupt_received = conn;
    758773}
     774
     775/* Primitive functions for simple communication */
     776void 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
     782void 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  
    6565
    6666        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) {
    6868                        return -1;
    6969                }
     
    7979
    8080        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]);
    8282       
    8383        return count;
     
    131131{
    132132        int c = 0;
    133        
     133
    134134        while (((streams[c].w) || (streams[c].r)) && (c < FDS))
    135135                c++;
     
    160160ssize_t write(int fd, const void *buf, size_t count)
    161161{
     162//      __SYSCALL3(SYS_IO, 1, (sysarg_t)buf, (sysarg_t) count);
     163//      return count;
    162164        if (fd < FDS)
    163165                return streams[fd].w(streams[fd].param, buf, count);
  • libc/generic/ipc.c

    rd7eafd8 r085bd54  
    438438}
    439439
    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  
    4343
    4444static LIST_INITIALIZE(ready_list);
     45static LIST_INITIALIZE(serialized_list);
    4546static LIST_INITIALIZE(manager_list);
    4647
     
    4950
    5051static atomic_t psthread_futex = FUTEX_INITIALIZER;
     52/** Count of real threads that are in async_serialized mode */
     53static int serialized_threads; /* Protected by async_futex */
     54/** Thread-local count of serialization. If >0, we must not preempt */
     55static __thread serialization_count;
     56/** Counter of threads residing in async_manager */
     57static int threads_in_manager;
    5158
    5259/** Setup PSthread information into TCB structure */
     
    7885}
    7986
    80 /** Function to preempt to other pseudo thread without adding
    81  * 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 
    10487/** Function that is called on entry to new uspace thread */
    10588void psthread_main(void)
     
    10790        psthread_data_t *pt = __tcb_get()->pst_data;
    10891
     92        serialization_count = 0; // TODO: WHY HERE?
    10993        pt->retval = pt->func(pt->arg);
    11094
     
    11397                list_append(&pt->waiter->link, &ready_list);
    11498
    115         psthread_exit();
     99        psthread_schedule_next_adv(PS_FROM_DEAD);
    116100}
    117101
     
    128112int psthread_schedule_next_adv(pschange_type ctype)
    129113{
    130         psthread_data_t *pt;
     114        psthread_data_t *srcpt, *dstpt;
    131115        int retval = 0;
    132116       
     
    136120                goto ret_0;
    137121
    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                }
    140129        }
    141130        /* 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        }
    156138       
    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);
    165177
    166178ret_0:
     
    183195        pt = (psthread_data_t *) psthrid;
    184196
    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
    192201        retval = pt->retval;
    193202
     
    224233        pt->finished = 0;
    225234        pt->waiter = NULL;
     235        pt->flags = 0;
    226236
    227237        context_save(&pt->ctx);
     
    239249        pt = (psthread_data_t *) psthrid;
    240250        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);
    242255        futex_up(&psthread_futex);
    243256}
     
    272285        return (pstid_t)__tcb_get()->pst_data;
    273286}
     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 */
     296void psthread_inc_sercount(void)
     297{
     298        serialization_count++;
     299}
     300
     301void psthread_dec_sercount(void)
     302{
     303        serialization_count--;
     304}
  • libc/include/async.h

    rd7eafd8 r085bd54  
    3838typedef void (*async_client_conn_t)(ipc_callid_t callid, ipc_call_t *call);
    3939
    40 int async_manager(void);
     40static inline void async_manager(void)
     41{
     42        psthread_schedule_next_adv(PS_TO_MANAGER);
     43}
     44
    4145ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs);
    4246static inline ipc_callid_t async_get_call(ipc_call_t *data)
     
    5862 * @return Return code of message
    5963 */
    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)
     64static inline ipcarg_t async_req_2(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2, ipcarg_t *r1, ipcarg_t *r2)
    6165{
    6266        ipc_call_t result;
     
    7175        return rc;
    7276}
    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)
    7478
    75 static inline ipcarg_t sync_send_3(int phoneid, ipcarg_t method, ipcarg_t arg1,
     79static inline ipcarg_t async_req_3(int phoneid, ipcarg_t method, ipcarg_t arg1,
    7680                                   ipcarg_t arg2, ipcarg_t arg3, ipcarg_t *r1,
    7781                                   ipcarg_t *r2, ipcarg_t *r3)
     
    103107
    104108
     109/* Primitve functions for IPC communication */
     110void async_msg_3(int phoneid, ipcarg_t method, ipcarg_t arg1, ipcarg_t arg2,
     111                 ipcarg_t arg3);
     112void 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
     115static inline void async_serialize_start(void)
     116{
     117        psthread_inc_sercount();
     118}
     119static inline void async_serialize_end(void)
     120{
     121        psthread_dec_sercount();
     122}
     123
    105124extern atomic_t async_futex;
    106 
    107125#endif
  • libc/include/ipc/ipc.h

    rd7eafd8 r085bd54  
    8282extern int ipc_forward_fast(ipc_callid_t callid, int phoneid, int method, ipcarg_t arg1);
    8383
    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 
    9684#endif
  • libc/include/psthread.h

    rd7eafd8 r085bd54  
    4141#endif /* context_set */
    4242
     43#define PSTHREAD_SERIALIZED   1
     44
    4345typedef enum {
    4446        PS_TO_MANAGER,
    4547        PS_FROM_MANAGER,
    46         PS_PREEMPT
     48        PS_PREEMPT,
     49        PS_FROM_DEAD
    4750} pschange_type;
    4851
     
    7679void psthread_remove_manager(void);
    7780pstid_t psthread_get_id(void);
     81void psthread_inc_sercount(void);
     82void psthread_dec_sercount(void);
    7883
    7984static inline int psthread_schedule_next() {
  • tetris/screen.c

    rd7eafd8 r085bd54  
    8181static void set_style(int fgcolor, int bgcolor)
    8282{
    83         send_call_2(con_phone, CONSOLE_SET_STYLE, fgcolor, bgcolor);
     83        async_msg_2(con_phone, CONSOLE_SET_STYLE, fgcolor, bgcolor);
    8484}
    8585
     
    9797void clear_screen(void)
    9898{
    99         send_call(con_phone, CONSOLE_CLEAR, 0);
     99        async_msg(con_phone, CONSOLE_CLEAR, 0);
    100100        moveto(0,0);
    101101}
     
    109109
    110110        resume_normal();
    111         send_call(con_phone, CONSOLE_CLEAR, 0);
     111        async_msg(con_phone, CONSOLE_CLEAR, 0);
    112112        curscore = -1;
    113113        memset((char *)curscreen, 0, sizeof(curscreen));
     
    121121{
    122122        con_phone = get_fd_phone(1);
    123         send_call(con_phone, CONSOLE_CURSOR_VISIBILITY, 0);
     123        async_msg(con_phone, CONSOLE_CURSOR_VISIBILITY, 0);
    124124        resume_normal();
    125125        scr_clear();
     
    128128void moveto(int r, int c)
    129129{
    130         send_call_2(con_phone, CONSOLE_GOTO, r, c);
     130        async_msg_2(con_phone, CONSOLE_GOTO, r, c);
    131131}
    132132
    133133static void fflush(void)
    134134{
    135         send_call(con_phone, CONSOLE_FLUSH, 0);
     135        async_msg(con_phone, CONSOLE_FLUSH, 0);
    136136}
    137137
     
    140140static int get_display_size(winsize_t *ws)
    141141{
    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);
    143143}
    144144
Note: See TracChangeset for help on using the changeset viewer.