Ignore:
Timestamp:
2010-04-04T21:41:47Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5db9084
Parents:
36a75a2 (diff), ee7e82a9 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 moved

Legend:

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

    r36a75a2 r59ecd4a  
    4545#include <sys/mman.h>
    4646
    47 #include "../../err.h"
    48 #include "../../messages.h"
    49 
    50 #include "packet.h"
    51 #include "packet_client.h"
    52 #include "packet_header.h"
    53 #include "packet_messages.h"
    54 #include "packet_server.h"
     47#include <net_err.h>
     48#include <net_messages.h>
     49#include <packet/packet.h>
     50#include <packet/packet_client.h>
     51#include <packet/packet_header.h>
     52#include <packet/packet_messages.h>
     53#include <packet/packet_server.h>
    5554
    5655#define FREE_QUEUES_COUNT       7
     
    9897};
    9998
    100 /** @name Packet server support functions
    101  */
    102 /*@{*/
    103 
    104 /** Returns the packet of dimensions at least as given.
    105  *  Tries to reuse free packets first.
    106  *  Creates a&nbsp;new packet aligned to the memory page size if none available.
    107  *  Locks the global data during its processing.
    108  *  @param[in] addr_len The source and destination addresses maximal length in bytes.
    109  *  @param[in] max_prefix The maximal prefix length in bytes.
    110  *  @param[in] max_content The maximal content length in bytes.
    111  *  @param[in] max_suffix The maximal suffix length in bytes.
    112  *  @returns The packet of dimensions at least as given.
    113  *  @returns NULL if there is not enough memory left.
    114  */
    115 packet_t packet_get(size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix);
    116 
    117 /** Releases the packet queue.
    118  *  @param[in] packet_id The first packet identifier.
    119  *  @returns EOK on success.
    120  *  @returns ENOENT if there is no such packet.
    121  */
    122 int packet_release_wrapper(packet_id_t packet_id);
    123 
    124 /** Releases the packet and returns it to the appropriate free packet queue.
    125  *  Should be used only when the global data are locked.
    126  *  @param[in] packet The packet to be released.
    127  */
    128 void packet_release(packet_t packet);
    129 
    130 /** Creates a&nbsp;new packet of dimensions at least as given.
    131  *  Should be used only when the global data are locked.
    132  *  @param[in] length The total length of the packet, including the header, the addresses and the data of the packet.
    133  *  @param[in] addr_len The source and destination addresses maximal length in bytes.
    134  *  @param[in] max_prefix The maximal prefix length in bytes.
    135  *  @param[in] max_content The maximal content length in bytes.
    136  *  @param[in] max_suffix The maximal suffix length in bytes.
    137  *  @returns The packet of dimensions at least as given.
    138  *  @returns NULL if there is not enough memory left.
    139  */
    140 packet_t packet_create(size_t length, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix);
     99int packet_translate(int phone, packet_ref packet, packet_id_t packet_id){
     100        if(! packet){
     101                return EINVAL;
     102        }
     103        *packet = pm_find(packet_id);
     104        return (*packet) ? EOK : ENOENT;
     105}
    141106
    142107/** Clears and initializes the packet according to the given dimensions.
     
    147112 *  @param[in] max_suffix The maximal suffix length in bytes.
    148113 */
    149 void packet_init(packet_t packet, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix);
    150 
    151 /** Shares the packet memory block.
    152  *  @param[in] packet The packet to be shared.
    153  *  @returns EOK on success.
    154  *  @returns EINVAL if the packet is not valid.
    155  *  @returns EINVAL if the calling module does not accept the memory.
    156  *  @returns ENOMEM if the desired and actual sizes differ.
    157  *  @returns Other error codes as defined for the async_share_in_finalize() function.
    158  */
    159 int packet_reply(const packet_t packet);
    160 
    161 /*@}*/
    162 
    163 int packet_translate(int phone, packet_ref packet, packet_id_t packet_id){
    164         if(! packet){
    165                 return EINVAL;
    166         }
    167         *packet = pm_find(packet_id);
    168         return (*packet) ? EOK : ENOENT;
    169 }
    170 
    171 packet_t packet_get_4(int phone, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix){
    172         return packet_get(addr_len, max_prefix, max_content, max_suffix);
    173 }
    174 
    175 packet_t packet_get_1(int phone, size_t content){
    176         return packet_get(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, content, DEFAULT_SUFFIX);
    177 }
    178 
    179 void pq_release(int phone, packet_id_t packet_id){
    180         (void) packet_release_wrapper(packet_id);
    181 }
    182 
    183 int packet_server_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
    184         packet_t packet;
    185 
    186         *answer_count = 0;
    187         switch(IPC_GET_METHOD(*call)){
    188                 case IPC_M_PHONE_HUNGUP:
    189                         return EOK;
    190                 case NET_PACKET_CREATE_1:
    191                         packet = packet_get(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, IPC_GET_CONTENT(call), DEFAULT_SUFFIX);
    192                         if(! packet){
    193                                 return ENOMEM;
    194                         }
    195                         *answer_count = 2;
    196                         IPC_SET_ARG1(*answer, (ipcarg_t) packet->packet_id);
    197                         IPC_SET_ARG2(*answer, (ipcarg_t) packet->length);
    198                         return EOK;
    199                 case NET_PACKET_CREATE_4:
    200                         packet = packet_get(((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));
    201                         if(! packet){
    202                                 return ENOMEM;
    203                         }
    204                         *answer_count = 2;
    205                         IPC_SET_ARG1(*answer, (ipcarg_t) packet->packet_id);
    206                         IPC_SET_ARG2(*answer, (ipcarg_t) packet->length);
    207                         return EOK;
    208                 case NET_PACKET_GET:
    209                         packet = pm_find(IPC_GET_ID(call));
    210                         if(! packet_is_valid(packet)){
    211                                 return ENOENT;
    212                         }
    213                         return packet_reply(packet);
    214                 case NET_PACKET_GET_SIZE:
    215                         packet = pm_find(IPC_GET_ID(call));
    216                         if(! packet_is_valid(packet)){
    217                                 return ENOENT;
    218                         }
    219                         IPC_SET_ARG1(*answer, (ipcarg_t) packet->length);
    220                         *answer_count = 1;
    221                         return EOK;
    222                 case NET_PACKET_RELEASE:
    223                         return packet_release_wrapper(IPC_GET_ID(call));
    224         }
    225         return ENOTSUP;
    226 }
    227 
    228 int packet_release_wrapper(packet_id_t packet_id){
    229         packet_t packet;
    230 
    231         packet = pm_find(packet_id);
    232         if(! packet_is_valid(packet)){
    233                 return ENOENT;
    234         }
    235         fibril_mutex_lock(&ps_globals.lock);
    236         pq_destroy(packet, packet_release);
    237         fibril_mutex_unlock(&ps_globals.lock);
    238         return EOK;
    239 }
    240 
    241 void packet_release(packet_t packet){
    242         int index;
    243         int result;
    244 
    245         // remove debug dump
    246 //      printf("packet %d released\n", packet->packet_id);
    247         for(index = 0; (index < FREE_QUEUES_COUNT - 1) && (packet->length > ps_globals.sizes[index]); ++ index);
    248         result = pq_add(&ps_globals.free[index], packet, packet->length, packet->length);
    249         assert(result == EOK);
    250 }
    251 
    252 packet_t packet_get(size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){
    253         int index;
    254         packet_t packet;
    255         size_t length;
    256 
    257         length = ALIGN_UP(sizeof(struct packet) + 2 * addr_len + max_prefix + max_content + max_suffix, PAGE_SIZE);
    258         fibril_mutex_lock(&ps_globals.lock);
    259         for(index = 0; index < FREE_QUEUES_COUNT - 1; ++ index){
    260                 if(length <= ps_globals.sizes[index]){
    261                         packet = ps_globals.free[index];
    262                         while(packet_is_valid(packet) && (packet->length < length)){
    263                                 packet = pm_find(packet->next);
    264                         }
    265                         if(packet_is_valid(packet)){
    266                                 if(packet == ps_globals.free[index]){
    267                                         ps_globals.free[index] = pq_detach(packet);
    268                                 }else{
    269                                         pq_detach(packet);
    270                                 }
    271                                 packet_init(packet, addr_len, max_prefix, max_content, max_suffix);
    272                                 fibril_mutex_unlock(&ps_globals.lock);
    273                                 // remove debug dump
    274 //                              printf("packet %d got\n", packet->packet_id);
    275                                 return packet;
    276                         }
    277                 }
    278         }
    279         packet = packet_create(length, addr_len, max_prefix, max_content, max_suffix);
    280         fibril_mutex_unlock(&ps_globals.lock);
    281         // remove debug dump
    282 //      printf("packet %d created\n", packet->packet_id);
    283         return packet;
    284 }
    285 
    286 packet_t packet_create(size_t length, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){
    287         ERROR_DECLARE;
    288 
    289         packet_t packet;
    290 
    291         // already locked
    292         packet = (packet_t) mmap(NULL, length, PROTO_READ | PROTO_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
    293         if(packet == MAP_FAILED){
    294                 return NULL;
    295         }
    296         ++ ps_globals.count;
    297         packet->packet_id = ps_globals.count;
    298         packet->length = length;
    299         packet_init(packet, addr_len, max_prefix, max_content, max_suffix);
    300         packet->magic_value = PACKET_MAGIC_VALUE;
    301         if(ERROR_OCCURRED(pm_add(packet))){
    302                 munmap(packet, packet->length);
    303                 return NULL;
    304         }
    305         return packet;
    306 }
    307 
    308 void packet_init(packet_t packet, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){
     114static void packet_init(packet_t packet, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){
    309115        // clear the packet content
    310116        bzero(((void *) packet) + sizeof(struct packet), packet->length - sizeof(struct packet));
     
    323129}
    324130
    325 int packet_reply(const packet_t packet){
     131/** Creates a&nbsp;new packet of dimensions at least as given.
     132 *  Should be used only when the global data are locked.
     133 *  @param[in] length The total length of the packet, including the header, the addresses and the data of the packet.
     134 *  @param[in] addr_len The source and destination addresses maximal length in bytes.
     135 *  @param[in] max_prefix The maximal prefix length in bytes.
     136 *  @param[in] max_content The maximal content length in bytes.
     137 *  @param[in] max_suffix The maximal suffix length in bytes.
     138 *  @returns The packet of dimensions at least as given.
     139 *  @returns NULL if there is not enough memory left.
     140 */
     141static packet_t packet_create(size_t length, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){
     142        ERROR_DECLARE;
     143
     144        packet_t packet;
     145
     146        // already locked
     147        packet = (packet_t) mmap(NULL, length, PROTO_READ | PROTO_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
     148        if(packet == MAP_FAILED){
     149                return NULL;
     150        }
     151        ++ ps_globals.count;
     152        packet->packet_id = ps_globals.count;
     153        packet->length = length;
     154        packet_init(packet, addr_len, max_prefix, max_content, max_suffix);
     155        packet->magic_value = PACKET_MAGIC_VALUE;
     156        if(ERROR_OCCURRED(pm_add(packet))){
     157                munmap(packet, packet->length);
     158                return NULL;
     159        }
     160        return packet;
     161}
     162
     163/** Returns the packet of dimensions at least as given.
     164 *  Tries to reuse free packets first.
     165 *  Creates a&nbsp;new packet aligned to the memory page size if none available.
     166 *  Locks the global data during its processing.
     167 *  @param[in] addr_len The source and destination addresses maximal length in bytes.
     168 *  @param[in] max_prefix The maximal prefix length in bytes.
     169 *  @param[in] max_content The maximal content length in bytes.
     170 *  @param[in] max_suffix The maximal suffix length in bytes.
     171 *  @returns The packet of dimensions at least as given.
     172 *  @returns NULL if there is not enough memory left.
     173 */
     174static packet_t packet_get(size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){
     175        int index;
     176        packet_t packet;
     177        size_t length;
     178
     179        length = ALIGN_UP(sizeof(struct packet) + 2 * addr_len + max_prefix + max_content + max_suffix, PAGE_SIZE);
     180        fibril_mutex_lock(&ps_globals.lock);
     181        for(index = 0; index < FREE_QUEUES_COUNT - 1; ++ index){
     182                if(length <= ps_globals.sizes[index]){
     183                        packet = ps_globals.free[index];
     184                        while(packet_is_valid(packet) && (packet->length < length)){
     185                                packet = pm_find(packet->next);
     186                        }
     187                        if(packet_is_valid(packet)){
     188                                if(packet == ps_globals.free[index]){
     189                                        ps_globals.free[index] = pq_detach(packet);
     190                                }else{
     191                                        pq_detach(packet);
     192                                }
     193                                packet_init(packet, addr_len, max_prefix, max_content, max_suffix);
     194                                fibril_mutex_unlock(&ps_globals.lock);
     195                                // remove debug dump
     196//                              printf("packet %d got\n", packet->packet_id);
     197                                return packet;
     198                        }
     199                }
     200        }
     201        packet = packet_create(length, addr_len, max_prefix, max_content, max_suffix);
     202        fibril_mutex_unlock(&ps_globals.lock);
     203        // remove debug dump
     204//      printf("packet %d created\n", packet->packet_id);
     205        return packet;
     206}
     207
     208packet_t packet_get_4(int phone, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix){
     209        return packet_get(addr_len, max_prefix, max_content, max_suffix);
     210}
     211
     212packet_t packet_get_1(int phone, size_t content){
     213        return packet_get(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, content, DEFAULT_SUFFIX);
     214}
     215
     216/** Releases the packet and returns it to the appropriate free packet queue.
     217 *  Should be used only when the global data are locked.
     218 *  @param[in] packet The packet to be released.
     219 */
     220static void packet_release(packet_t packet){
     221        int index;
     222        int result;
     223
     224        // remove debug dump
     225//      printf("packet %d released\n", packet->packet_id);
     226        for(index = 0; (index < FREE_QUEUES_COUNT - 1) && (packet->length > ps_globals.sizes[index]); ++ index);
     227        result = pq_add(&ps_globals.free[index], packet, packet->length, packet->length);
     228        assert(result == EOK);
     229}
     230
     231/** Releases the packet queue.
     232 *  @param[in] packet_id The first packet identifier.
     233 *  @returns EOK on success.
     234 *  @returns ENOENT if there is no such packet.
     235 */
     236static int packet_release_wrapper(packet_id_t packet_id){
     237        packet_t packet;
     238
     239        packet = pm_find(packet_id);
     240        if(! packet_is_valid(packet)){
     241                return ENOENT;
     242        }
     243        fibril_mutex_lock(&ps_globals.lock);
     244        pq_destroy(packet, packet_release);
     245        fibril_mutex_unlock(&ps_globals.lock);
     246        return EOK;
     247}
     248
     249void pq_release(int phone, packet_id_t packet_id){
     250        (void) packet_release_wrapper(packet_id);
     251}
     252
     253/** Shares the packet memory block.
     254 *  @param[in] packet The packet to be shared.
     255 *  @returns EOK on success.
     256 *  @returns EINVAL if the packet is not valid.
     257 *  @returns EINVAL if the calling module does not accept the memory.
     258 *  @returns ENOMEM if the desired and actual sizes differ.
     259 *  @returns Other error codes as defined for the async_share_in_finalize() function.
     260 */
     261static int packet_reply(const packet_t packet){
    326262        ipc_callid_t callid;
    327263        size_t size;
     
    337273}
    338274
     275int packet_server_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
     276        packet_t packet;
     277
     278        *answer_count = 0;
     279        switch(IPC_GET_METHOD(*call)){
     280                case IPC_M_PHONE_HUNGUP:
     281                        return EOK;
     282                case NET_PACKET_CREATE_1:
     283                        packet = packet_get(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, IPC_GET_CONTENT(call), DEFAULT_SUFFIX);
     284                        if(! packet){
     285                                return ENOMEM;
     286                        }
     287                        *answer_count = 2;
     288                        IPC_SET_ARG1(*answer, (ipcarg_t) packet->packet_id);
     289                        IPC_SET_ARG2(*answer, (ipcarg_t) packet->length);
     290                        return EOK;
     291                case NET_PACKET_CREATE_4:
     292                        packet = packet_get(((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));
     293                        if(! packet){
     294                                return ENOMEM;
     295                        }
     296                        *answer_count = 2;
     297                        IPC_SET_ARG1(*answer, (ipcarg_t) packet->packet_id);
     298                        IPC_SET_ARG2(*answer, (ipcarg_t) packet->length);
     299                        return EOK;
     300                case NET_PACKET_GET:
     301                        packet = pm_find(IPC_GET_ID(call));
     302                        if(! packet_is_valid(packet)){
     303                                return ENOENT;
     304                        }
     305                        return packet_reply(packet);
     306                case NET_PACKET_GET_SIZE:
     307                        packet = pm_find(IPC_GET_ID(call));
     308                        if(! packet_is_valid(packet)){
     309                                return ENOENT;
     310                        }
     311                        IPC_SET_ARG1(*answer, (ipcarg_t) packet->length);
     312                        *answer_count = 1;
     313                        return EOK;
     314                case NET_PACKET_RELEASE:
     315                        return packet_release_wrapper(IPC_GET_ID(call));
     316        }
     317        return ENOTSUP;
     318}
     319
    339320/** @}
    340321 */
Note: See TracChangeset for help on using the changeset viewer.