Changeset 849ed54 in mainline for uspace/lib/socket/packet/packet_server.c
- Timestamp:
- 2010-03-30T18:39:04Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7553689
- Parents:
- 7d6fe4db
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/socket/packet/packet_server.c
r7d6fe4db r849ed54 45 45 #include <sys/mman.h> 46 46 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> 55 54 56 55 #define FREE_QUEUES_COUNT 7 … … 98 97 }; 99 98 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 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 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); 99 int 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 } 141 106 142 107 /** Clears and initializes the packet according to the given dimensions. … … 147 112 * @param[in] max_suffix The maximal suffix length in bytes. 148 113 */ 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){ 114 static void packet_init(packet_t packet, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix){ 309 115 // clear the packet content 310 116 bzero(((void *) packet) + sizeof(struct packet), packet->length - sizeof(struct packet)); … … 323 129 } 324 130 325 int packet_reply(const packet_t packet){ 131 /** Creates a 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 */ 141 static 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 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 */ 174 static 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 208 packet_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 212 packet_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 */ 220 static 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 */ 236 static 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 249 void 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 */ 261 static int packet_reply(const packet_t packet){ 326 262 ipc_callid_t callid; 327 263 size_t size; … … 337 273 } 338 274 275 int 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 339 320 /** @} 340 321 */
Note:
See TracChangeset
for help on using the changeset viewer.