Subversion Repositories HelenOS

Rev

Rev 3886 | Rev 3912 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3886 mejdrech 1
/*
2
 * Copyright (c) 2008 Lukas Mejdrech
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 *
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
14
 * - The name of the author may not be used to endorse or promote products
15
 *   derived from this software without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
28
 
29
/** @addtogroup net
3901 mejdrech 30
 *  @{
3886 mejdrech 31
 */
32
 
33
/** @file
34
 */
35
 
36
#include <errno.h>
3901 mejdrech 37
#include <malloc.h>
38
//#include <stdio.h>
3886 mejdrech 39
#include <string.h>
40
 
41
#include <sys/mman.h>
42
 
43
#include "../../err.h"
44
 
3901 mejdrech 45
#include "../generic_field.h"
46
 
47
#include "packet_header.h"
3886 mejdrech 48
#include "packet.h"
49
 
3901 mejdrech 50
// TODO power of 2 aritmetic => div and mod speedup?
51
#define PACKET_MAP_SIZE	100
3886 mejdrech 52
 
3901 mejdrech 53
#define PACKET_MAP_PAGE( packet_id )	((( packet_id ) - 1 ) / PACKET_MAP_SIZE )
54
#define PACKET_MAP_INDEX( packet_id )	((( packet_id ) - 1 ) % PACKET_MAP_SIZE )
3886 mejdrech 55
 
56
 
3901 mejdrech 57
int packet_destroy( packet_t packet );
3886 mejdrech 58
 
3901 mejdrech 59
typedef packet_t packet_map_t[ PACKET_MAP_SIZE ];
60
typedef packet_map_t * packet_map_ref;
61
 
62
GENERIC_FIELD_DECLARE( gpm, packet_map_t );
63
 
64
GENERIC_FIELD_IMPLEMENT( gpm, packet_map_t );
65
 
66
static struct{
67
	// TODO lock
68
	gpm_t map;
69
} pm_globals;
70
 
71
int packet_destroy( packet_t packet ){
72
	if( ! packet_is_valid( packet )) return EINVAL;
73
	return munmap( packet, packet->length );
3886 mejdrech 74
}
75
 
3901 mejdrech 76
int pm_init( void ){
77
	return gpm_initialize( & pm_globals.map );
3886 mejdrech 78
}
79
 
3901 mejdrech 80
packet_t pm_find( packet_id_t packet_id ){
81
	packet_map_ref map;
3886 mejdrech 82
 
3901 mejdrech 83
	if( ! packet_id ) return NULL;
84
	if( packet_id > PACKET_MAP_SIZE * gpm_count( & pm_globals.map )) return NULL;
85
	map = gpm_get_index( & pm_globals.map, PACKET_MAP_PAGE( packet_id ));
86
	if( ! map ) return NULL;
87
	return ( * map )[ PACKET_MAP_INDEX( packet_id ) ];
3886 mejdrech 88
}
89
 
3901 mejdrech 90
int pm_add( packet_t packet ){
91
	ERROR_DECLARE;
92
 
93
	packet_map_ref map;
94
 
95
	if(( ! packet_is_valid( packet )) || ( gpm_count( & pm_globals.map ) < -1 )) return EINVAL;
96
	if( PACKET_MAP_PAGE( packet->packet_id ) < gpm_count( & pm_globals.map )){
97
		map = gpm_get_index( & pm_globals.map, PACKET_MAP_PAGE( packet->packet_id ));
98
	}else{
99
		do{
100
			map = ( packet_map_ref ) malloc( sizeof( packet_map_t ));
101
			if( ! map ) return ENOMEM;
102
			memset( map, 0, sizeof( packet_map_t ));
103
			if(( ERROR_CODE = gpm_add( & pm_globals.map, map )) < 0 ){
104
				free( map );
105
				return ERROR_CODE;
106
			}
107
		}while( PACKET_MAP_PAGE( packet->packet_id ) >= gpm_count( & pm_globals.map ));
3886 mejdrech 108
	}
3901 mejdrech 109
	( * map )[ PACKET_MAP_INDEX( packet->packet_id ) ] = packet;
3886 mejdrech 110
	return EOK;
111
}
112
 
3901 mejdrech 113
void pm_destroy( void ){
114
	int count;
115
	int index;
116
	packet_map_ref map;
117
	packet_t packet;
3886 mejdrech 118
 
3901 mejdrech 119
	count = gpm_count( & pm_globals.map );
120
	while( count > 0 ){
121
		map = gpm_get_index( & pm_globals.map, count - 1 );
122
		for( index = PACKET_MAP_SIZE - 1; index >= 0; -- index ){
123
			packet = ( * map )[ index ];
124
			if( packet_is_valid( packet )){
125
				munmap( packet, packet->length );
126
			}
127
		}
128
	}
129
	gpm_destroy( & pm_globals.map );
3886 mejdrech 130
}
131
 
3901 mejdrech 132
packet_t pq_add( packet_t first, packet_t packet, int order, size_t metric ){
133
	packet_t	item;
3886 mejdrech 134
 
3901 mejdrech 135
	if( ! packet_is_valid( packet )) return NULL;
136
	pq_set( packet, order, metric );
137
	if( packet_is_valid( first )){
138
		item = first;
139
		do{
140
			if( item->order < order ){
141
				if( item->next ){
142
					item = pm_find( item->next );
143
				}else{
144
					item->next = packet->packet_id;
145
					packet->previous = item->packet_id;
146
					return first;
147
				}
148
			}else{
149
				packet->previous = item->previous;
150
				packet->next = item->packet_id;
151
				item->previous = packet->packet_id;
152
				item = pm_find( packet->previous );
153
				if( item ) item->next = packet->packet_id;
154
				return item;
155
			}
156
		}while( packet_is_valid( item ));
157
	}
158
	return packet;
3886 mejdrech 159
}
160
 
3901 mejdrech 161
packet_t pq_detach( packet_t packet ){
162
	packet_t next;
163
	packet_t previous;
3886 mejdrech 164
 
3901 mejdrech 165
	if( ! packet_is_valid( packet )) return NULL;
166
	next = pm_find( packet->next );
167
	if( next ){
168
		next->previous = packet->previous;
169
		previous = pm_find( next->previous );
170
		if( previous ){
171
			previous->next = next->packet_id;
172
		}
3886 mejdrech 173
	}
3901 mejdrech 174
	packet->previous = 0;
175
	packet->next = 0;
176
	return next;
3886 mejdrech 177
}
178
 
3901 mejdrech 179
int pq_set( packet_t packet, int order, size_t metric ){
3886 mejdrech 180
	if( ! packet_is_valid( packet )) return EINVAL;
3901 mejdrech 181
	packet->order = order;
182
	packet->metric = metric;
183
	return EOK;
3886 mejdrech 184
}
185
 
3901 mejdrech 186
void pq_destroy( packet_t first, void ( * packet_release )( packet_t packet )){
187
	packet_t	actual;
188
	packet_t	next;
3886 mejdrech 189
 
3901 mejdrech 190
	actual = first;
191
	while( packet_is_valid( actual )){
192
		next = pm_find( actual->next );
193
		actual->next = 0;
194
		actual->previous = 0;
195
		if( packet_release ) packet_release( actual );
196
		actual = next;
197
	}
3886 mejdrech 198
}
199
 
200
/** @}
201
 */