Changeset 80649a91 in mainline


Ignore:
Timestamp:
2006-05-21T19:28:37Z (19 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a410beb
Parents:
1ee11f4
Message:

Merged libadt into libc.
Made lot of psthread and thread stuff thread-safe.
Added new driver framework for easy C connection programming.
Changed FB code to use new API.

Files:
1 deleted
13 edited
5 moved

Legend:

Unmodified
Added
Removed
  • Makefile

    r1ee11f4 r80649a91  
    3636        softint \
    3737        softfloat \
    38         libadt \
    3938        init \
     39        test \
    4040        ns \
    4141        fb
  • fb/fb.c

    r1ee11f4 r80649a91  
    4545
    4646#include <kernel/errno.h>
    47 
     47#include <async.h>
    4848
    4949#include "fb.h"
    50 
    51 
    52 
    53 #define pl /*printf("FB:L:%d\n",(int)__LINE__);*/
    5450
    5551#define EFB (-1)
     
    8076
    8177
    82 
    83 
    84 int main(int argc, char *argv[])
    85 {
    86        
     78static int init_fb(void)
     79{
    8780        __address fb_ph_addr;
    8881        unsigned int fb_width;
     
    9285        __address fb_addr;
    9386        int a=0;
    94 
    95 
    96         if(!sysinfo_value("fb")) return -1;
    97        
     87        int i,j,k;
     88        int w;
     89        char text[]="HelenOS Framebuffer driver\non Virtual Framebuffer\nVFB ";
     90
    9891        fb_ph_addr=sysinfo_value("fb.address.physical");
    9992        fb_width=sysinfo_value("fb.width");
     
    10598
    10699
    107 
     100       
    108101        map_physmem(task_get_id(),(void *)((__address)fb_ph_addr),(void *)fb_addr,
    109                 (fb_scanline*fb_height+PAGE_SIZE-1)>>PAGE_WIDTH,1);
     102                    (fb_scanline*fb_height+PAGE_SIZE-1)>>PAGE_WIDTH,1);
    110103       
    111104        fb_init(0,fb_addr, fb_width, fb_height, fb_bpp, fb_scanline,
     
    115108        fb_putchar(0,' ');
    116109
    117 
    118         {
    119                 int i,j;
    120 
    121                 for(i=0;i<H_NO_VFBS;i++)
    122                         for(j=0;j<V_NO_VFBS;j++)
    123                         {
    124        
    125                                 int w=create_window(0,(fb_width/H_NO_VFBS)*i+SPACING,
    126                                         (fb_height/V_NO_VFBS)*j+SPACING,(fb_width/H_NO_VFBS)-2*SPACING ,
    127                                                 (fb_height/V_NO_VFBS)-2*SPACING,mod_col(DEFAULT_BGCOLOR,/*i+j*H_NO_VFBS*/0),
    128                                                         mod_col(DEFAULT_FGCOLOR,/*i+j*H_NO_VFBS*/0),
    129                                                                 mod_col(DEFAULT_LOGOCOLOR,/*i+j*H_NO_VFBS)*/0));
    130 
    131                                 if(w==EFB) return -1;
    132 
    133                                 {
    134                                         char text[]="Hello, World from\nHelenOS Framebuffer driver\non Virtual Framebuffer\nVFB ";
    135                                         int i;
    136                                         for(i=0;text[i];i++) fb_putchar(w,text[i]);
    137                                         fb_putchar(w,w+'0');
    138                                         fb_putchar(w,'\n');
    139                                 }
    140                         }
     110        for(i=0;i<H_NO_VFBS;i++)
     111                for(j=0;j<V_NO_VFBS;j++) {
     112                        w = create_window(0,(fb_width/H_NO_VFBS)*i+SPACING,
     113                                          (fb_height/V_NO_VFBS)*j+SPACING,(fb_width/H_NO_VFBS)-2*SPACING ,
     114                                          (fb_height/V_NO_VFBS)-2*SPACING,mod_col(DEFAULT_BGCOLOR,/*i+j*H_NO_VFBS*/0),
     115                                          mod_col(DEFAULT_FGCOLOR,/*i+j*H_NO_VFBS*/0),
     116                                          mod_col(DEFAULT_LOGOCOLOR,/*i+j*H_NO_VFBS)*/0));
     117                       
     118                        if( w== EFB)
     119                                return -1;
     120                       
     121                        for(k=0;text[k];k++)
     122                                fb_putchar(w,text[k]);
     123                        fb_putchar(w,w+'0');
     124                        fb_putchar(w,'\n');
     125                }
     126        return 0;
     127}
     128
     129int vfb_no = 1;
     130void client_connection(ipc_callid_t iid, ipc_call_t *icall)
     131{
     132        ipc_callid_t callid;
     133        ipc_call_t call;
     134        int vfb = vfb_no++;
     135
     136        if (vfb > 9) {
     137                ipc_answer_fast(iid, ELIMIT, 0,0);
     138                return;
    141139        }
    142 
    143 
     140        ipc_answer_fast(iid, 0, 0, 0);
     141
     142        while (1) {
     143                callid = async_get_call(&call);
     144                switch (IPC_GET_METHOD(call)) {
     145                case IPC_M_PHONE_HUNGUP:
     146                        ipc_answer_fast(callid,0,0,0);
     147                        return; /* Exit thread */
     148
     149                case FB_PUTCHAR:
     150                        ipc_answer_fast(callid,0,0,0);
     151                        fb_putchar(vfb,IPC_GET_ARG2(call));
     152                        break;
     153                default:
     154                        ipc_answer_fast(callid,ENOENT,0,0);
     155                }
     156        }
     157}
     158
     159int main(int argc, char *argv[])
     160{
    144161        ipc_call_t call;
    145162        ipc_callid_t callid;
     
    151168        ipcarg_t retval, arg1, arg2;
    152169
     170        if(!sysinfo_value("fb")) return -1;
    153171
    154172
    155173        if ((res = ipc_connect_to_me(PHONE_NS, SERVICE_VIDEO, 0, &phonead)) != 0)
    156         {
    157174                return -1;
    158         };
    159 
    160                
    161         while (1) {
    162                 static int vfb_no=1;
    163 
    164                 callid = ipc_wait_for_call(&call);
    165         //      printf("%s:Call phone=%lX..", NAME, call.in_phone_hash);
    166                 switch (IPC_GET_METHOD(call)&((1<<METHOD_WIDTH)-1)) {
    167                         case IPC_M_PHONE_HUNGUP:
    168 //                              fb_putchar(4,((a++)&15)+'A');
    169                                
    170                                 retval = 0;
    171                                 break;
    172                         case IPC_M_CONNECT_ME_TO:
    173                                         retval = 0;
    174 //                              fb_putchar(1,((a++)&15)+'A');
    175                                 break;
    176                         case FB_GET_VFB:
    177                                 retval = 0;
    178                                 arg1 = vfb_no++;       
    179 //                              fb_putchar(2,((a++)&15)+'A');
    180                                
    181                                 break;
    182 
    183                         case FB_PUTCHAR:
    184                                 retval = 0;
    185                                 fb_putchar(IPC_GET_ARG1(call),IPC_GET_ARG2(call));
    186 //                              fb_putchar(2,((a++)&15)+'A');
    187                                 break;
    188 
    189                         default:
    190                                 retval = ENOENT;
    191 //                              fb_putchar(3,((a++)&15)+'A');
    192                                 break;
    193                 }
    194 
    195                 if (! (callid & IPC_CALLID_NOTIFICATION)) {
    196                         ipc_answer_fast(callid, retval, arg1, arg2);
    197                 }
    198         }
    199 
     175       
     176        init_fb();
     177
     178        async_manager();
     179        /* Never reached */
    200180        return 0;
    201181}
     
    310290        FB(item,fbaddress)[startbyte + 0] = BLUE(color, 8);
    311291#endif
    312                                                                                                                                                                                                
    313292
    314293}
     
    372351        for (y = 0; y < FB(item,yres); y++)
    373352        {
    374                 clear_line(item,y); pl
     353                clear_line(item,y);
    375354        }       
    376355}
     
    554533
    555534               
    556         FB(item,fbaddress) = (unsigned char *) addr; pl
    557         FB(item,xres) = x; pl
    558         FB(item,yres) = y; pl
    559         FB(item,scanline) = scan; pl
    560        
    561        
    562         FB(item,rows) = y / FONT_SCANLINES; pl
    563         FB(item,columns) = x / COL_WIDTH; pl
     535        FB(item,fbaddress) = (unsigned char *) addr;
     536        FB(item,xres) = x;
     537        FB(item,yres) = y;
     538        FB(item,scanline) = scan;
     539       
     540       
     541        FB(item,rows) = y / FONT_SCANLINES;
     542        FB(item,columns) = x / COL_WIDTH;
    564543
    565544        FB(item,BGCOLOR)=BGCOLOR;
     
    568547
    569548
    570         clear_screen(item); pl
    571         draw_logo(item,FB(item,xres) - helenos_width, 0); pl
    572         invert_cursor(item); pl
     549        clear_screen(item);
     550        draw_logo(item,FB(item,xres) - helenos_width, 0);
     551        invert_cursor(item);
    573552
    574553}
  • kbd/generic/kbd.c

    r1ee11f4 r80649a91  
    3737#include <kbd.h>
    3838#include <key_buffer.h>
    39 #include <fifo.h>
     39#include <libadt/fifo.h>
    4040
    4141#define NAME "KBD"
  • kbd/generic/key_buffer.c

    r1ee11f4 r80649a91  
    2828
    2929#include <key_buffer.h>
    30 #include <fifo.h>
     30#include <libadt/fifo.h>
    3131
    3232#define KBD_BUFFER_SIZE 128 /**< Size of buffer for pressed keys */
  • libc/Makefile

    r1ee11f4 r80649a91  
    6363        generic/psthread.c \
    6464        generic/sysinfo.c \
    65         generic/ipc.c
     65        generic/ipc.c \
     66        generic/async.c \
     67        generic/libadt/list.o \
     68        generic/libadt/hash_table.o
    6669
    6770ARCH_SOURCES += \
     
    8083        ln -sfn kernel/arch include/arch
    8184        ln -sfn ../arch/$(ARCH)/include include/libarch
    82         ln -sfn ../../libadt/include include/libadt
    8385
    8486-include Makefile.depend
    8587
    8688clean:
    87         -rm -f include/kernel include/arch include/libarch include/libadt libc.a arch/$(ARCH)/_link.ld Makefile.depend
     89        -rm -f include/kernel include/arch include/libarch libc.a arch/$(ARCH)/_link.ld Makefile.depend
    8890        find generic/ arch/$(ARCH)/ -name '*.o' -follow -exec rm \{\} \;
    8991
     
    9294
    9395libc.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS)
    94         $(AR) rc libc.a $(ARCH_OBJECTS) $(GENERIC_OBJECTS)
     96        $(AR) rc libc.a $(LIBS) $(ARCH_OBJECTS) $(GENERIC_OBJECTS)
    9597
    9698arch/$(ARCH)/_link.ld: arch/$(ARCH)/_link.ld.in
  • libc/generic/async.c

    r1ee11f4 r80649a91  
    2727 */
    2828
    29 ipc_wait_t call_func(args)
    30 {
    31 }
    32 
    33 ipc_wait_t fire_function(args)
    34 {
    35         stack = malloc(stacksize);
    36         setup(stack);
    37         add_to_list_of_ready_funcs(stack);
    38         if (threads_waiting_for_message)
    39                 send_message_to_self_to_one_up();
    40 }
    41 
    42 void discard_result(ipc_wait_t funcid)
    43 {
    44 }
    45 
    46 int wait_result(ipc_wait_t funcid);
    47 {
    48         save_context(self);
    49 restart:
    50         if result_available() {
    51                 if in_list_of_ready(self):
    52                         tear_off_list(self);
    53                 return retval;
    54         }
    55         add_to_waitlist_of(funcid);
    56 
    57         take_something_from_list_of_ready();
    58         if something {
    59                
    60                 restore_context(something);
    61         } else { /* nothing */
    62                 wait_for_call();
    63                 if (answer) {
    64                         mark_result_ready();
    65                         put_waiting_thread_to_waitlist();
    66 
    67                         goto restart;
     29/**
     30 * Asynchronous library
     31 *
     32 * The aim of this library is facilitating writing programs utilizing
     33 * the asynchronous nature of Helenos IPC, yet using a normal way
     34 * of programming.
     35 *
     36 * You should be able to write very simple multithreaded programs,
     37 * the async framework will automatically take care of most synchronization
     38 * problems.
     39 *
     40 * Default semantics:
     41 * - send() - send asynchronously. If the kernel refuses to send more
     42 *            messages, [ try to get responses from kernel, if nothing
     43 *            found, might try synchronous ]
     44 *
     45 * Example of use:
     46 *
     47 * 1) Multithreaded client application
     48 *  create_thread(thread1);
     49 *  create_thread(thread2);
     50 *  ...
     51 * 
     52 *  thread1() {
     53 *        conn = ipc_connect_me_to();
     54 *        c1 = send(conn);
     55 *        c2 = send(conn);
     56 *        wait_for(c1);
     57 *        wait_for(c2);
     58 *  }
     59 *
     60 *
     61 * 2) Multithreaded server application
     62 * main() {
     63 *      wait_for_connection(new_connection);
     64 * }
     65 *
     66 *
     67 * new_connection(int connection) {
     68 *       accept(connection);
     69 *       msg = get_msg();
     70 *       handle(msg);
     71 *       answer(msg);
     72 *
     73 *       msg = get_msg();
     74 *       ....
     75 * }
     76 */
     77#include <futex.h>
     78#include <async.h>
     79#include <psthread.h>
     80#include <stdio.h>
     81#include <libadt/hash_table.h>
     82#include <libadt/list.h>
     83#include <ipc/ipc.h>
     84#include <assert.h>
     85#include <errno.h>
     86
     87static atomic_t conn_futex = FUTEX_INITIALIZER;
     88static hash_table_t conn_hash_table;
     89
     90typedef struct {
     91        link_t link;
     92        ipc_callid_t callid;
     93        ipc_call_t call;
     94} msg_t;
     95
     96typedef struct {
     97        link_t link;
     98        ipcarg_t in_phone_hash;         /**< Incoming phone hash. */
     99        link_t msg_queue;              /**< Messages that should be delivered to this thread */
     100        pstid_t ptid;                /**< Thread associated with this connection */
     101        int active;                     /**< If this thread is currently active */
     102        int opened;                    /* If the connection was accepted */
     103        /* Structures for connection opening packet */
     104        ipc_callid_t callid;
     105        ipc_call_t call;
     106} connection_t;
     107
     108__thread connection_t *PS_connection;
     109
     110/* Hash table functions */
     111
     112#define ASYNC_HASH_TABLE_CHAINS 32
     113
     114static hash_index_t conn_hash(unsigned long *key)
     115{
     116        assert(key);
     117        return ((*key) >> 4) % ASYNC_HASH_TABLE_CHAINS;
     118}
     119
     120static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item)
     121{
     122        connection_t *hs;
     123
     124        hs = hash_table_get_instance(item, connection_t, link);
     125       
     126        return key[0] == hs->in_phone_hash;
     127}
     128
     129static void conn_remove(link_t *item)
     130{
     131        free(hash_table_get_instance(item, connection_t, link));
     132}
     133
     134
     135/** Operations for NS hash table. */
     136static hash_table_operations_t conn_hash_table_ops = {
     137        .hash = conn_hash,
     138        .compare = conn_compare,
     139        .remove_callback = conn_remove
     140};
     141
     142/** Try to route a call to an appropriate connection thread
     143 *
     144 */
     145static int route_call(ipc_callid_t callid, ipc_call_t *call)
     146{
     147        connection_t *conn;
     148        msg_t *msg;
     149        link_t *hlp;
     150        unsigned long key;
     151
     152        futex_down(&conn_futex);
     153
     154        key = call->in_phone_hash;
     155        hlp = hash_table_find(&conn_hash_table, &key);
     156        if (!hlp) {
     157                futex_up(&conn_futex);
     158                return 0;
     159        }
     160        conn = hash_table_get_instance(hlp, connection_t, link);
     161
     162        msg = malloc(sizeof(*msg));
     163        msg->callid = callid;
     164        msg->call = *call;
     165        list_append(&msg->link, &conn->msg_queue);
     166       
     167        if (!conn->active) {
     168                conn->active = 1;
     169                psthread_add_ready(conn->ptid);
     170        }
     171
     172        futex_up(&conn_futex);
     173
     174        return 1;
     175}
     176
     177ipc_callid_t async_get_call(ipc_call_t *call)
     178{
     179        msg_t *msg;
     180        ipc_callid_t callid;
     181        connection_t *conn;
     182       
     183        futex_down(&conn_futex);
     184
     185        conn = PS_connection;
     186        /* If nothing in queue, wait until something appears */
     187        if (list_empty(&conn->msg_queue)) {
     188                conn->active = 0;
     189                psthread_schedule_next_adv(PS_TO_MANAGER);
     190        }
     191       
     192        msg = list_get_instance(conn->msg_queue.next, msg_t, link);
     193        list_remove(&msg->link);
     194        callid = msg->callid;
     195        *call = msg->call;
     196        free(msg);
     197       
     198        futex_up(&conn_futex);
     199        return callid;
     200}
     201
     202void client_connection(ipc_callid_t callid, ipc_call_t *call)
     203{
     204        printf("Got connection - no handler.\n");
     205        _exit(1);
     206}
     207
     208static int connection_thread(void  *arg)
     209{
     210        /* Setup thread local connection pointer */
     211        PS_connection = (connection_t *)arg;
     212        client_connection(PS_connection->callid, &PS_connection->call);
     213
     214        futex_down(&conn_futex);
     215        /* TODO: remove myself from connection hash table */
     216        futex_up(&conn_futex);
     217        /* TODO: answer all unanswered messages in queue with
     218         *       EHANGUP */
     219}
     220
     221/** Create new thread for a new connection
     222 *
     223 * Creates new thread for connection, fills in connection
     224 * structures and inserts it into the hash table, so that
     225 * later we can easily do routing of messages to particular
     226 * threads.
     227 */
     228static void new_connection(ipc_callid_t callid, ipc_call_t *call)
     229{
     230        pstid_t ptid;
     231        connection_t *conn;
     232        unsigned long key;
     233
     234        conn = malloc(sizeof(*conn));
     235        if (!conn) {
     236                ipc_answer_fast(callid, ENOMEM, 0, 0);
     237                return;
     238        }
     239        conn->in_phone_hash = IPC_GET_ARG3(*call);
     240        list_initialize(&conn->msg_queue);
     241        conn->opened = 0;
     242        conn->ptid = psthread_create(connection_thread, conn);
     243        conn->callid = callid;
     244        conn->call = *call;
     245        conn->active = 1; /* We will activate it asap */
     246        list_initialize(&conn->link);
     247        if (!conn->ptid) {
     248                free(conn);
     249                ipc_answer_fast(callid, ENOMEM, 0, 0);
     250                return;
     251        }
     252        key = conn->in_phone_hash;
     253        futex_down(&conn_futex);
     254        /* Add connection to hash table */
     255        hash_table_insert(&conn_hash_table, &key, &conn->link);
     256        futex_up(&conn_futex);
     257
     258        psthread_add_ready(conn->ptid);
     259}
     260
     261/** Handle call to a task */
     262static void handle_call(ipc_callid_t callid, ipc_call_t *call)
     263{
     264        if (route_call(callid, call))
     265                return;
     266
     267        switch (IPC_GET_METHOD(*call)) {
     268        case IPC_M_INTERRUPT:
     269                break;
     270        case IPC_M_CONNECT_ME_TO:
     271                /* Open new connection with thread etc. */
     272                new_connection(callid, call);
     273                break;
     274        default:
     275                ipc_answer_fast(callid, EHANGUP, 0, 0);
     276        }
     277}
     278
     279/** Endless loop dispatching incoming calls and answers */
     280int async_manager()
     281{
     282        ipc_call_t call;
     283        ipc_callid_t callid;
     284
     285        while (1) {
     286                if (psthread_schedule_next_adv(PS_FROM_MANAGER)) {
     287                        futex_up(&conn_futex); /* conn_futex is always held
     288                                                * when entering manager thread
     289                                                */
     290                        continue;
    68291                }
    69         }
    70        
    71 }
    72 
    73 
    74 int ipc_call_sync(args)
    75 {
    76         return ipc_wait(call_func(args));
    77 }
     292                callid = ipc_wait_cycle(&call,SYNCH_NO_TIMEOUT,SYNCH_BLOCKING);
     293
     294                if (callid & IPC_CALLID_ANSWERED)
     295                        continue;
     296                handle_call(callid, &call);
     297        }
     298}
     299
     300static int async_manager_thread(void *arg)
     301{
     302        futex_up(&conn_futex); /* conn_futex is always locked when entering
     303                                * manager */
     304        async_manager();
     305}
     306
     307/** Add one manager to manager list */
     308void async_create_manager(void)
     309{
     310        pstid_t ptid;
     311
     312        ptid = psthread_create(async_manager_thread, NULL);
     313        psthread_add_manager(ptid);
     314}
     315
     316/** Remove one manager from manager list */
     317void async_destroy_manager(void)
     318{
     319        psthread_remove_manager();
     320}
     321
     322/** Initialize internal structures needed for async manager */
     323int _async_init(void)
     324{
     325        if (!hash_table_create(&conn_hash_table, ASYNC_HASH_TABLE_CHAINS, 1, &conn_hash_table_ops)) {
     326                printf("%s: cannot create hash table\n", "async");
     327                return ENOMEM;
     328        }
     329       
     330}
  • libc/generic/ipc.c

    r1ee11f4 r80649a91  
    5858LIST_INITIALIZE(queued_calls);
    5959
    60 static atomic_t ipc_futex;
    61 
    62 void _ipc_init(void)
    63 {
    64         futex_initialize(&ipc_futex, 1);
    65 }
     60static atomic_t ipc_futex = FUTEX_INITIALIZER;
    6661
    6762int ipc_call_sync(int phoneid, ipcarg_t method, ipcarg_t arg1,
     
    253248
    254249
    255 /** Unconditionally wait for an IPC call.
     250/** One cycle of ipc wait for call call
    256251 *
    257252 * - dispatch ASYNC reoutines in the background
    258253 * @param call Space where the message is stored
     254 * @param usec Timeout in microseconds
     255 * @param flags Flags passed to SYS_IPC_WAIT (blocking, nonblocking)
    259256 * @return Callid of the answer.
    260257 */
    261 ipc_callid_t ipc_wait_for_call(ipc_call_t *call)
    262 {
    263         ipc_callid_t callid;
    264 
    265         do {
    266                 try_dispatch_queued_calls();
    267 
    268                 callid = __SYSCALL3(SYS_IPC_WAIT, (sysarg_t) call, SYNCH_NO_TIMEOUT, SYNCH_BLOCKING);
    269                 /* Handle received answers */
    270                 if (callid & IPC_CALLID_ANSWERED)
    271                         handle_answer(callid, call);
    272         } while (callid & IPC_CALLID_ANSWERED);
     258ipc_callid_t ipc_wait_cycle(ipc_call_t *call, uint32_t usec, int flags)
     259{
     260        ipc_callid_t callid;
     261
     262        try_dispatch_queued_calls();
     263       
     264        callid = __SYSCALL3(SYS_IPC_WAIT, (sysarg_t) call, usec, flags);
     265        /* Handle received answers */
     266        if (callid & IPC_CALLID_ANSWERED)
     267                handle_answer(callid, call);
    273268
    274269        return callid;
     
    287282
    288283        do {
    289                 try_dispatch_queued_calls();
    290 
    291                 callid = __SYSCALL3(SYS_IPC_WAIT, (sysarg_t) call, usec, SYNCH_BLOCKING);
    292                 /* Handle received answers */
    293                 if (callid & IPC_CALLID_ANSWERED)
    294                         handle_answer(callid, call);
     284                callid = ipc_wait_cycle(call, usec, SYNCH_BLOCKING);
    295285        } while (callid & IPC_CALLID_ANSWERED);
    296286
     
    309299
    310300        do {
    311                 try_dispatch_queued_calls();
    312 
    313                 callid = __SYSCALL3(SYS_IPC_WAIT, (sysarg_t)call, SYNCH_NO_TIMEOUT, SYNCH_NON_BLOCKING);
    314                 /* Handle received answers */
    315                 if (callid & IPC_CALLID_ANSWERED)
    316                         handle_answer(callid, call);
     301                callid = ipc_wait_cycle(call, SYNCH_NO_TIMEOUT, SYNCH_NON_BLOCKING);
    317302        } while (callid & IPC_CALLID_ANSWERED);
    318303
  • libc/generic/libadt/hash_table.c

    r1ee11f4 r80649a91  
    3131 */
    3232
    33 #include <hash_table.h>
    34 #include <list.h>
     33#include <libadt/hash_table.h>
     34#include <libadt/list.h>
    3535#include <unistd.h>
    3636#include <malloc.h>
  • libc/generic/libadt/list.c

    r1ee11f4 r80649a91  
    2727 */
    2828
    29 #include <list.h>
     29#include <libadt/list.h>
    3030
    3131
  • libc/generic/libc.c

    r1ee11f4 r80649a91  
    3434#include <io/stream.h>
    3535#include <ipc/ipc.h>
     36#include <async.h>
    3637
    3738void _exit(int status) {
     
    4041
    4142void __main(void) {
    42         tcb_t *tcb;
    43        
    44         tcb = __make_tls();
    45         __tcb_set(tcb);
    46         psthread_setup(tcb);
    47         _ipc_init();
     43        psthread_data_t *pt;
     44
     45        _async_init();
     46        pt = psthread_setup();
     47        __tcb_set(pt->tcb);
    4848}
    4949
     
    5555
    5656void __exit(void) {
    57         tcb_t *tcb;
    58 
    59         tcb = __tcb_get();
    60         psthread_teardown(tcb->pst_data);
    61         __free_tls(tcb);
     57        psthread_teardown(__tcb_get()->pst_data);
    6258        _exit(0);
    6359}
  • libc/generic/psthread.c

    r1ee11f4 r80649a91  
    3434#include <stdio.h>
    3535#include <kernel/arch/faddr.h>
    36 
     36#include <futex.h>
     37#include <assert.h>
    3738
    3839#ifndef PSTHREAD_INITIAL_STACK_PAGES_NO
     
    4142
    4243static LIST_INITIALIZE(ready_list);
     44static LIST_INITIALIZE(manager_list);
    4345
    4446static void psthread_exit(void) __attribute__ ((noinline));
    4547static void psthread_main(void);
    4648
     49static atomic_t psthread_futex = FUTEX_INITIALIZER;
     50
    4751/** Setup PSthread information into TCB structure */
    48 psthread_data_t * psthread_setup(tcb_t *tcb)
    49 {
    50         psthread_data_t *pt;
     52psthread_data_t * psthread_setup()
     53{
     54        psthread_data_t *pt;
     55        tcb_t *tcb;
     56
     57        tcb = __make_tls();
     58        if (!tcb)
     59                return NULL;
    5160
    5261        pt = malloc(sizeof(*pt));
    5362        if (!pt) {
     63                __free_tls(tcb);
    5464                return NULL;
    5565        }
     
    6373void psthread_teardown(psthread_data_t *pt)
    6474{
     75        __free_tls(pt->tcb);
    6576        free(pt);
    6677}
     
    7384        psthread_data_t *pt;
    7485
    75         if (list_empty(&ready_list)) {
    76                 /* Wait on IPC queue etc... */
    77                 printf("Cannot exit!!!\n");
     86        futex_down(&psthread_futex);
     87
     88        if (!list_empty(&ready_list))
     89                pt = list_get_instance(ready_list.next, psthread_data_t, link);
     90        else if (!list_empty(&manager_list))
     91                pt = list_get_instance(manager_list.next, psthread_data_t, link);
     92        else {
     93                printf("Cannot find suitable psthread to run.\n");
    7894                _exit(0);
    7995        }
    80         pt = list_get_instance(ready_list.next, psthread_data_t, link);
    8196        list_remove(&pt->link);
     97        futex_up(&psthread_futex);
     98
    8299        context_restore(&pt->ctx);
     100        /* Never reached */
    83101}
    84102
     
    99117/** Schedule next userspace pseudo thread.
    100118 *
     119 * @param tomanager If true, we are switching to next ready manager thread
     120 *                  (if none is found, thread is exited)
     121 * @param frommanager If true, we are switching from manager thread
    101122 * @return 0 if there is no ready pseudo thread, 1 otherwise.
    102123 */
    103 int psthread_schedule_next(void)
    104 {
    105         psthread_data_t *pt;
    106 
    107         if (list_empty(&ready_list))
    108                 return 0;
     124int psthread_schedule_next_adv(pschange_type ctype)
     125{
     126        psthread_data_t *pt;
     127        int retval = 0;
     128       
     129        futex_down(&psthread_futex);
     130
     131        if (ctype == PS_PREEMPT && list_empty(&ready_list))
     132                goto ret_0;
     133
     134        if (ctype == PS_FROM_MANAGER && list_empty(&ready_list)) {
     135                goto ret_0;
     136        }
     137        assert(!(ctype == PS_TO_MANAGER && list_empty(&manager_list)));
    109138
    110139        pt = __tcb_get()->pst_data;
    111         if (!context_save(&pt->ctx))
    112                 return 1;
     140        if (!context_save(&pt->ctx))
     141                return 1; // futex_up already done here
     142
     143        if (ctype == PS_PREEMPT)
     144                list_append(&pt->link, &ready_list);
     145        else if (ctype == PS_FROM_MANAGER)
     146                list_append(&pt->link, &manager_list);
    113147       
    114         list_append(&pt->link, &ready_list);
    115         pt = list_get_instance(ready_list.next, psthread_data_t, link);
     148        if (ctype == PS_TO_MANAGER)
     149                pt = list_get_instance(manager_list.next,psthread_data_t, link);
     150        else
     151                pt = list_get_instance(ready_list.next, psthread_data_t, link);
    116152        list_remove(&pt->link);
    117153
     154        futex_up(&psthread_futex);
    118155        context_restore(&pt->ctx);
     156
     157ret_0:
     158        futex_up(&psthread_futex);
     159        return retval;
    119160}
    120161
     
    143184
    144185        free(pt->stack);
    145         __free_tls(pt->tcb);
    146186        psthread_teardown((void *)pt);
    147187
     
    150190
    151191/**
    152  * Create a userspace thread and append it to ready list.
     192 * Create a userspace thread
    153193 *
    154194 * @param func Pseudo thread function.
     
    160200{
    161201        psthread_data_t *pt;
    162         tcb_t *tcb;
    163 
    164         tcb = __make_tls();
    165         if (!tcb)
     202
     203        pt = psthread_setup();
     204        if (!pt)
    166205                return 0;
    167 
    168         pt = psthread_setup(tcb);
    169         if (!pt) {
    170                 __free_tls(tcb);
    171                 return 0;
    172         }
    173206        pt->stack = (char *) malloc(PSTHREAD_INITIAL_STACK_PAGES_NO*getpagesize());
    174207
    175208        if (!pt->stack) {
    176                 __free_tls(tcb);
    177209                psthread_teardown(pt);
    178210                return 0;
     
    186218        context_save(&pt->ctx);
    187219        context_set(&pt->ctx, FADDR(psthread_main), pt->stack, PSTHREAD_INITIAL_STACK_PAGES_NO*getpagesize(),
    188                     tcb);
    189 
     220                    pt->tcb);
     221
     222        return (pstid_t )pt;
     223}
     224
     225/** Add a thread to ready list */
     226void psthread_add_ready(pstid_t psthrid)
     227{
     228        psthread_data_t *pt;
     229
     230        pt = (psthread_data_t *) psthrid;
     231        futex_down(&psthread_futex);
    190232        list_append(&pt->link, &ready_list);
    191 
    192         return (pstid_t )pt;
    193 }
     233        futex_up(&psthread_futex);
     234}
     235
     236/** Add a thread to manager list */
     237void psthread_add_manager(pstid_t psthrid)
     238{
     239        psthread_data_t *pt;
     240
     241        pt = (psthread_data_t *) psthrid;
     242
     243        futex_down(&psthread_futex);
     244        list_append(&pt->link, &manager_list);
     245        futex_up(&psthread_futex);
     246}
     247
     248/** Remove one manager from manager list */
     249void psthread_remove_manager()
     250{
     251        futex_down(&psthread_futex);
     252        if (list_empty(&manager_list)) {
     253                printf("No manager found!.\n");
     254                futex_up(&psthread_futex);
     255                return;
     256        }
     257        list_remove(manager_list.next);
     258        futex_up(&psthread_futex);
     259}
  • libc/generic/thread.c

    r1ee11f4 r80649a91  
    3434#include <psthread.h>
    3535#include <string.h>
     36#include <async.h>
    3637
    3738#include <stdio.h>
     
    8182 *
    8283 * @param uarg Pointer to userspace argument structure.
     84 *
     85 * TODO: Thread stack pages memory leak
    8386 */
    8487void __thread_main(uspace_arg_t *uarg)
    8588{
    86         tcb_t *tcb;
    87         /* This should initialize the area according to TLS specicification */
    88         tcb = __make_tls();
    89         __tcb_set(tcb);
    90         psthread_setup(tcb);
     89        psthread_data_t *pt;
     90
     91        pt = psthread_setup();
     92        __tcb_set(pt->tcb);
     93       
     94        async_create_manager();
    9195
    9296        uarg->uspace_thread_function(uarg->uspace_thread_arg);
     
    9498        free(uarg);
    9599
    96         psthread_teardown(tcb->pst_data);
    97         __free_tls(tcb);
     100        async_destroy_manager();
     101        psthread_teardown(pt);
    98102
    99103        thread_exit(0);
  • libc/include/ipc/ipc.h

    r1ee11f4 r80649a91  
    3434#include <libc.h>
    3535#include <types.h>
     36#include <kernel/synch/synch.h>
    3637
    3738typedef sysarg_t ipcarg_t;
     
    5455extern int ipc_call_sync(int phoneid, ipcarg_t method, ipcarg_t arg1,
    5556                         ipcarg_t *result);
    56 extern ipc_callid_t ipc_wait_for_call(ipc_call_t *data);
     57extern ipc_callid_t ipc_wait_cycle(ipc_call_t *call, uint32_t usec, int flags);
    5758extern ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *data, uint32_t usec);
     59static inline ipc_callid_t ipc_wait_for_call(ipc_call_t *data)
     60{
     61        return ipc_wait_for_call_timeout(data, SYNCH_NO_TIMEOUT);
     62}
    5863extern ipc_callid_t ipc_trywait_for_call(ipc_call_t *data);
    5964
     
    7277extern int ipc_unregister_irq(int irq);
    7378extern int ipc_forward_fast(ipc_callid_t callid, int phoneid, int method, ipcarg_t arg1);
    74 extern void _ipc_init(void);
    7579
    7680#endif
  • libc/include/psthread.h

    r1ee11f4 r80649a91  
    4141#endif /* context_set */
    4242
     43typedef enum {
     44        PS_TO_MANAGER,
     45        PS_FROM_MANAGER,
     46        PS_PREEMPT
     47} pschange_type;
     48
    4349typedef sysarg_t pstid_t;
    4450
     
    6268
    6369pstid_t psthread_create(int (*func)(void *), void *arg);
    64 int psthread_schedule_next(void);
    6570int psthread_join(pstid_t psthrid);
    66 psthread_data_t * psthread_setup(tcb_t *tcb);
     71psthread_data_t * psthread_setup(void);
    6772void psthread_teardown(psthread_data_t *pt);
     73int psthread_schedule_next_adv(pschange_type ctype);
     74void psthread_add_ready(pstid_t ptid);
     75void psthread_add_manager(pstid_t psthrid);
     76void psthread_remove_manager(void);
     77
     78static inline int psthread_schedule_next() {
     79        return psthread_schedule_next_adv(PS_PREEMPT);
     80}
    6881
    6982
  • ns/Makefile

    r1ee11f4 r80649a91  
    3131
    3232LIBC_PREFIX = ../libc
    33 LIBADT_PREFIX = ../libadt
    3433SOFTINT_PREFIX = ../softint
    3534include $(LIBC_PREFIX)/Makefile.toolchain
    3635
    37 LIBS = $(LIBADT_PREFIX)/libadt.a $(LIBC_PREFIX)/libc.a
     36LIBS = $(LIBC_PREFIX)/libc.a
    3837
    3938## Sources
Note: See TracChangeset for help on using the changeset viewer.