Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3989 → Rev 3990

/branches/network/uspace/srv/net/structures/packet/packet_header.h
37,8 → 37,6
#ifndef __NET_PACKET_HEADER_H__
#define __NET_PACKET_HEADER_H__
 
#include <ipc/services.h>
 
#include "packet.h"
 
/** Packet integrity check magic value.
51,14 → 49,6
/** Packet identifier.
*/
packet_id_t packet_id;
//TODO packet owner not used
/** Packet owner.
*/
services_t owner;
//TODO needed packet mode?
/** Packet mode.
*/
packet_mode_t mode;
/** Packet queue sorting value.
* The packet queue is sorted the ascending order.
*/
/branches/network/uspace/srv/net/structures/packet/packet_client.c
41,7 → 41,6
#include <string.h>
 
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <sys/mman.h>
 
#include "../../err.h"
63,18 → 62,6
*/
int packet_return( int phone, packet_ref packet, packet_id_t packet_id, size_t size );
 
packet_t packet_copy( int phone, services_t owner, const packet_t packet ){
packet_t new;
 
if( ! packet_is_valid( packet )) return NULL;
// new = ( packet_t ) mmap( NULL, packet->length, PROTO_READ | PROTO_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0 );
// if( new == MAP_FAILED ) return NULL;
// memcpy( new, packet, packet->length );
new = packet_get_1( phone, owner, packet_get_data_length( packet ));
packet_copy_data( new, packet_get_data( packet ), packet_get_data_length( packet ));
return new;
}
 
int packet_copy_data( packet_t packet, const void * data, size_t length ){
if( ! packet_is_valid( packet )) return EINVAL;
if( packet->data_start + length >= packet->length ) return ENOMEM;
127,11 → 114,6
return ( void * ) packet + packet->data_start;
}
 
packet_mode_t packet_get_mode( const packet_t packet ){
if( packet_is_valid( packet )) return packet->mode;
return PM_ONE_WAY;
}
 
int packet_set_addr( packet_t packet, const uint8_t * src, const uint8_t * dest, size_t addr_len ){
size_t padding;
 
153,18 → 135,6
return EOK;
}
 
int packet_set_mode( packet_t packet, packet_mode_t mode ){
if( ! packet_is_valid( packet )) return EINVAL;
packet->mode = mode;
return EOK;
}
 
int packet_set_owner( packet_t packet, services_t owner ){
if( ! packet_is_valid( packet )) return EINVAL;
packet->owner = owner;
return EOK;
}
 
int packet_translate( int phone, packet_ref packet, packet_id_t packet_id ){
ERROR_DECLARE;
 
196,7 → 166,7
return result;
}
 
packet_t packet_get_5( int phone, services_t owner, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix ){
packet_t packet_get_4( int phone, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix ){
ERROR_DECLARE;
 
packet_id_t packet_id;
203,7 → 173,7
unsigned int size;
packet_t packet;
 
if( ERROR_OCCURRED( async_req_5_2( phone, NET_PACKET_CREATE_5, owner, max_content, addr_len, max_prefix, max_suffix, & packet_id, & size ))
if( ERROR_OCCURRED( async_req_4_2( phone, NET_PACKET_CREATE_4, max_content, addr_len, max_prefix, max_suffix, & packet_id, & size ))
|| ERROR_OCCURRED( packet_return( phone, & packet, packet_id, size ))){
return NULL;
}
210,7 → 180,7
return packet;
}
 
packet_t packet_get_1( int phone, services_t owner, size_t content ){
packet_t packet_get_1( int phone, size_t content ){
ERROR_DECLARE;
 
packet_id_t packet_id;
217,7 → 187,7
unsigned int size;
packet_t packet;
 
if( ERROR_OCCURRED( async_req_2_2( phone, NET_PACKET_CREATE_1, owner, content, & packet_id, & size ))
if( ERROR_OCCURRED( async_req_1_2( phone, NET_PACKET_CREATE_1, content, & packet_id, & size ))
|| ERROR_OCCURRED( packet_return( phone, & packet, packet_id, size ))){
return NULL;
}
/branches/network/uspace/srv/net/structures/packet/packet.c
36,8 → 36,8
*/
 
#include <errno.h>
#include <futex.h>
#include <malloc.h>
#include <rwlock.h>
//#include <stdio.h>
#include <string.h>
 
50,7 → 50,6
#include "packet_header.h"
#include "packet.h"
 
// TODO power of 2 aritmetic => div and mod speedup?
/** Packet map page size.
*/
#define PACKET_MAP_SIZE 100
89,9 → 88,8
*/
static struct{
/** Safety lock.
* Used as a&nbsp;mutex.
*/
futex_t lock;
rwlock_t lock;
/** Packet map.
*/
gpm_t packet_map;
107,11 → 105,10
int pm_init( void ){
ERROR_DECLARE;
 
// start locked
futex_initialize( & pm_globals.lock, 0 );
rwlock_initialize( & pm_globals.lock );
rwlock_write_lock( & pm_globals.lock );
ERROR_PROPAGATE( gpm_initialize( & pm_globals.packet_map ));
// release the lock
futex_up( & pm_globals.lock );
rwlock_write_unlock( & pm_globals.lock );
return EOK;
}
 
120,18 → 117,18
packet_t packet;
 
if( ! packet_id ) return NULL;
futex_down( & pm_globals.lock );
rwlock_read_lock( & pm_globals.lock );
if( packet_id > PACKET_MAP_SIZE * gpm_count( & pm_globals.packet_map )){
futex_up( & pm_globals.lock );
rwlock_read_unlock( & pm_globals.lock );
return NULL;
}
map = gpm_get_index( & pm_globals.packet_map, PACKET_MAP_PAGE( packet_id ));
if( ! map ){
futex_up( & pm_globals.lock );
rwlock_read_unlock( & pm_globals.lock );
return NULL;
}
packet = ( * map )[ PACKET_MAP_INDEX( packet_id ) ];
futex_up( & pm_globals.lock );
rwlock_read_unlock( & pm_globals.lock );
return packet;
}
 
141,7 → 138,7
packet_map_ref map;
 
if( ! packet_is_valid( packet )) return EINVAL;
futex_down( & pm_globals.lock );
rwlock_write_lock( & pm_globals.lock );
if( PACKET_MAP_PAGE( packet->packet_id ) < gpm_count( & pm_globals.packet_map )){
map = gpm_get_index( & pm_globals.packet_map, PACKET_MAP_PAGE( packet->packet_id ));
}else{
148,19 → 145,19
do{
map = ( packet_map_ref ) malloc( sizeof( packet_map_t ));
if( ! map ){
futex_up( & pm_globals.lock );
rwlock_write_unlock( & pm_globals.lock );
return ENOMEM;
}
memset( map, 0, sizeof( packet_map_t ));
if(( ERROR_CODE = gpm_add( & pm_globals.packet_map, map )) < 0 ){
rwlock_write_unlock( & pm_globals.lock );
free( map );
futex_up( & pm_globals.lock );
return ERROR_CODE;
}
}while( PACKET_MAP_PAGE( packet->packet_id ) >= gpm_count( & pm_globals.packet_map ));
}
( * map )[ PACKET_MAP_INDEX( packet->packet_id ) ] = packet;
futex_up( & pm_globals.lock );
rwlock_write_unlock( & pm_globals.lock );
return EOK;
}
 
170,7 → 167,7
packet_map_ref map;
packet_t packet;
 
futex_down( & pm_globals.lock );
rwlock_write_lock( & pm_globals.lock );
count = gpm_count( & pm_globals.packet_map );
while( count > 0 ){
map = gpm_get_index( & pm_globals.packet_map, count - 1 );
/branches/network/uspace/srv/net/structures/packet/packet_client.h
54,7 → 54,7
* @returns NULL if the packet is not valid.
* @returns NULL if there is not enough memory left.
*/
#define PACKET_PREFIX( packet, type ) ( type * ) packet_prepend(( packet ), sizeof( type ))
#define PACKET_PREFIX( packet, type ) ( type * ) packet_prefix(( packet ), sizeof( type ))
 
/** Allocates the specified type right after the actual packet content and returns its pointer.
* The wrapper of the packet_append() function.
64,7 → 64,7
* @returns NULL if the packet is not valid.
* @returns NULL if there is not enough memory left.
*/
#define PACKET_SUFFIX( packet, type ) ( type * ) packet_append(( packet ), sizeof( type ))
#define PACKET_SUFFIX( packet, type ) ( type * ) packet_suffix(( packet ), sizeof( type ))
 
/** Trims the actual packet content by the specified prefix and suffix types.
* The wrapper of the packet_trim() function.
103,18 → 103,6
*/
int packet_trim( packet_t packet, size_t prefix, size_t suffix );
 
/** Copies the packet content.
* Obtains the new packet from the packet server.
* @param phone The packet server module phone. Input parameter.
* @param owner The owner of the new packet. Input parameter.
* @param packet The packet reference. Input parameter.
* @returns The packet copy.
* @returns NULL if the source packet ids not valid.
* @returns NULL on error.
* \todo other error?
*/
packet_t packet_copy( int phone, services_t owner, const packet_t packet );
 
/** Copies the specified data to the beginning of the actual packet content.
* Pushes the content end if needed.
* @param packet The packet to be filled. Input parameter.
158,13 → 146,6
*/
int packet_get_addr( const packet_t packet, uint8_t ** src, uint8_t ** dest );
 
/** Returns the packet operation mode.
* @param packet The packet. Input parameter.
* @returns The packet operation mode.
* @see packet_mode
*/
packet_mode_t packet_get_mode( const packet_t packet );
 
/** Sets the packet addresses.
* @param packet The packet. Input parameter.
* @param src The new source address. Output parameter.
176,23 → 157,6
*/
int packet_set_addr( packet_t packet, const uint8_t * src, const uint8_t * dest, size_t addr_len );
 
/** Sets the packet operation mode.
* @param packet The packet. Input parameter.
* @param mode The new packet operation mode. Input parameter.
* @returns EOK on success.
* @returns EINVAL if the packet is not valid.
* @see packet_mode
*/
int packet_set_mode( packet_t packet, packet_mode_t mode );
 
/** Sets the packet owner.
* @param packet The packet. Input parameter.
* @param owner The new packet owner. Input parameter.
* @returns EOK on success.
* @returns EINVAL if the packet is not valid.
*/
int packet_set_owner( packet_t packet, services_t owner );
 
/** Translates the packet identifier to the packet reference.
* Tries to find mapping first.
* Contacts the packet server to share the packet if the mapping is not present.
209,7 → 173,6
/** Obtains the packet of the given dimensions.
* Contacts the packet server to return the appropriate packet.
* @param phone The packet server module phone. Input parameter.
* @param owner The owner of the new packet. Input parameter.
* @param addr_len The source and destination addresses maximal length in bytes. Input parameter.
* @param max_prefix The maximal prefix length in bytes. Input parameter.
* @param max_content The maximal content length in bytes. Input parameter.
216,20 → 179,19
* @param max_suffix The maximal suffix length in bytes. Input parameter.
* @returns The packet reference.
* @returns NULL on error.
* \todo error as NET_PACKET_CREATE_5, packet_return()
* \todo error as NET_PACKET_CREATE_4, packet_return()
*/
packet_t packet_get_5( int phone, services_t owner, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix );
packet_t packet_get_4( int phone, size_t max_content, size_t addr_len, size_t max_prefix, size_t max_suffix );
 
/** Obtains the packet of the given content size.
* Contacts the packet server to return the appropriate packet.
* @param phone The packet server module phone. Input parameter.
* @param owner The owner of the new packet. Input parameter.
* @param content The maximal content length in bytes. Input parameter.
* @returns The packet reference.
* @returns NULL on error.
* \todo error as NET_PACKET_CREATE_1, packet_return()
*/
packet_t packet_get_1( int phone, services_t owner, size_t content );
packet_t packet_get_1( int phone, size_t content );
 
/** Releases the packet.
* The packet is marked as free for use.
/branches/network/uspace/srv/net/structures/packet/packet.h
52,19 → 52,21
*/
typedef packet_t * packet_ref;
 
/** Packet operation mode type.
/** Type of the received packet.
*/
typedef enum packet_mode packet_mode_t;
 
/** Packet operation mode.
*/
enum packet_mode{
/** The packet is processed in one direction and can be released at any time.
enum packet_type{
/** The packet is from the local subsystem.
*/
PM_ONE_WAY,
/** The packet should be returned at the end of the processing back to its initiator.
PACKET_SELF,
/** The packet is for all hosts.
*/
PM_RETURN
PACKET_BROADCAST,
/** The packet target complies with the local subsystem filter.
*/
PACKET_MULTICAST,
/** The packet is for the local subsystem from other host.
*/
PACKET_OTHERHOST
};
 
/** Finds the packet mapping.
108,6 → 110,7
/** Detach the packet from the queue.
* @param packet The packet to be detached. Input parameter.
* @returns The next packet in the queue. If the packet is the first one of the queue, this becomes the new first one.
* @returns NULL if there is no packet left.
* @returns NULL if the packet is not valid.
*/
packet_t pq_detach( packet_t packet );
/branches/network/uspace/srv/net/structures/packet/packet_server.c
42,7 → 42,6
#include <unistd.h>
 
#include <ipc/ipc.h>
#include <ipc/services.h>
#include <sys/mman.h>
 
#include "../../err.h"
56,25 → 55,21
*/
#define IPC_GET_ID( call ) ( packet_id_t ) IPC_GET_ARG1( * call )
 
/** Returns the owner message parameter.
*/
#define IPC_GET_OWNER( call ) ( services_t ) IPC_GET_ARG1( * call )
 
/** Returns the maximal content length message parameter.
*/
#define IPC_GET_CONTENT( call ) ( size_t ) IPC_GET_ARG2( * call )
#define IPC_GET_CONTENT( call ) ( size_t ) IPC_GET_ARG1( * call )
 
/** Returns the maximal address length message parameter.
*/
#define IPC_GET_ADDR_LEN( call ) ( size_t ) IPC_GET_ARG3( * call )
#define IPC_GET_ADDR_LEN( call ) ( size_t ) IPC_GET_ARG2( * call )
 
/** Returns the maximal prefix length message parameter.
*/
#define IPC_GET_PREFIX( call ) ( size_t ) IPC_GET_ARG4( * call )
#define IPC_GET_PREFIX( call ) ( size_t ) IPC_GET_ARG3( * call )
 
/** Returns the maximal suffix length message parameter.
*/
#define IPC_GET_SUFIX( call ) ( size_t ) IPC_GET_ARG5( * call )
#define IPC_GET_SUFIX( call ) ( size_t ) IPC_GET_ARG4( * call )
 
#define FREE_QUEUES_COUNT 7
 
112,7 → 107,6
* Tries to reuse free packets first.
* Creates a&nbsp;new packet aligned to the memory page size if none available.
* Locks the global data during its processing.
* @param owner The new owner of the packet. Input parameter.
* @param addr_len The source and destination addresses maximal length in bytes. Input parameter.
* @param max_prefix The maximal prefix length in bytes. Input parameter.
* @param max_content The maximal content length in bytes. Input parameter.
120,12 → 114,11
* @returns The packet of dimensions at least as given.
* @returns NULL if there is not enough memory left.
*/
packet_t packet_get( services_t owner, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix );
packet_t packet_get( size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix );
 
/** Creates a&nbsp;new packet of dimensions at least as given.
* Should be used only when the global data are locked.
* @param length The total length of the packet, including the header, the addresses and the data of the packet. Input parameter.
* @param owner The new owner of the packet. Input parameter.
* @param addr_len The source and destination addresses maximal length in bytes. Input parameter.
* @param max_prefix The maximal prefix length in bytes. Input parameter.
* @param max_content The maximal content length in bytes. Input parameter.
133,17 → 126,16
* @returns The packet of dimensions at least as given.
* @returns NULL if there is not enough memory left.
*/
packet_t packet_create( size_t length, services_t owner, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix );
packet_t packet_create( size_t length, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix );
 
/** Initializes the packet according to the given dimensions.
* @param packet The packet to be initialized. Input parameter.
* @param owner The new owner of the packet. Input parameter.
* @param addr_len The source and destination addresses maximal length in bytes. Input parameter.
* @param max_prefix The maximal prefix length in bytes. Input parameter.
* @param max_content The maximal content length in bytes. Input parameter.
* @param max_suffix The maximal suffix length in bytes. Input parameter.
*/
void packet_init( packet_t packet, services_t owner, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix );
void packet_init( packet_t packet, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix );
 
/** Shares the packet memory block.
* @param packet The packet to be shared.
163,14 → 155,14
case IPC_M_PHONE_HUNGUP:
return EOK;
case NET_PACKET_CREATE_1:
packet = packet_get( IPC_GET_OWNER( call ), 0, 0, IPC_GET_CONTENT( call ), 0 );
packet = packet_get( 0, 0, IPC_GET_CONTENT( call ), 0 );
if( ! packet ) return ENOMEM;
* answer_count = 2;
IPC_SET_ARG1( * answer, packet->packet_id );
IPC_SET_ARG2( * answer, packet->length );
return EOK;
case NET_PACKET_CREATE_5:
packet = packet_get( IPC_GET_OWNER( call ), IPC_GET_ADDR_LEN( call ), IPC_GET_PREFIX( call ), IPC_GET_CONTENT( call ), IPC_GET_SUFIX( call ));
case NET_PACKET_CREATE_4:
packet = packet_get( IPC_GET_ADDR_LEN( call ), IPC_GET_PREFIX( call ), IPC_GET_CONTENT( call ), IPC_GET_SUFIX( call ));
if( ! packet ) return ENOMEM;
* answer_count = 2;
IPC_SET_ARG1( * answer, packet->packet_id );
204,7 → 196,7
ps_globals.free[ index ] = pq_add( ps_globals.free[ index ], packet, packet->length, packet->length );
}
 
packet_t packet_get( services_t owner, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix ){
packet_t packet_get( size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix ){
int index;
packet_t packet;
size_t length;
218,18 → 210,18
packet = pm_find( packet->next );
}
if( packet ){
packet_init( packet, owner, addr_len, max_prefix, max_content, max_suffix );
packet_init( packet, addr_len, max_prefix, max_content, max_suffix );
futex_up( & ps_globals.lock );
return packet;
}
}
}
packet = packet_create( length, owner, addr_len, max_prefix, max_content, max_suffix );
packet = packet_create( length, addr_len, max_prefix, max_content, max_suffix );
futex_up( & ps_globals.lock );
return packet;
}
 
packet_t packet_create( size_t length, services_t owner, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix ){
packet_t packet_create( size_t length, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix ){
ERROR_DECLARE;
 
packet_t packet;
239,9 → 231,8
if( packet == MAP_FAILED ) return NULL;
++ ps_globals.count;
packet->packet_id = ps_globals.count;
packet->mode = PM_ONE_WAY;
packet->length = length;
packet_init( packet, owner, addr_len, max_prefix, max_content, max_suffix );
packet_init( packet, addr_len, max_prefix, max_content, max_suffix );
packet->magic_value = PACKET_MAGIC_VALUE;
if( ERROR_OCCURRED( pm_add( packet ))){
munmap( packet, packet->length );
251,8 → 242,7
return packet;
}
 
void packet_init( packet_t packet, services_t owner, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix ){
packet->owner = owner;
void packet_init( packet_t packet, size_t addr_len, size_t max_prefix, size_t max_content, size_t max_suffix ){
packet->order = 0;
packet->metric = 0;
packet->previous = 0;