Changeset 609243f4 in mainline for uspace/srv/net/net/packet_server.c
- Timestamp:
- 2011-10-07T15:46:01Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e2c50e1
- Parents:
- f51b1d3
- File:
-
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/net/packet_server.c
rf51b1d3 r609243f4 1 1 /* 2 2 * Copyright (c) 2009 Lukas Mejdrech 3 * Copyright (c) 2011 Radim Vansa 3 4 * All rights reserved. 4 5 * … … 35 36 */ 36 37 37 #include <packet_server.h>38 38 #include <align.h> 39 39 #include <assert.h> 40 40 #include <async.h> 41 41 #include <errno.h> 42 #include <str_error.h> 43 #include <stdio.h> 42 44 #include <fibril_synch.h> 43 45 #include <unistd.h> … … 48 50 #include <net/packet_header.h> 49 51 52 #include "packet_server.h" 53 54 #define PACKET_SERVER_PROFILE 1 55 56 /** Number of queues cacheing the unused packets */ 50 57 #define FREE_QUEUES_COUNT 7 58 /** Maximum number of packets in each queue */ 59 #define FREE_QUEUE_MAX_LENGTH 16 51 60 52 61 /** The default address length reserved for new packets. */ … … 58 67 /** The default suffix reserved for new packets. */ 59 68 #define DEFAULT_SUFFIX 64 69 70 /** The queue with unused packets */ 71 typedef struct packet_queue { 72 packet_t *first; /**< First packet in the queue */ 73 size_t packet_size; /**< Maximal size of the packets in this queue */ 74 int count; /**< Length of the queue */ 75 } packet_queue_t; 60 76 61 77 /** Packet server global data. */ … … 64 80 fibril_mutex_t lock; 65 81 /** Free packet queues. */ 66 packet_t *free[FREE_QUEUES_COUNT]; 67 68 /** 69 * Packet length upper bounds of the free packet queues. The maximal 70 * lengths of packets in each queue in the ascending order. The last 71 * queue is not limited. 72 */ 73 size_t sizes[FREE_QUEUES_COUNT]; 82 packet_queue_t free_queues[FREE_QUEUES_COUNT]; 74 83 75 84 /** Total packets allocated. */ 76 unsigned int count;85 packet_id_t next_id; 77 86 } ps_globals = { 78 87 .lock = FIBRIL_MUTEX_INITIALIZER(ps_globals.lock), 79 .free = {80 NULL,81 NULL,82 NULL,83 NULL,84 NULL,85 NULL,86 NULL88 .free_queues = { 89 { NULL, PAGE_SIZE, 0}, 90 { NULL, PAGE_SIZE * 2, 0}, 91 { NULL, PAGE_SIZE * 4, 0}, 92 { NULL, PAGE_SIZE * 8, 0}, 93 { NULL, PAGE_SIZE * 16, 0}, 94 { NULL, PAGE_SIZE * 32, 0}, 95 { NULL, PAGE_SIZE * 64, 0}, 87 96 }, 88 .sizes = { 89 PAGE_SIZE, 90 PAGE_SIZE * 2, 91 PAGE_SIZE * 4, 92 PAGE_SIZE * 8, 93 PAGE_SIZE * 16, 94 PAGE_SIZE * 32, 95 PAGE_SIZE * 64 96 }, 97 .count = 0 97 .next_id = 1 98 98 }; 99 99 … … 107 107 * @param[in] max_suffix The maximal suffix length in bytes. 108 108 */ 109 static void 110 packet_init(packet_t *packet, size_t addr_len, size_t max_prefix, 111 size_t max_content, size_t max_suffix) 109 static void packet_init(packet_t *packet, 110 size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix) 112 111 { 113 112 /* Clear the packet content */ … … 120 119 packet->previous = 0; 121 120 packet->next = 0; 121 packet->offload_info = 0; 122 packet->offload_mask = 0; 122 123 packet->addr_len = 0; 123 124 packet->src_addr = sizeof(packet_t); … … 127 128 packet->data_start = packet->dest_addr + addr_len + packet->max_prefix; 128 129 packet->data_end = packet->data_start; 130 } 131 132 /** 133 * Releases the memory allocated for the packet 134 * 135 * @param[in] packet Pointer to the memory where the packet was allocated 136 */ 137 static void packet_dealloc(packet_t *packet) 138 { 139 pm_remove(packet); 140 munmap(packet, packet->length); 129 141 } 130 142 … … 141 153 * @return NULL if there is not enough memory left. 142 154 */ 143 static packet_t * 144 packet_create(size_t length, size_t addr_len, size_t max_prefix, 145 size_t max_content, size_t max_suffix) 155 static packet_t *packet_alloc(size_t length, size_t addr_len, 156 size_t max_prefix, size_t max_content, size_t max_suffix) 146 157 { 147 158 packet_t *packet; 148 159 int rc; 149 160 161 /* Global lock is locked */ 150 162 assert(fibril_mutex_is_locked(&ps_globals.lock)); 151 152 /* Already locked */ 163 /* The length is some multiple of PAGE_SIZE */ 164 assert(!(length & (PAGE_SIZE - 1))); 165 153 166 packet = (packet_t *) mmap(NULL, length, PROTO_READ | PROTO_WRITE, 154 167 MAP_SHARED | MAP_ANONYMOUS, 0, 0); 155 168 if (packet == MAP_FAILED) 156 169 return NULL; 157 158 ps_globals.count++; 159 packet->packet_id = ps_globals.count; 170 171 /* Using 32bit packet_id the id could overflow */ 172 packet_id_t pid; 173 do { 174 pid = ps_globals.next_id; 175 ps_globals.next_id++; 176 } while (!pid || pm_find(pid)); 177 packet->packet_id = pid; 178 160 179 packet->length = length; 161 180 packet_init(packet, addr_len, max_prefix, max_content, max_suffix); … … 163 182 rc = pm_add(packet); 164 183 if (rc != EOK) { 165 munmap(packet, packet->length);184 packet_dealloc(packet); 166 185 return NULL; 167 186 } … … 184 203 * @return NULL if there is not enough memory left. 185 204 */ 186 static packet_t * 187 packet_get_local(size_t addr_len, size_t max_prefix, size_t max_content, 188 size_t max_suffix) 189 { 190 size_t length = ALIGN_UP(sizeof(packet_t) + 2 * addr_len + 191 max_prefix + max_content + max_suffix, PAGE_SIZE); 192 205 static packet_t *packet_get_local(size_t addr_len, 206 size_t max_prefix, size_t max_content, size_t max_suffix) 207 { 208 size_t length = ALIGN_UP(sizeof(packet_t) + 2 * addr_len 209 + max_prefix + max_content + max_suffix, PAGE_SIZE); 210 211 if (length > PACKET_MAX_LENGTH) 212 return NULL; 213 193 214 fibril_mutex_lock(&ps_globals.lock); 194 215 … … 197 218 198 219 for (index = 0; index < FREE_QUEUES_COUNT; index++) { 199 if ((length > ps_globals. sizes[index]) &&200 220 if ((length > ps_globals.free_queues[index].packet_size) && 221 (index < FREE_QUEUES_COUNT - 1)) 201 222 continue; 202 223 203 packet = ps_globals.free [index];224 packet = ps_globals.free_queues[index].first; 204 225 while (packet_is_valid(packet) && (packet->length < length)) 205 226 packet = pm_find(packet->next); 206 227 207 228 if (packet_is_valid(packet)) { 208 if (packet == ps_globals.free[index]) 209 ps_globals.free[index] = pq_detach(packet); 210 else 229 ps_globals.free_queues[index].count--; 230 if (packet == ps_globals.free_queues[index].first) { 231 ps_globals.free_queues[index].first = pq_detach(packet); 232 } else { 211 233 pq_detach(packet); 234 } 212 235 213 packet_init(packet, addr_len, max_prefix, max_content, 214 max_suffix); 236 packet_init(packet, addr_len, max_prefix, max_content, max_suffix); 215 237 fibril_mutex_unlock(&ps_globals.lock); 216 238 … … 219 241 } 220 242 221 packet = packet_ create(length, addr_len, max_prefix, max_content,222 243 packet = packet_alloc(length, addr_len, 244 max_prefix, max_content, max_suffix); 223 245 224 246 fibril_mutex_unlock(&ps_globals.lock); … … 240 262 241 263 for (index = 0; (index < FREE_QUEUES_COUNT - 1) && 242 (packet->length > ps_globals. sizes[index]); index++) {264 (packet->length > ps_globals.free_queues[index].packet_size); index++) { 243 265 ; 244 266 } 245 267 246 result = pq_add(&ps_globals.free[index], packet, packet->length, 247 packet->length); 268 ps_globals.free_queues[index].count++; 269 result = pq_add(&ps_globals.free_queues[index].first, packet, 270 packet->length, packet->length); 248 271 assert(result == EOK); 249 272 } … … 328 351 case NET_PACKET_CREATE_1: 329 352 packet = packet_get_local(DEFAULT_ADDR_LEN, DEFAULT_PREFIX, 330 353 IPC_GET_CONTENT(*call), DEFAULT_SUFFIX); 331 354 if (!packet) 332 355 return ENOMEM; … … 338 361 case NET_PACKET_CREATE_4: 339 362 packet = packet_get_local( 340 363 ((DEFAULT_ADDR_LEN < IPC_GET_ADDR_LEN(*call)) ? 341 364 IPC_GET_ADDR_LEN(*call) : DEFAULT_ADDR_LEN), 342 365 DEFAULT_PREFIX + IPC_GET_PREFIX(*call), … … 352 375 case NET_PACKET_GET: 353 376 packet = pm_find(IPC_GET_ID(*call)); 354 if (!packet_is_valid(packet)) 377 if (!packet_is_valid(packet)) { 355 378 return ENOENT; 379 } 356 380 return packet_reply(packet); 357 381 … … 371 395 } 372 396 397 int packet_server_init() 398 { 399 return EOK; 400 } 401 373 402 /** @} 374 403 */
Note:
See TracChangeset
for help on using the changeset viewer.