Changeset e74cb73 in mainline for generic/src


Ignore:
Timestamp:
2006-03-14T09:30:07Z (19 years ago)
Author:
Ondrej Palkovsky <ondrap@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d1f8a87
Parents:
27810c5
Message:

Added skeleton name service.
Cleanup for IPC to use mutexes instead of spinlocks.

Location:
generic/src
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • generic/src/ipc/ipc.c

    r27810c5 re74cb73  
    3232 */
    3333
    34 #include <synch/waitq.h>
     34#include <synch/condvar.h>
     35#include <synch/mutex.h>
    3536#include <ipc/ipc.h>
    3637#include <errno.h>
     
    4445#include <proc/thread.h>
    4546
    46 answerbox_t *ipc_central_box;
     47/* Open channel that is assigned automatically to new tasks */
     48answerbox_t *ipc_phone_0 = NULL;
    4749
    4850static slab_cache_t *ipc_call_slab;
     
    6466}
    6567
     68/** Initialize allocated call */
     69void ipc_call_init(call_t *call)
     70{
     71        call->callerbox = &TASK->answerbox;
     72        call->flags = IPC_CALL_STATIC_ALLOC;
     73}
     74
    6675/** Deallocate call stracuture */
    6776void ipc_call_free(call_t *call)
     
    7483void ipc_answerbox_init(answerbox_t *box)
    7584{
    76         spinlock_initialize(&box->lock, "abox_lock");
    77         waitq_initialize(&box->wq);
     85        mutex_initialize(&box->mutex);
     86        condvar_initialize(&box->cv);
    7887        list_initialize(&box->connected_phones);
    7988        list_initialize(&box->calls);
     
    8998       
    9099        phone->callee = box;
    91         spinlock_lock(&box->lock);
     100
     101        mutex_lock(&box->mutex);
    92102        list_append(&phone->list, &box->connected_phones);
    93         spinlock_unlock(&box->lock);
     103        mutex_unlock(&box->mutex);
    94104}
    95105
     
    101111        ASSERT(box);
    102112
    103         spinlock_lock(&box->lock);
     113        mutex_lock(&box->mutex);
    104114        list_remove(&phone->list);
    105         spinlock_unlock(&box->lock);
     115        mutex_unlock(&box->mutex);
    106116}
    107117
     
    131141        ASSERT(box);
    132142
    133         spinlock_lock(&box->lock);
     143        mutex_lock(&box->mutex);
    134144        list_append(&request->list, &box->calls);
    135         spinlock_unlock(&box->lock);
    136         waitq_wakeup(&box->wq, 0);
     145        mutex_unlock(&box->mutex);
     146        condvar_signal(&box->cv);
    137147}
    138148
     
    148158        request->flags |= IPC_CALL_ANSWERED;
    149159
    150         spinlock_lock(&box->lock);
    151         spinlock_lock(&callerbox->lock);
    152 
     160        mutex_lock(&box->mutex);
    153161        list_remove(&request->list);
     162        mutex_unlock(&box->mutex);
     163
     164        mutex_lock(&callerbox->mutex);
    154165        list_append(&request->list, &callerbox->answers);
    155         waitq_wakeup(&callerbox->wq, 0);
    156 
    157         spinlock_unlock(&callerbox->lock);
    158         spinlock_unlock(&box->lock);
     166        mutex_unlock(&callerbox->mutex);
     167        condvar_signal(&callerbox->cv);
    159168}
    160169
     
    168177        call_t *request;
    169178
    170         if ((flags & IPC_WAIT_NONBLOCKING)) {
    171                 if (waitq_sleep_timeout(&box->wq,SYNCH_NO_TIMEOUT,SYNCH_NON_BLOCKING) == ESYNCH_WOULD_BLOCK)
    172                         return 0;
    173         } else {
    174                 waitq_sleep(&box->wq);
     179        mutex_lock(&box->mutex);
     180        while (1) {
     181                if (!list_empty(&box->answers)) {
     182                        /* Handle asynchronous answers */
     183                        request = list_get_instance(box->answers.next, call_t, list);
     184                        list_remove(&request->list);
     185                } else if (!list_empty(&box->calls)) {
     186                        /* Handle requests */
     187                        request = list_get_instance(box->calls.next, call_t, list);
     188                        list_remove(&request->list);
     189                        /* Append request to dispatch queue */
     190                        list_append(&request->list, &box->dispatched_calls);
     191                } else {
     192                        if (!(flags & IPC_WAIT_NONBLOCKING)) {
     193                                condvar_wait(&box->cv, &box->mutex);
     194                                continue;
     195                        }
     196                        if (condvar_trywait(&box->cv, &box->mutex) != ESYNCH_WOULD_BLOCK)
     197                                continue;
     198                        request = NULL;
     199                }
     200                break;
    175201        }
    176 
    177 
    178         // TODO - might need condition variable+mutex if we want to support
    179         // removing of requests from queue before dispatch
    180         spinlock_lock(&box->lock);
    181         /* Handle answers first */
    182         if (!list_empty(&box->answers)) {
    183                 request = list_get_instance(box->answers.next, call_t, list);
    184                 list_remove(&request->list);
    185         } else {
    186                 ASSERT (! list_empty(&box->calls));
    187                 request = list_get_instance(box->calls.next, call_t, list);
    188                 list_remove(&request->list);
    189                 /* Append request to dispatch queue */
    190                 list_append(&request->list, &box->dispatched_calls);
    191         }
    192         spinlock_unlock(&box->lock);
    193 
     202        mutex_unlock(&box->mutex);
    194203        return request;
    195204}
     
    203212                                          NULL, NULL, 0);
    204213}
    205 
    206 static void ipc_phonecompany_thread(void *data)
    207 {
    208         call_t *call;
    209 
    210         printf("Phone company started.\n");
    211         while (1) {
    212                 call = ipc_wait_for_call(&TASK->answerbox, 0);
    213                 printf("Received phone call - %P %P\n",
    214                        call->data[0], call->data[1]);
    215                 call->data[0] = 0xbabaaaee;;
    216                 call->data[1] = 0xaaaaeeee;
    217                 ipc_answer(&TASK->answerbox, call);
    218                 printf("Call answered.\n");
    219         }
    220 }
    221 
    222 void ipc_create_phonecompany(void)
    223 {
    224         thread_t *t;
    225        
    226         if ((t = thread_create(ipc_phonecompany_thread, "phonecompany",
    227                                TASK, 0)))
    228                 thread_ready(t);
    229         else
    230                 panic("thread_create/phonecompany");
    231 
    232         ipc_central_box = &TASK->answerbox;
    233 }
  • generic/src/main/kinit.c

    r27810c5 re74cb73  
    4848#include <console/kconsole.h>
    4949#include <elf.h>
     50#include <ipc/ns.h>
    5051
    5152#ifdef CONFIG_SMP
     
    139140        interrupts_enable();
    140141
    141         ipc_create_phonecompany();
     142        /* Initialize name service */
     143        ns_start();
    142144
    143145        if (config.init_size > 0) {
  • generic/src/proc/task.c

    r27810c5 re74cb73  
    3737#include <adt/list.h>
    3838#include <ipc/ipc.h>
     39#include <ipc/ns.h>
    3940#include <memstr.h>
    4041
     
    7677        ipc_answerbox_init(&ta->answerbox);
    7778        memsetb((__address)&ta->phones, sizeof(ta->phones[0])*IPC_MAX_PHONES, 0);
    78         if (ipc_central_box)
    79                 ipc_phone_init(&ta->phones[0], ipc_central_box);
     79        if (ipc_phone_0)
     80                ipc_phone_init(&ta->phones[0], ipc_phone_0);
    8081       
    8182        ipl = interrupts_disable();
  • generic/src/syscall/syscall.c

    r27810c5 re74cb73  
    6161           -2 on 'Too many async request, handle answers first
    6262 */
    63 static __native sys_ipc_call_sync(__native phoneid, __native arg1,
    64                                    __native arg2, __native *respdata)
     63static __native sys_ipc_call_sync(__native phoneid, __native method,
     64                                   __native arg1, __native *data)
    6565{
    66         call_t *call;
     66        call_t call;
    6767        phone_t *phone;
    6868        /* Special answerbox for synchronous messages */
    6969
    7070        if (phoneid >= IPC_MAX_PHONES)
    71                 return -ENOENT;
     71                return IPC_CALLRET_FATAL;
    7272
    7373        phone = &TASK->phones[phoneid];
    7474        if (!phone->callee)
    75                 return -ENOENT;
     75                return IPC_CALLRET_FATAL;
    7676
    77         call = ipc_call_alloc();
    78         call->data[0] = arg1;
    79         call->data[1] = arg2;
     77        ipc_call_init(&call);
     78        IPC_SET_METHOD(call.data, method);
     79        IPC_SET_ARG1(call.data, arg1);
    8080       
    81         ipc_call_sync(phone, call);
     81        ipc_call_sync(phone, &call);
    8282
    83         copy_to_uspace(respdata, &call->data, sizeof(__native) * IPC_CALL_LEN);
     83        copy_to_uspace(data, &call.data, sizeof(call.data));
    8484
    8585        return 0;
    8686}
     87
     88static __native sys_ipc_call_sync_medium(__native phoneid, __native *data)
     89{
     90        call_t call;
     91        phone_t *phone;
     92        /* Special answerbox for synchronous messages */
     93
     94        if (phoneid >= IPC_MAX_PHONES)
     95                return IPC_CALLRET_FATAL;
     96
     97        phone = &TASK->phones[phoneid];
     98        if (!phone->callee)
     99                return IPC_CALLRET_FATAL;
     100
     101        ipc_call_init(&call);
     102        copy_from_uspace(&call.data, data, sizeof(call.data));
     103       
     104        ipc_call_sync(phone, &call);
     105
     106        copy_to_uspace(data, &call.data, sizeof(call.data));
     107
     108        return 0;
     109}
     110
    87111
    88112/** Send an asynchronous call over ipc
     
    91115           -2 on 'Too many async request, handle answers first
    92116 */
    93 static __native sys_ipc_call_async(__native phoneid, __native arg1,
    94                                    __native arg2)
     117static __native sys_ipc_call_async(__native phoneid, __native method,
     118                                   __native arg1, __native arg2)
    95119{
    96120        call_t *call;
     
    98122
    99123        if (phoneid >= IPC_MAX_PHONES)
    100                 return -ENOENT;
     124                return IPC_CALLRET_FATAL;
    101125
    102126        phone = &TASK->phones[phoneid];
    103127        if (!phone->callee)
    104                 return -ENOENT;
    105 
     128                return IPC_CALLRET_FATAL;
    106129
    107130        /* TODO: Check that we did not exceed system imposed maximum
     
    110133         */
    111134        call = ipc_call_alloc();
    112         call->data[0] = arg1;
    113         call->data[1] = arg2;
     135        IPC_SET_METHOD(call->data, method);
     136        IPC_SET_ARG1(call->data, arg1);
     137        IPC_SET_ARG2(call->data, arg2);
     138
    114139        ipc_call(phone, call);
    115140
     
    118143
    119144/** Send IPC answer */
    120 static __native sys_ipc_answer(__native callid, __native arg1, __native arg2)
     145static __native sys_ipc_answer(__native callid, __native retval, __native arg1,
     146                               __native arg2)
    121147{
    122148        call_t *call;
     
    127153        call = (call_t *) callid;
    128154
    129         call->data[0] = arg1;
    130         call->data[1] = arg2;
     155        IPC_SET_RETVAL(call->data, retval);
     156        IPC_SET_ARG1(call->data, arg1);
     157        IPC_SET_ARG2(call->data, arg2);
    131158
    132159        ipc_answer(&TASK->answerbox, call);
     
    145172       
    146173        call = ipc_wait_for_call(&TASK->answerbox, flags);
    147         copy_to_uspace(calldata, &call->data, sizeof(__native) * IPC_CALL_LEN);
    148174
    149         if (call->flags & IPC_CALL_ANSWERED)
    150                 return ((__native)call) | 1;
     175        copy_to_uspace(calldata, &call->data, sizeof(call->data));
     176        if (call->flags & IPC_CALL_ANSWERED) {
     177                ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC));
     178                ipc_call_free(call);
     179                return ((__native)call) | IPC_CALLID_ANSWERED;
     180        }
    151181        return (__native)call;
    152182}
     
    157187        sys_io,
    158188        sys_ipc_call_sync,
     189        sys_ipc_call_sync_medium,
    159190        sys_ipc_call_async,
    160191        sys_ipc_answer,
Note: See TracChangeset for help on using the changeset viewer.