Subversion Repositories HelenOS

Rev

Rev 3914 | Rev 4075 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3914 Rev 3990
Line 34... Line 34...
34
 *  Packet map and queue implementation.
34
 *  Packet map and queue implementation.
35
 *  This file has to be compiled with both the packet server and the client.
35
 *  This file has to be compiled with both the packet server and the client.
36
 */
36
 */
37
 
37
 
38
#include <errno.h>
38
#include <errno.h>
39
#include <futex.h>
-
 
40
#include <malloc.h>
39
#include <malloc.h>
-
 
40
#include <rwlock.h>
41
//#include <stdio.h>
41
//#include <stdio.h>
42
#include <string.h>
42
#include <string.h>
43
 
43
 
44
#include <sys/mman.h>
44
#include <sys/mman.h>
45
 
45
 
Line 48... Line 48...
48
#include "../generic_field.h"
48
#include "../generic_field.h"
49
 
49
 
50
#include "packet_header.h"
50
#include "packet_header.h"
51
#include "packet.h"
51
#include "packet.h"
52
 
52
 
53
// TODO power of 2 aritmetic => div and mod speedup?
-
 
54
/** Packet map page size.
53
/** Packet map page size.
55
 */
54
 */
56
#define PACKET_MAP_SIZE 100
55
#define PACKET_MAP_SIZE 100
57
 
56
 
58
/** Returns the packet map page index.
57
/** Returns the packet map page index.
Line 87... Line 86...
87
 
86
 
88
/** Packet map global data.
87
/** Packet map global data.
89
 */
88
 */
90
static struct{
89
static struct{
91
    /** Safety lock.
90
    /** Safety lock.
92
     *  Used as a&nbsp;mutex.
-
 
93
     */
91
     */
94
    futex_t lock;
92
    rwlock_t    lock;
95
    /** Packet map.
93
    /** Packet map.
96
     */
94
     */
97
    gpm_t   packet_map;
95
    gpm_t   packet_map;
98
} pm_globals;
96
} pm_globals;
99
 
97
 
Line 105... Line 103...
105
}
103
}
106
 
104
 
107
int pm_init( void ){
105
int pm_init( void ){
108
    ERROR_DECLARE;
106
    ERROR_DECLARE;
109
 
107
 
110
    // start locked
108
    rwlock_initialize( & pm_globals.lock );
111
    futex_initialize( & pm_globals.lock, 0 );
109
    rwlock_write_lock( & pm_globals.lock );
112
    ERROR_PROPAGATE( gpm_initialize( & pm_globals.packet_map ));
110
    ERROR_PROPAGATE( gpm_initialize( & pm_globals.packet_map ));
113
    // release the lock
-
 
114
    futex_up( & pm_globals.lock );
111
    rwlock_write_unlock( & pm_globals.lock );
115
    return EOK;
112
    return EOK;
116
}
113
}
117
 
114
 
118
packet_t pm_find( packet_id_t packet_id ){
115
packet_t pm_find( packet_id_t packet_id ){
119
    packet_map_ref map;
116
    packet_map_ref map;
120
    packet_t packet;
117
    packet_t packet;
121
 
118
 
122
    if( ! packet_id ) return NULL;
119
    if( ! packet_id ) return NULL;
123
    futex_down( & pm_globals.lock );
120
    rwlock_read_lock( & pm_globals.lock );
124
    if( packet_id > PACKET_MAP_SIZE * gpm_count( & pm_globals.packet_map )){
121
    if( packet_id > PACKET_MAP_SIZE * gpm_count( & pm_globals.packet_map )){
125
        futex_up( & pm_globals.lock );
122
        rwlock_read_unlock( & pm_globals.lock );
126
        return NULL;
123
        return NULL;
127
    }
124
    }
128
    map = gpm_get_index( & pm_globals.packet_map, PACKET_MAP_PAGE( packet_id ));
125
    map = gpm_get_index( & pm_globals.packet_map, PACKET_MAP_PAGE( packet_id ));
129
    if( ! map ){
126
    if( ! map ){
130
        futex_up( & pm_globals.lock );
127
        rwlock_read_unlock( & pm_globals.lock );
131
        return NULL;
128
        return NULL;
132
    }
129
    }
133
    packet = ( * map )[ PACKET_MAP_INDEX( packet_id ) ];
130
    packet = ( * map )[ PACKET_MAP_INDEX( packet_id ) ];
134
    futex_up( & pm_globals.lock );
131
    rwlock_read_unlock( & pm_globals.lock );
135
    return packet;
132
    return packet;
136
}
133
}
137
 
134
 
138
int pm_add( packet_t packet ){
135
int pm_add( packet_t packet ){
139
    ERROR_DECLARE;
136
    ERROR_DECLARE;
140
 
137
 
141
    packet_map_ref map;
138
    packet_map_ref map;
142
 
139
 
143
    if( ! packet_is_valid( packet )) return EINVAL;
140
    if( ! packet_is_valid( packet )) return EINVAL;
144
    futex_down( & pm_globals.lock );
141
    rwlock_write_lock( & pm_globals.lock );
145
    if( PACKET_MAP_PAGE( packet->packet_id ) < gpm_count( & pm_globals.packet_map )){
142
    if( PACKET_MAP_PAGE( packet->packet_id ) < gpm_count( & pm_globals.packet_map )){
146
        map = gpm_get_index( & pm_globals.packet_map, PACKET_MAP_PAGE( packet->packet_id ));
143
        map = gpm_get_index( & pm_globals.packet_map, PACKET_MAP_PAGE( packet->packet_id ));
147
    }else{
144
    }else{
148
        do{
145
        do{
149
            map = ( packet_map_ref ) malloc( sizeof( packet_map_t ));
146
            map = ( packet_map_ref ) malloc( sizeof( packet_map_t ));
150
            if( ! map ){
147
            if( ! map ){
151
                futex_up( & pm_globals.lock );
148
                rwlock_write_unlock( & pm_globals.lock );
152
                return ENOMEM;
149
                return ENOMEM;
153
            }
150
            }
154
            memset( map, 0, sizeof( packet_map_t ));
151
            memset( map, 0, sizeof( packet_map_t ));
155
            if(( ERROR_CODE = gpm_add( & pm_globals.packet_map, map )) < 0 ){
152
            if(( ERROR_CODE = gpm_add( & pm_globals.packet_map, map )) < 0 ){
-
 
153
                rwlock_write_unlock( & pm_globals.lock );
156
                free( map );
154
                free( map );
157
                futex_up( & pm_globals.lock );
-
 
158
                return ERROR_CODE;
155
                return ERROR_CODE;
159
            }
156
            }
160
        }while( PACKET_MAP_PAGE( packet->packet_id ) >= gpm_count( & pm_globals.packet_map ));
157
        }while( PACKET_MAP_PAGE( packet->packet_id ) >= gpm_count( & pm_globals.packet_map ));
161
    }
158
    }
162
    ( * map )[ PACKET_MAP_INDEX( packet->packet_id ) ] = packet;
159
    ( * map )[ PACKET_MAP_INDEX( packet->packet_id ) ] = packet;
163
    futex_up( & pm_globals.lock );
160
    rwlock_write_unlock( & pm_globals.lock );
164
    return EOK;
161
    return EOK;
165
}
162
}
166
 
163
 
167
void pm_destroy( void ){
164
void pm_destroy( void ){
168
    int count;
165
    int count;
169
    int index;
166
    int index;
170
    packet_map_ref map;
167
    packet_map_ref map;
171
    packet_t packet;
168
    packet_t packet;
172
 
169
 
173
    futex_down( & pm_globals.lock );
170
    rwlock_write_lock( & pm_globals.lock );
174
    count = gpm_count( & pm_globals.packet_map );
171
    count = gpm_count( & pm_globals.packet_map );
175
    while( count > 0 ){
172
    while( count > 0 ){
176
        map = gpm_get_index( & pm_globals.packet_map, count - 1 );
173
        map = gpm_get_index( & pm_globals.packet_map, count - 1 );
177
        for( index = PACKET_MAP_SIZE - 1; index >= 0; -- index ){
174
        for( index = PACKET_MAP_SIZE - 1; index >= 0; -- index ){
178
            packet = ( * map )[ index ];
175
            packet = ( * map )[ index ];