Changeset e74cb73 in mainline


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.

Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • Makefile

    r27810c5 re74cb73  
    135135        generic/src/synch/waitq.c \
    136136        generic/src/smp/ipi.c \
    137         generic/src/ipc/ipc.c
     137        generic/src/ipc/ipc.c \
     138        generic/src/ipc/ns.c
    138139
    139140## Test sources
  • generic/include/ipc/ipc.h

    r27810c5 re74cb73  
    3030#define __IPC_H__
    3131
    32 #define IPC_CALL_LEN    2
     32/* Length of data being transfered with IPC call */
     33/* - the uspace may not be able to utilize full length */
     34#define IPC_CALL_LEN    4
    3335
    3436/* Flags for calls */
    35 #define IPC_CALL_ANSWERED    1
     37#define IPC_CALL_ANSWERED      1 /**< This is answer to a call */
     38#define IPC_CALL_STATIC_ALLOC  2 /**< This call will not be freed on error */
     39
    3640/* Flags for ipc_wait_for_call */
    37 #define IPC_WAIT_NONBLOCKING 1
     41#define IPC_WAIT_NONBLOCKING   1
     42
     43/* Flags of callid */
     44#define IPC_CALLID_ANSWERED  1
     45
     46/* Return values from IPC_ASYNC */
     47#define IPC_CALLRET_FATAL         -1
     48#define IPC_CALLRET_TEMPORARY     -2
     49
     50
     51/* Macros for manipulating calling data */
     52#define IPC_SET_RETVAL(data, retval)   ((data)[0] = (retval))
     53#define IPC_SET_METHOD(data, val)   ((data)[0] = (val))
     54#define IPC_SET_ARG1(data, val)   ((data)[1] = (val))
     55#define IPC_SET_ARG2(data, val)   ((data)[2] = (val))
     56#define IPC_SET_ARG3(data, val)   ((data)[3] = (val))
     57
     58#define IPC_GET_METHOD(data)           ((data)[0])
     59#define IPC_GET_RETVAL(data)           ((data)[0])
     60
     61#define IPC_GET_ARG1(data)              ((data)[1])
     62#define IPC_GET_ARG2(data)              ((data)[2])
     63#define IPC_GET_ARG3(data)              ((data)[3])
     64
     65/* Well known phone descriptors */
     66#define PHONE_NS              0
    3867
    3968#ifdef KERNEL
    4069
    41 #include <synch/waitq.h>
    42 #include <synch/spinlock.h>
     70#include <synch/mutex.h>
     71#include <synch/condvar.h>
    4372#include <adt/list.h>
    4473
     
    5887        SPINLOCK_DECLARE(lock);
    5988
    60         waitq_t wq;
     89        mutex_t mutex;
     90        condvar_t cv;
    6191
    6292        link_t connected_phones; /**< Phones connected to this answerbox */
     
    73103} phone_t;
    74104
    75 extern void ipc_create_phonecompany(void);
    76105extern void ipc_init(void);
    77106extern call_t * ipc_wait_for_call(answerbox_t *box, int flags);
     
    83112extern void ipc_call_free(call_t *call);
    84113extern call_t * ipc_call_alloc(void);
    85 void ipc_answerbox_init(answerbox_t *box);
    86 void ipc_phone_init(phone_t *phone, answerbox_t *box);
     114extern void ipc_answerbox_init(answerbox_t *box);
     115extern void ipc_phone_init(phone_t *phone, answerbox_t *box);
     116extern void ipc_call_init(call_t *call);
    87117
    88 extern answerbox_t *ipc_central_box;
     118extern answerbox_t *ipc_phone_0;
    89119
    90120#endif
  • generic/include/mm/page.h

    r27810c5 re74cb73  
    6868}
    6969
    70 static inline void copy_to_kernel(void *dst, void *src, count_t cnt)
     70static inline void copy_from_uspace(void *dst, void *src, count_t cnt)
    7171{
    7272        memcpy(dst, src, cnt);
  • generic/include/syscall/syscall.h

    r27810c5 re74cb73  
    3434        SYS_IO,
    3535        SYS_IPC_CALL_SYNC,
     36        SYS_IPC_CALL_SYNC_MEDIUM,
    3637        SYS_IPC_CALL_ASYNC,
    3738        SYS_IPC_ANSWER,
  • 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.