Changeset 84947a4 in mainline


Ignore:
Timestamp:
2007-06-20T20:52:23Z (17 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0eb58f1
Parents:
9ec12fd
Message:

Improve the rd task (not tested):

  • allow more connections
  • support write operation
  • support concurrent requests
  • sanity checks
  • add comments

Please review.

Location:
uspace/rd
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/rd/rd.c

    r9ec12fd r84947a4  
    33 * Copyright (c) 2007 Martin Jelen
    44 * Copyright (c) 2007 Peter Majer
     5 * Copyright (c) 2007 Jakub Jermar
    56 * All rights reserved.
    67 *
     
    5051#include <align.h>
    5152#include <async.h>
     53#include <futex.h>
    5254#include "rd.h"
    5355
     56/** Pointer to the ramdisk's image. */
    5457static void *rd_addr;
    55 static void *fs_addr;
    56 
     58
     59/**
     60 * This futex protects the ramdisk's data.
     61 * If we were to serve multiple requests (read + write or several writes)
     62 * concurrently (i.e. from two or more threads), each read and write needs to be
     63 * protected by this futex.
     64 */
     65atomic_t rd_futex = FUTEX_INITIALIZER;
     66
     67/** Handle one connection to ramdisk.
     68 *
     69 * @param iid           Hash of the request that opened the connection.
     70 * @param icall         Call data of the request that opened the connection.
     71 */
    5772static void rd_connection(ipc_callid_t iid, ipc_call_t *icall)
    5873{
     
    6075        ipc_call_t call;
    6176        int retval;
    62 
    63         ipc_answer_fast(iid, 0, 0, 0);
     77        uintptr_t fs_va = NULL;
    6478        ipcarg_t offset;
    6579
     80        /*
     81         * We allocate VA for communication per connection.
     82         * This allows us to potentionally have more clients and work
     83         * concurrently.
     84         */
     85        fs_va = as_get_mappable_page(ALIGN_UP(BLOCK_SIZE, PAGE_SIZE));
     86        if (!fs_va) {
     87                /*
     88                 * Hang up the phone if we cannot proceed any further.
     89                 * This is the answer to the call that opened the connection.
     90                 */
     91                ipc_answer_fast(iid, EHANGUP, 0, 0);
     92                return;
     93        } else {
     94                /*
     95                 * Answer the first IPC_M_CONNECT_ME_TO call.
     96                 * Return supported block size as ARG1.
     97                 */
     98                ipc_answer_fast(iid, EOK, BLOCK_SIZE, 0);
     99        }
     100
     101        /*
     102         * Now we wait for the client to send us its communication as_area.
     103         */
     104        callid = async_get_call(&call);
     105        if (IPC_GET_METHOD(call) == IPC_M_AS_AREA_SEND) {
     106                if (IPC_GET_ARG1(call) >= (ipcarg_t) BLOCK_SIZE) {
     107                        /*
     108                         * The client sends an as_area that can absorb the whole
     109                         * block.
     110                         */
     111                        ipc_answer_fast(callid, EOK, (uintptr_t) fs_va, 0);
     112                } else {
     113                        /*
     114                         * The client offered as_area too small.
     115                         * Close the connection.
     116                         */
     117                        ipc_answer_fast(callid, EHANGUP, 0, 0);
     118                        return;         
     119                }
     120        } else {
     121                /*
     122                 * The client doesn't speak the same protocol.
     123                 * At this point we can't handle protocol variations.
     124                 * Close the connection.
     125                 */
     126                ipc_answer_fast(callid, EHANGUP, 0, 0);
     127                return;
     128        }
     129       
    66130        while (1) {
    67131                callid = async_get_call(&call);
    68132                switch (IPC_GET_METHOD(call)) {
    69133                case IPC_M_PHONE_HUNGUP:
    70                         ipc_answer_fast(callid, 0, 0, 0);
     134                        /*
     135                         * The other side has hung up.
     136                         * Answer the message and exit the pseudo thread.
     137                         */
     138                        ipc_answer_fast(callid, EOK, 0, 0);
    71139                        return;
    72                 case IPC_M_AS_AREA_SEND:
    73                         ipc_answer_fast(callid, 0, (uintptr_t) fs_addr, 0);
    74                         continue;
    75                 case RD_READ_BLOCK:                     
     140                case RD_READ_BLOCK:
    76141                        offset = IPC_GET_ARG1(call);
    77                         memcpy((void *) fs_addr, rd_addr + offset, BLOCK_SIZE);
     142                        futex_down(&rd_futex);
     143                        memcpy((void *) fs_va, rd_addr + offset, BLOCK_SIZE);
     144                        futex_up(&rd_futex);
     145                        retval = EOK;
     146                        break;
     147                case RD_WRITE_BLOCK:
     148                        offset = IPC_GET_ARG1(call);
     149                        futex_up(&rd_futex);
     150                        memcpy(rd_addr + offset, (void *) fs_va, BLOCK_SIZE);
     151                        futex_down(&rd_futex);
    78152                        retval = EOK;
    79153                        break;
    80154                default:
     155                        /*
     156                         * The client doesn't speak the same protocol.
     157                         * Instead of closing the connection, we just ignore
     158                         * the call. This can be useful if the client uses a
     159                         * newer version of the protocol.
     160                         */
    81161                        retval = EINVAL;
     162                        break;
    82163                }
    83164                ipc_answer_fast(callid, retval, 0, 0);
     
    85166}
    86167
    87 
     168/** Prepare the ramdisk image for operation. */
    88169static bool rd_init(void)
    89170{
     
    104185        if (retval < 0)
    105186                return false;
    106        
    107         size_t fs_size = ALIGN_UP(BLOCK_SIZE * sizeof(char), PAGE_SIZE);
    108         fs_addr = as_get_mappable_page(fs_size);
    109 
    110187        return true;
    111188}
  • uspace/rd/rd.h

    r9ec12fd r84947a4  
    33 * Copyright (c) 2007 Martin Jelen
    44 * Copyright (c) 2007 Peter Majer
     5 * Copyright (c) 2007 Jakub Jermar
    56 * All rights reserved.
    67 *
     
    4041/* Basic constants. */
    4142
    42 #ifndef _RD_H
    43 #define _RD_H
     43#ifndef RD_RD_H_
     44#define RD_RD_H_
    4445
    45 #define BLOCK_SIZE      1024  /**< Working block size */
     46#define BLOCK_SIZE      1024    /**< Working block size */
    4647
    47 #define RD_OFFSET       100 /**< IPC Message offset */
     48#define RD_BASE         1024
     49#define RD_READ_BLOCK   (RD_BASE + 1)   /**< Method for reading block. */
     50#define RD_WRITE_BLOCK  (RD_BASE + 2)   /**< Method for writing block. */
    4851
    49 #define RD_BASE         (FIRST_USER_METHOD + RD_OFFSET)  /**< IPC Index of the first RD message */
    50 #define RD_READ_BLOCK   (RD_BASE + 1) /**< IPC Index of the RD_READ_BLOCK message */
    51 
    52 #endif /* _RD_H */
     52#endif
Note: See TracChangeset for help on using the changeset viewer.