Ignore:
Timestamp:
2010-10-24T21:32:54Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
57f737a
Parents:
95e3fd0b
Message:

Cleanup libpacket.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/packet/generic/packet_server.c

    r95e3fd0b r515a00da  
    2727 */
    2828
    29 /** @addtogroup packet
     29/** @addtogroup libpacket
    3030 *  @{
    3131 */
    3232
    3333/** @file
    34  *  Packet server implementation.
    35  */
     34 * Packet server implementation.
     35 */
     36
     37#include <packet_server.h>
     38#include <packet_local.h>
    3639
    3740#include <align.h>
     
    5154#include <net/packet_header.h>
    5255
    53 #include <packet_server.h>
    54 #include <packet_local.h>
    55 
    5656#define FREE_QUEUES_COUNT       7
    5757
    58 /** The default address length reserved for new packets.
    59  */
     58/** The default address length reserved for new packets. */
    6059#define DEFAULT_ADDR_LEN        32
    6160
    62 /** The default prefix reserved for new packets.
    63  */
     61/** The default prefix reserved for new packets. */
    6462#define DEFAULT_PREFIX          64
    6563
    66 /** The default suffix reserved for new packets.
    67  */
     64/** The default suffix reserved for new packets. */
    6865#define DEFAULT_SUFFIX          64
    6966
    70 /** Packet server global data.
    71  */
    72 static struct{
    73         /** Safety lock.
    74          */
     67/** Packet server global data. */
     68static struct {
     69        /** Safety lock. */
    7570        fibril_mutex_t lock;
    76         /** Free packet queues.
    77          */
     71        /** Free packet queues. */
    7872        packet_t free[FREE_QUEUES_COUNT];
    79         /** Packet length upper bounds of the free packet queues.
    80          *  The maximal lengths of packets in each queue in the ascending order.
    81          *  The last queue is not limited.
     73       
     74        /**
     75         * Packet length upper bounds of the free packet queues. The maximal
     76         * lengths of packets in each queue in the ascending order. The last
     77         * queue is not limited.
    8278         */
    8379        size_t sizes[FREE_QUEUES_COUNT];
    84         /** Total packets allocated.
    85         */
     80       
     81        /** Total packets allocated. */
    8682        unsigned int count;
    8783} ps_globals = {
    8884        .lock = FIBRIL_MUTEX_INITIALIZER(ps_globals.lock),
    89         .free = {NULL, NULL, NULL, NULL, NULL, NULL, NULL},
    90         .sizes = {PAGE_SIZE, PAGE_SIZE * 2, PAGE_SIZE * 4, PAGE_SIZE * 8, PAGE_SIZE * 16, PAGE_SIZE * 32, PAGE_SIZE * 64},
     85        .free = {
     86                NULL,
     87                NULL,
     88                NULL,
     89                NULL,
     90                NULL,
     91                NULL,
     92                NULL
     93        },
     94        .sizes = {
     95                PAGE_SIZE,
     96                PAGE_SIZE * 2,
     97                PAGE_SIZE * 4,
     98                PAGE_SIZE * 8,
     99                PAGE_SIZE * 16,
     100                PAGE_SIZE * 32,
     101                PAGE_SIZE * 64
     102        },
    91103        .count = 0
    92104};
     
    102114
    103115/** Clears and initializes the packet according to the given dimensions.
    104  *  @param[in] packet The packet to be initialized.
    105  *  @param[in] addr_len The source and destination addresses maximal length in bytes.
    106  *  @param[in] max_prefix The maximal prefix length in bytes.
    107  *  @param[in] max_content The maximal content length in bytes.
    108  *  @param[in] max_suffix The maximal suffix length in bytes.
    109  */
    110 static void packet_init(packet_t packet, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){
     116 *
     117 * @param[in] packet    The packet to be initialized.
     118 * @param[in] addr_len  The source and destination addresses maximal length in
     119 *                      bytes.
     120 * @param[in] max_prefix The maximal prefix length in bytes.
     121 * @param[in] max_content The maximal content length in bytes.
     122 * @param[in] max_suffix The maximal suffix length in bytes.
     123 */
     124static void
     125packet_init(packet_t packet, size_t addr_len, size_t max_prefix,
     126    size_t max_content, size_t max_suffix)
     127{
    111128        // clear the packet content
    112         bzero(((void *) packet) + sizeof(struct packet), packet->length - sizeof(struct packet));
     129        bzero(((void *) packet) + sizeof(struct packet),
     130            packet->length - sizeof(struct packet));
     131       
    113132        // clear the packet header
    114133        packet->order = 0;
     
    125144}
    126145
    127 /** Creates a&nbsp;new packet of dimensions at least as given.
    128  *  Should be used only when the global data are locked.
    129  *  @param[in] length The total length of the packet, including the header, the addresses and the data of the packet.
    130  *  @param[in] addr_len The source and destination addresses maximal length in bytes.
    131  *  @param[in] max_prefix The maximal prefix length in bytes.
    132  *  @param[in] max_content The maximal content length in bytes.
    133  *  @param[in] max_suffix The maximal suffix length in bytes.
    134  *  @returns The packet of dimensions at least as given.
    135  *  @returns NULL if there is not enough memory left.
    136  */
    137 static packet_t packet_create(size_t length, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){
     146/** Creates a new packet of dimensions at least as given.
     147 *
     148 * Should be used only when the global data are locked.
     149 *
     150 * @param[in] length    The total length of the packet, including the header,
     151 *                      the addresses and the data of the packet.
     152 * @param[in] addr_len  The source and destination addresses maximal length in
     153 *                      bytes.
     154 * @param[in] max_prefix The maximal prefix length in bytes.
     155 * @param[in] max_content The maximal content length in bytes.
     156 * @param[in] max_suffix The maximal suffix length in bytes.
     157 * @returns             The packet of dimensions at least as given.
     158 * @returns             NULL if there is not enough memory left.
     159 */
     160static packet_t
     161packet_create(size_t length, size_t addr_len, size_t max_prefix,
     162    size_t max_content, size_t max_suffix)
     163{
    138164        ERROR_DECLARE;
    139165
     
    141167
    142168        // already locked
    143         packet = (packet_t) mmap(NULL, length, PROTO_READ | PROTO_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
    144         if(packet == MAP_FAILED){
     169        packet = (packet_t) mmap(NULL, length, PROTO_READ | PROTO_WRITE,
     170            MAP_SHARED | MAP_ANONYMOUS, 0, 0);
     171        if (packet == MAP_FAILED)
    145172                return NULL;
    146         }
     173
    147174        ++ ps_globals.count;
    148175        packet->packet_id = ps_globals.count;
     
    150177        packet_init(packet, addr_len, max_prefix, max_content, max_suffix);
    151178        packet->magic_value = PACKET_MAGIC_VALUE;
    152         if(ERROR_OCCURRED(pm_add(packet))){
     179        if (ERROR_OCCURRED(pm_add(packet))) {
    153180                munmap(packet, packet->length);
    154181                return NULL;
    155182        }
     183       
    156184        return packet;
    157185}
     
    163191 * Lock the global data during its processing.
    164192 *
    165  * @param[in] addr_len    The source and destination addresses
    166  *                        maximal length in bytes.
    167  * @param[in] max_prefix  The maximal prefix length in bytes.
     193 * @param[in] addr_len  The source and destination addresses maximal length in
     194 *                      bytes.
     195 * @param[in] max_prefix The maximal prefix length in bytes.
    168196 * @param[in] max_content The maximal content length in bytes.
    169  * @param[in] max_suffix  The maximal suffix length in bytes.
    170  *
    171  * @return The packet of dimensions at least as given.
    172  * @return NULL if there is not enough memory left.
    173  *
    174  */
    175 static packet_t packet_get_local(size_t addr_len, size_t max_prefix,
    176     size_t max_content, size_t max_suffix)
    177 {
    178         size_t length = ALIGN_UP(sizeof(struct packet) + 2 * addr_len + max_prefix
    179             + max_content + max_suffix, PAGE_SIZE);
     197 * @param[in] max_suffix The maximal suffix length in bytes.
     198 * @return              The packet of dimensions at least as given.
     199 * @return              NULL if there is not enough memory left.
     200 */
     201static packet_t
     202packet_get_local(size_t addr_len, size_t max_prefix, size_t max_content,
     203    size_t max_suffix)
     204{
     205        size_t length = ALIGN_UP(sizeof(struct packet) + 2 * addr_len +
     206            max_prefix + max_content + max_suffix, PAGE_SIZE);
    180207       
    181208        fibril_mutex_lock(&ps_globals.lock);
     
    185212       
    186213        for (index = 0; index < FREE_QUEUES_COUNT - 1; index++) {
    187                 if (length <= ps_globals.sizes[index]) {
    188                         packet = ps_globals.free[index];
     214                if (length > ps_globals.sizes[index])
     215                        continue;
     216               
     217                packet = ps_globals.free[index];
     218                while (packet_is_valid(packet) && (packet->length < length))
     219                        packet = pm_find(packet->next);
     220               
     221                if (packet_is_valid(packet)) {
     222                        if (packet == ps_globals.free[index])
     223                                ps_globals.free[index] = pq_detach(packet);
     224                        else
     225                                pq_detach(packet);
    189226                       
    190                         while (packet_is_valid(packet) && (packet->length < length))
    191                                 packet = pm_find(packet->next);
     227                        packet_init(packet, addr_len, max_prefix, max_content,
     228                            max_suffix);
     229                        fibril_mutex_unlock(&ps_globals.lock);
    192230                       
    193                         if (packet_is_valid(packet)) {
    194                                 if (packet == ps_globals.free[index])
    195                                         ps_globals.free[index] = pq_detach(packet);
    196                                 else
    197                                         pq_detach(packet);
    198                                
    199                                 packet_init(packet, addr_len, max_prefix, max_content,
    200                                     max_suffix);
    201                                 fibril_mutex_unlock(&ps_globals.lock);
    202                                
    203                                 return packet;
    204                         }
     231                        return packet;
    205232                }
    206233        }
     
    228255/** Release the packet and returns it to the appropriate free packet queue.
    229256 *
    230  *  Should be used only when the global data are locked.
    231  *
    232  *  @param[in] packet The packet to be released.
    233  *
    234  */
    235 static void packet_release(packet_t packet){
     257 * Should be used only when the global data are locked.
     258 *
     259 * @param[in] packet    The packet to be released.
     260 *
     261 */
     262static void packet_release(packet_t packet)
     263{
    236264        int index;
    237265        int result;
    238266
    239         // remove debug dump
    240 //      printf("packet %d released\n", packet->packet_id);
    241         for(index = 0; (index < FREE_QUEUES_COUNT - 1) && (packet->length > ps_globals.sizes[index]); ++ index);
    242         result = pq_add(&ps_globals.free[index], packet, packet->length, packet->length);
     267        for (index = 0; (index < FREE_QUEUES_COUNT - 1) &&
     268            (packet->length > ps_globals.sizes[index]); index++) {
     269                ;
     270        }
     271       
     272        result = pq_add(&ps_globals.free[index], packet, packet->length,
     273            packet->length);
    243274        assert(result == EOK);
    244275}
    245276
    246277/** Releases the packet queue.
    247  *  @param[in] packet_id The first packet identifier.
    248  *  @returns EOK on success.
    249  *  @returns ENOENT if there is no such packet.
    250  */
    251 static int packet_release_wrapper(packet_id_t packet_id){
     278 *
     279 * @param[in] packet_id The first packet identifier.
     280 * @returns             EOK on success.
     281 * @returns             ENOENT if there is no such packet.
     282 */
     283static int packet_release_wrapper(packet_id_t packet_id)
     284{
    252285        packet_t packet;
    253286
    254287        packet = pm_find(packet_id);
    255         if(! packet_is_valid(packet)){
     288        if (!packet_is_valid(packet))
    256289                return ENOENT;
    257         }
     290
    258291        fibril_mutex_lock(&ps_globals.lock);
    259292        pq_destroy(packet, packet_release);
    260293        fibril_mutex_unlock(&ps_globals.lock);
     294
    261295        return EOK;
    262296}
     
    268302
    269303/** Shares the packet memory block.
    270  *  @param[in] packet The packet to be shared.
    271  *  @returns EOK on success.
    272  *  @returns EINVAL if the packet is not valid.
    273  *  @returns EINVAL if the calling module does not accept the memory.
    274  *  @returns ENOMEM if the desired and actual sizes differ.
    275  *  @returns Other error codes as defined for the async_share_in_finalize() function.
    276  */
    277 static int packet_reply(const packet_t packet){
     304 * @param[in] packet    The packet to be shared.
     305 * @returns             EOK on success.
     306 * @returns             EINVAL if the packet is not valid.
     307 * @returns             EINVAL if the calling module does not accept the memory.
     308 * @returns             ENOMEM if the desired and actual sizes differ.
     309 * @returns             Other error codes as defined for the
     310 *                      async_share_in_finalize() function.
     311 */
     312static int packet_reply(const packet_t packet)
     313{
    278314        ipc_callid_t callid;
    279315        size_t size;
    280316
    281         if(! packet_is_valid(packet)){
     317        if (!packet_is_valid(packet))
    282318                return EINVAL;
     319
     320        if (size != packet->length)
     321                return ENOMEM;
     322
     323        if (!async_share_in_receive(&callid, &size))
     324                return EINVAL;
     325       
     326        return async_share_in_finalize(callid, packet,
     327            PROTO_READ | PROTO_WRITE);
     328}
     329
     330/** Processes the packet server message.
     331 *
     332 * @param[in] callid    The message identifier.
     333 * @param[in] call      The message parameters.
     334 * @param[out] answer   The message answer parameters.
     335 * @param[out] answer_count The last parameter for the actual answer in the
     336 *                      answer parameter.
     337 * @returns             EOK on success.
     338 * @returns             ENOMEM if there is not enough memory left.
     339 * @returns             ENOENT if there is no such packet as in the packet
     340 *                      message parameter.
     341 * @returns             ENOTSUP if the message is not known.
     342 * @returns             Other error codes as defined for the
     343 *                      packet_release_wrapper() function.
     344 */
     345int
     346packet_server_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
     347    int *answer_count)
     348{
     349        packet_t packet;
     350
     351        *answer_count = 0;
     352        switch (IPC_GET_METHOD(*call)) {
     353        case IPC_M_PHONE_HUNGUP:
     354                return EOK;
     355       
     356        case NET_PACKET_CREATE_1:
     357                packet = packet_get_local(DEFAULT_ADDR_LEN, DEFAULT_PREFIX,
     358                    IPC_GET_CONTENT(call), DEFAULT_SUFFIX);
     359                if (!packet)
     360                        return ENOMEM;
     361                *answer_count = 2;
     362                IPC_SET_ARG1(*answer, (ipcarg_t) packet->packet_id);
     363                IPC_SET_ARG2(*answer, (ipcarg_t) packet->length);
     364                return EOK;
     365       
     366        case NET_PACKET_CREATE_4:
     367                packet = packet_get_local(
     368                    ((DEFAULT_ADDR_LEN < IPC_GET_ADDR_LEN(call)) ?
     369                    IPC_GET_ADDR_LEN(call) : DEFAULT_ADDR_LEN),
     370                    DEFAULT_PREFIX + IPC_GET_PREFIX(call),
     371                    IPC_GET_CONTENT(call),
     372                    DEFAULT_SUFFIX + IPC_GET_SUFFIX(call));
     373                if (!packet)
     374                        return ENOMEM;
     375                *answer_count = 2;
     376                IPC_SET_ARG1(*answer, (ipcarg_t) packet->packet_id);
     377                IPC_SET_ARG2(*answer, (ipcarg_t) packet->length);
     378                return EOK;
     379       
     380        case NET_PACKET_GET:
     381                packet = pm_find(IPC_GET_ID(call));
     382                if (!packet_is_valid(packet))
     383                        return ENOENT;
     384                return packet_reply(packet);
     385       
     386        case NET_PACKET_GET_SIZE:
     387                packet = pm_find(IPC_GET_ID(call));
     388                if (!packet_is_valid(packet))
     389                        return ENOENT;
     390                IPC_SET_ARG1(*answer, (ipcarg_t) packet->length);
     391                *answer_count = 1;
     392                return EOK;
     393       
     394        case NET_PACKET_RELEASE:
     395                return packet_release_wrapper(IPC_GET_ID(call));
    283396        }
    284         if(async_share_in_receive(&callid, &size) <= 0) return EINVAL;
    285         if(size != packet->length){
    286                 return ENOMEM;
    287         }
    288         return async_share_in_finalize(callid, packet, PROTO_READ | PROTO_WRITE);
    289 }
    290 
    291 int packet_server_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
    292         packet_t packet;
    293 
    294         *answer_count = 0;
    295         switch(IPC_GET_METHOD(*call)){
    296                 case IPC_M_PHONE_HUNGUP:
    297                         return EOK;
    298                 case NET_PACKET_CREATE_1:
    299                         packet = packet_get_local(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, IPC_GET_CONTENT(call), DEFAULT_SUFFIX);
    300                         if(! packet){
    301                                 return ENOMEM;
    302                         }
    303                         *answer_count = 2;
    304                         IPC_SET_ARG1(*answer, (ipcarg_t) packet->packet_id);
    305                         IPC_SET_ARG2(*answer, (ipcarg_t) packet->length);
    306                         return EOK;
    307                 case NET_PACKET_CREATE_4:
    308                         packet = packet_get_local(((DEFAULT_ADDR_LEN < IPC_GET_ADDR_LEN(call)) ? IPC_GET_ADDR_LEN(call) : DEFAULT_ADDR_LEN), DEFAULT_PREFIX + IPC_GET_PREFIX(call), IPC_GET_CONTENT(call), DEFAULT_SUFFIX + IPC_GET_SUFFIX(call));
    309                         if(! packet){
    310                                 return ENOMEM;
    311                         }
    312                         *answer_count = 2;
    313                         IPC_SET_ARG1(*answer, (ipcarg_t) packet->packet_id);
    314                         IPC_SET_ARG2(*answer, (ipcarg_t) packet->length);
    315                         return EOK;
    316                 case NET_PACKET_GET:
    317                         packet = pm_find(IPC_GET_ID(call));
    318                         if(! packet_is_valid(packet)){
    319                                 return ENOENT;
    320                         }
    321                         return packet_reply(packet);
    322                 case NET_PACKET_GET_SIZE:
    323                         packet = pm_find(IPC_GET_ID(call));
    324                         if(! packet_is_valid(packet)){
    325                                 return ENOENT;
    326                         }
    327                         IPC_SET_ARG1(*answer, (ipcarg_t) packet->length);
    328                         *answer_count = 1;
    329                         return EOK;
    330                 case NET_PACKET_RELEASE:
    331                         return packet_release_wrapper(IPC_GET_ID(call));
    332         }
     397       
    333398        return ENOTSUP;
    334399}
Note: See TracChangeset for help on using the changeset viewer.