cleanup for new object changes
This commit was SVN r681.
Этот коммит содержится в:
родитель
c4c07e755d
Коммит
6453116b31
@ -22,7 +22,8 @@ enum {
|
||||
LAM_ERR_INTERUPTED = -12,
|
||||
LAM_ERR_WOULD_BLOCK = -13,
|
||||
LAM_ERR_IN_ERRNO = -14,
|
||||
LAM_ERR_UNREACH = -15
|
||||
LAM_ERR_UNREACH = -15,
|
||||
LAM_ERR_NOT_FOUND = -16
|
||||
};
|
||||
|
||||
#endif /* LAM_CONSTANTS_H */
|
||||
|
@ -10,19 +10,19 @@ noinst_LTLIBRARIES = liblfc.la
|
||||
# Source code files
|
||||
|
||||
headers = \
|
||||
array.h \
|
||||
hash_table.h \
|
||||
lam_pointer_array.h \
|
||||
list.h \
|
||||
object.h
|
||||
object.h \
|
||||
varray.h
|
||||
|
||||
liblfc_la_SOURCES = \
|
||||
$(headers) \
|
||||
array.c \
|
||||
hash_table.c \
|
||||
lam_pointer_array.c \
|
||||
lam_pointer_array.c \
|
||||
lam_value_array.c \
|
||||
list.c \
|
||||
object.c
|
||||
object.c
|
||||
|
||||
# Conditionally install the header files
|
||||
|
||||
|
@ -10,431 +10,249 @@
|
||||
#include "lam/constants.h"
|
||||
#include "lam/lfc/hash_table.h"
|
||||
|
||||
#define BUCKET_ALLOC_SZ 5
|
||||
/*
|
||||
* lam_hash_table_t
|
||||
*/
|
||||
|
||||
lam_class_info_t lam_fast_hash_t_class_info = {
|
||||
"lam_fast_hash_t",
|
||||
#define HASH_MULTIPLIER 31
|
||||
|
||||
static void lam_hash_table_construct(lam_hash_table_t* ht);
|
||||
static void lam_hash_table_destruct(lam_hash_table_t* ht);
|
||||
|
||||
|
||||
lam_class_info_t lam_hash_table_t_class_info = {
|
||||
"lam_hash_table_t",
|
||||
CLASS_INFO(lam_object_t),
|
||||
(lam_construct_t) lam_fh_construct,
|
||||
(lam_destruct_t) lam_fh_destruct
|
||||
(lam_construct_t)lam_hash_table_construct,
|
||||
(lam_destruct_t)lam_hash_table_destruct
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
* Private hash table functions
|
||||
*
|
||||
*/
|
||||
#define MULTIPLIER 31
|
||||
|
||||
static inline uint32_t lam_hash_value(const unsigned char * key, uint32_t keysize)
|
||||
static inline uint32_t lam_hash_value(const unsigned char *key, uint32_t keysize)
|
||||
{
|
||||
uint32_t h, i;
|
||||
const char *p;
|
||||
uint32_t h, i;
|
||||
const unsigned char *p;
|
||||
|
||||
h = 0;
|
||||
p = key;
|
||||
for (i = 0; i < keysize; i++, p++)
|
||||
h = MULTIPLIER*h + *p;
|
||||
|
||||
h = HASH_MULTIPLIER*h + *p;
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
static inline void *lam_fh_get_value_nkey(lam_fast_hash_t *htbl, void *key, uint32_t keysize)
|
||||
static void lam_hash_table_construct(lam_hash_table_t* ht)
|
||||
{
|
||||
uint32_t hval, i;
|
||||
lam_fhnode_t *buckets;
|
||||
|
||||
/* ASSERT: table size is power of 2 and table
|
||||
has been initialized using lam_fh_construct_with().
|
||||
*/
|
||||
hval = lam_hash_value((const char *)key, keysize) & htbl->fh_mask;
|
||||
buckets = htbl->fh_nodes[hval];
|
||||
if ( !buckets )
|
||||
return NULL;
|
||||
|
||||
for ( i = 0; i < htbl->fh_bucket_cnt[hval]; i++ )
|
||||
{
|
||||
if ( (true == buckets[i].fhn_is_taken) &&
|
||||
(0 == memcmp(&(buckets[i].fhn_key), key, keysize)) )
|
||||
return buckets[i].fhn_value;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
OBJ_CONSTRUCT_SUPER(ht, lam_object_t);
|
||||
OBJ_CONSTRUCT(&ht->ht_nodes, lam_list_t);
|
||||
ht->ht_table = 0;
|
||||
ht->ht_table_size = 0;
|
||||
ht->ht_size = 0;
|
||||
}
|
||||
|
||||
|
||||
static inline void *lam_fh_get_value_ptrkey(lam_fast_hash_t *htbl, void *key, uint32_t keysize)
|
||||
static void lam_hash_table_destruct(lam_hash_table_t* ht)
|
||||
{
|
||||
uint32_t hval, i;
|
||||
lam_fhnode_t *buckets;
|
||||
|
||||
/* ASSERT: table size is power of 2 and table
|
||||
has been initialized using lam_fh_construct_with().
|
||||
*/
|
||||
hval = lam_hash_value((const char *)key, keysize) & htbl->fh_mask;
|
||||
buckets = htbl->fh_nodes[hval];
|
||||
if ( !buckets )
|
||||
return NULL;
|
||||
|
||||
for ( i = 0; i < htbl->fh_bucket_cnt[hval]; i++ )
|
||||
{
|
||||
if ( (true == buckets[i].fhn_is_taken)
|
||||
&& (buckets[i].fhn_ptr_key_size == keysize)
|
||||
&& (0 == memcmp(buckets[i].fhn_key.pval, key, keysize)) )
|
||||
return buckets[i].fhn_value;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
OBJ_DESTRUCT(&ht->ht_nodes);
|
||||
OBJ_DESTRUCT_SUPER(ht, lam_object_t);
|
||||
}
|
||||
|
||||
|
||||
static inline void lam_fh_remove_value_nkey(lam_fast_hash_t *htbl, void *key, uint32_t keysize)
|
||||
int lam_hash_table_init(lam_hash_table_t* ht, size_t table_size)
|
||||
{
|
||||
uint32_t hval, i;
|
||||
lam_fhnode_t *buckets;
|
||||
|
||||
/* ASSERT: table size is power of 2 and table
|
||||
has been initialized using lam_fh_construct_with().
|
||||
*/
|
||||
hval = lam_hash_value((const char *)key, keysize) & htbl->fh_mask;
|
||||
buckets = htbl->fh_nodes[hval];
|
||||
if ( !buckets )
|
||||
return ;
|
||||
|
||||
for ( i = 0; i < htbl->fh_bucket_cnt[hval]; i++ )
|
||||
{
|
||||
if ( (true == buckets[i].fhn_is_taken) &&
|
||||
(0 == memcmp(&(buckets[i].fhn_key), key, sizeof(lam_ptr_t))) )
|
||||
{
|
||||
buckets[i].fhn_is_taken = false;
|
||||
buckets[i].fhn_value = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void lam_fh_remove_value_ptrkey(lam_fast_hash_t *htbl, void *key, uint32_t keysize)
|
||||
{
|
||||
uint32_t hval, i;
|
||||
lam_fhnode_t *buckets;
|
||||
|
||||
/* ASSERT: table size is power of 2 and table
|
||||
has been initialized using lam_fh_construct_with().
|
||||
*/
|
||||
hval = lam_hash_value((const char *)key, keysize) & htbl->fh_mask;
|
||||
buckets = htbl->fh_nodes[hval];
|
||||
if ( !buckets )
|
||||
return ;
|
||||
|
||||
for ( i = 0; i < htbl->fh_bucket_cnt[hval]; i++ )
|
||||
{
|
||||
if ( (true == buckets[i].fhn_is_taken)
|
||||
&& (buckets[i].fhn_ptr_key_size == keysize)
|
||||
&& (0 == memcmp(&(buckets[i].fhn_key), key, keysize)) )
|
||||
{
|
||||
buckets[i].fhn_is_taken = false;
|
||||
buckets[i].fhn_value = 0;
|
||||
free(buckets[i].fhn_key.pval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline int lam_fh_find_empty_bucket(lam_fast_hash_t *htbl, uint32_t hval,
|
||||
uint32_t *bucket_idx)
|
||||
{
|
||||
uint32_t i;
|
||||
lam_fhnode_t *buckets;
|
||||
|
||||
/* ASSERT: table size is power of 2 and table
|
||||
has been initialized using lam_fh_construct_with().
|
||||
*/
|
||||
buckets = htbl->fh_nodes[hval];
|
||||
if ( !buckets )
|
||||
{
|
||||
/* create new array of buckets
|
||||
for collision */
|
||||
htbl->fh_nodes[hval] = malloc(sizeof(lam_fhnode_t) * BUCKET_ALLOC_SZ);
|
||||
if ( !htbl->fh_nodes[hval] )
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
|
||||
memset(htbl->fh_nodes[hval], 0,
|
||||
sizeof(lam_fhnode_t) * BUCKET_ALLOC_SZ);
|
||||
htbl->fh_bucket_cnt[hval] = BUCKET_ALLOC_SZ; /* keep track of array size. */
|
||||
buckets = htbl->fh_nodes[hval];
|
||||
}
|
||||
|
||||
/* find an empty bucket. If no empty buckets,
|
||||
then realloc. */
|
||||
for ( i = 0; i < htbl->fh_bucket_cnt[hval]; i++ )
|
||||
{
|
||||
if ( false == buckets[i].fhn_is_taken )
|
||||
{
|
||||
/* found empty bucket */
|
||||
*bucket_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( i == htbl->fh_bucket_cnt[hval] )
|
||||
{
|
||||
/* no empty buckets! */
|
||||
htbl->fh_nodes[hval] = (lam_fhnode_t *)realloc(htbl->fh_nodes[hval],
|
||||
sizeof(lam_fhnode_t)
|
||||
* (htbl->fh_bucket_cnt[hval] + BUCKET_ALLOC_SZ));
|
||||
|
||||
if ( !htbl->fh_nodes[hval] )
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
|
||||
/* get ptr to start of newly alloc buckets */
|
||||
buckets = htbl->fh_nodes[hval] + htbl->fh_bucket_cnt[hval];
|
||||
memset(buckets, 0,
|
||||
sizeof(lam_fhnode_t) * BUCKET_ALLOC_SZ);
|
||||
*bucket_idx = htbl->fh_bucket_cnt[hval];
|
||||
htbl->fh_bucket_cnt[hval] += BUCKET_ALLOC_SZ; /* keep track of array size. */
|
||||
}
|
||||
|
||||
return LAM_SUCCESS;
|
||||
}
|
||||
|
||||
static inline int lam_fh_set_value_ptrkey(lam_fast_hash_t *htbl, void *val,
|
||||
void *key, uint32_t keysize)
|
||||
{
|
||||
int err;
|
||||
uint32_t hval, bucket_idx;
|
||||
lam_fhnode_t *buckets;
|
||||
|
||||
/* ASSERT: table size is power of 2 and table
|
||||
has been initialized using lam_fh_construct_with().
|
||||
*/
|
||||
hval = lam_hash_value((const char *)key, keysize) & htbl->fh_mask;
|
||||
err = lam_fh_find_empty_bucket(htbl, hval, &bucket_idx);
|
||||
if ( LAM_SUCCESS != err )
|
||||
return err;
|
||||
|
||||
/* ASSERT: we have an empty bucket */
|
||||
/* found empty bucket */
|
||||
buckets = htbl->fh_nodes[hval];
|
||||
buckets[bucket_idx].fhn_key.pval = malloc(keysize);
|
||||
if ( NULL == buckets[bucket_idx].fhn_key.pval )
|
||||
{
|
||||
size_t i;
|
||||
ht->ht_table = realloc(ht->ht_table, table_size * sizeof(lam_list_t));
|
||||
if(NULL == ht->ht_table)
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
memcpy(buckets[bucket_idx].fhn_key.pval, key, keysize);
|
||||
buckets[bucket_idx].fhn_using_key_ptr = true;
|
||||
buckets[bucket_idx].fhn_value = val;
|
||||
buckets[bucket_idx].fhn_ptr_key_size = keysize;
|
||||
buckets[bucket_idx].fhn_is_taken = true;
|
||||
|
||||
htbl->fh_count++;
|
||||
|
||||
|
||||
for(i=ht->ht_table_size; i<table_size; i++)
|
||||
OBJ_CONSTRUCT(ht->ht_table+i, lam_list_t);
|
||||
return LAM_SUCCESS;
|
||||
}
|
||||
|
||||
static inline int lam_fh_set_value_nkey(lam_fast_hash_t *htbl, void *val,
|
||||
void *key, uint32_t keysize)
|
||||
|
||||
/*
|
||||
* lam_uint32_hash_node_t
|
||||
*/
|
||||
|
||||
struct lam_uint32_hash_node_t
|
||||
{
|
||||
int err;
|
||||
uint32_t hval, bucket_idx;
|
||||
lam_fhnode_t *buckets;
|
||||
|
||||
/* ASSERT: table size is power of 2 and table
|
||||
has been initialized using lam_fh_construct_with().
|
||||
*/
|
||||
hval = lam_hash_value((const char *)key, keysize) & htbl->fh_mask;
|
||||
err = lam_fh_find_empty_bucket(htbl, hval, &bucket_idx);
|
||||
if ( LAM_SUCCESS != err )
|
||||
return err;
|
||||
|
||||
/* ASSERT: we have an empty bucket */
|
||||
/* found empty bucket */
|
||||
buckets = htbl->fh_nodes[hval];
|
||||
memcpy(&(buckets[bucket_idx].fhn_key), key, keysize);
|
||||
buckets[bucket_idx].fhn_using_key_ptr = false;
|
||||
buckets[bucket_idx].fhn_value = val;
|
||||
buckets[bucket_idx].fhn_is_taken = true;
|
||||
/* We don't need to set the key_size field for numeric keys */
|
||||
|
||||
htbl->fh_count++;
|
||||
|
||||
|
||||
lam_list_item_t super;
|
||||
uint32_t hn_key;
|
||||
void *hn_value;
|
||||
};
|
||||
typedef struct lam_uint32_hash_node_t lam_uint32_hash_node_t;
|
||||
|
||||
static void lam_uint32_hash_node_construct(lam_uint32_hash_node_t* hn)
|
||||
{
|
||||
OBJ_CONSTRUCT_SUPER(hn, lam_list_item_t);
|
||||
}
|
||||
|
||||
static void lam_uint32_hash_node_destruct(lam_uint32_hash_node_t* hn)
|
||||
{
|
||||
OBJ_DESTRUCT_SUPER(hn, lam_list_item_t);
|
||||
}
|
||||
|
||||
static lam_class_info_t lam_uint32_hash_node_t_class_info = {
|
||||
"lam_uint32_hash_node_t",
|
||||
&lam_list_item_t_class_info,
|
||||
(lam_construct_t)lam_uint32_hash_node_construct,
|
||||
(lam_destruct_t)lam_uint32_hash_node_destruct
|
||||
};
|
||||
|
||||
|
||||
void* lam_hash_table_get_value_uint32(lam_hash_table_t* ht, uint32_t key)
|
||||
{
|
||||
lam_list_t* list = ht->ht_table + (key & ht->ht_mask);
|
||||
lam_uint32_hash_node_t *node;
|
||||
|
||||
for(node = (lam_uint32_hash_node_t*)lam_list_get_first(list);
|
||||
node != (lam_uint32_hash_node_t*)lam_list_get_last(list);
|
||||
node = (lam_uint32_hash_node_t*)lam_list_get_next(list)) {
|
||||
if (node->hn_key == key) {
|
||||
return node->hn_value;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int lam_hash_table_set_value_uint32(lam_hash_table_t* ht, uint32_t key, void* value)
|
||||
{
|
||||
lam_list_t* list = ht->ht_table + (key & ht->ht_mask);
|
||||
lam_uint32_hash_node_t *node;
|
||||
|
||||
for(node = (lam_uint32_hash_node_t*)lam_list_get_first(list);
|
||||
node != (lam_uint32_hash_node_t*)lam_list_get_last(list);
|
||||
node = (lam_uint32_hash_node_t*)lam_list_get_next(list)) {
|
||||
if (node->hn_key == key) {
|
||||
node->hn_value = value;
|
||||
return LAM_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
node = (lam_uint32_hash_node_t*)lam_list_remove_first(&ht->ht_nodes);
|
||||
if(NULL == node) {
|
||||
node = OBJ_NEW(lam_uint32_hash_node_t);
|
||||
if(NULL == node)
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
node->hn_key = key;
|
||||
node->hn_value = value;
|
||||
lam_list_append(list, (lam_list_item_t*)node);
|
||||
ht->ht_size++;
|
||||
return LAM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int lam_hash_table_remove_value_uint32(lam_hash_table_t* ht, uint32_t key)
|
||||
{
|
||||
lam_list_t* list = ht->ht_table + (key & ht->ht_mask);
|
||||
lam_uint32_hash_node_t *node;
|
||||
|
||||
for(node = (lam_uint32_hash_node_t*)lam_list_get_first(list);
|
||||
node != (lam_uint32_hash_node_t*)lam_list_get_last(list);
|
||||
node = (lam_uint32_hash_node_t*)lam_list_get_next(list)) {
|
||||
if (node->hn_key == key) {
|
||||
lam_list_remove_item(list, (lam_list_item_t*)node);
|
||||
lam_list_append(&ht->ht_nodes, (lam_list_item_t*)node);
|
||||
ht->ht_size--;
|
||||
return LAM_SUCCESS;
|
||||
}
|
||||
}
|
||||
return LAM_ERR_BAD_PARAM;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Fast hash table interface
|
||||
*
|
||||
* lam_uint64_hash_node_t
|
||||
*/
|
||||
|
||||
static uint32_t lam_log2(unsigned int n)
|
||||
struct lam_uint64_hash_node_t
|
||||
{
|
||||
int overflow;
|
||||
unsigned int cnt, nn;
|
||||
|
||||
cnt = 0;
|
||||
nn = n;
|
||||
while (nn >>= 1) {
|
||||
cnt++;
|
||||
}
|
||||
overflow = (~(1 << cnt) & n) > 0;
|
||||
|
||||
return cnt + overflow;
|
||||
|
||||
lam_list_item_t super;
|
||||
uint64_t hn_key;
|
||||
void* hn_value;
|
||||
};
|
||||
typedef struct lam_uint64_hash_node_t lam_uint64_hash_node_t;
|
||||
|
||||
static void lam_uint64_hash_node_construct(lam_uint64_hash_node_t* hn)
|
||||
{
|
||||
OBJ_CONSTRUCT_SUPER(hn, lam_list_item_t);
|
||||
}
|
||||
|
||||
|
||||
#define DEFAULT_SIZE 128
|
||||
|
||||
void lam_fh_construct(lam_fast_hash_t *htbl)
|
||||
static void lam_uint64_hash_node_destruct(lam_uint64_hash_node_t* hn)
|
||||
{
|
||||
OBJ_CONSTRUCT_SUPER(htbl, lam_object_t);
|
||||
htbl->fh_nodes = 0;
|
||||
htbl->fh_count = 0;
|
||||
htbl->fh_size = 0;
|
||||
htbl->fh_mask = 0;
|
||||
htbl->fh_bucket_cnt = 0;
|
||||
lam_fh_resize(htbl, DEFAULT_SIZE);
|
||||
OBJ_DESTRUCT_SUPER(hn, lam_list_item_t);
|
||||
}
|
||||
|
||||
void lam_fh_destruct(lam_fast_hash_t *htbl)
|
||||
static lam_class_info_t lam_uint64_hash_node_t_class_info = {
|
||||
"lam_uint64_hash_node_t",
|
||||
CLASS_INFO(lam_list_item_t),
|
||||
(lam_construct_t)lam_uint64_hash_node_construct,
|
||||
(lam_destruct_t)lam_uint64_hash_node_destruct
|
||||
};
|
||||
|
||||
|
||||
void* lam_hash_table_get_value_uint64(lam_hash_table_t* ht, uint64_t key)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ( htbl->fh_nodes )
|
||||
{
|
||||
lam_fh_remove_all(htbl);
|
||||
for ( i = 0; i < htbl->fh_size; i++ )
|
||||
{
|
||||
if ( htbl->fh_nodes[i] )
|
||||
free(htbl->fh_nodes[i]);
|
||||
lam_list_t* list = ht->ht_table + (key & ht->ht_mask);
|
||||
lam_uint64_hash_node_t *node;
|
||||
|
||||
for(node = (lam_uint64_hash_node_t*)lam_list_get_first(list);
|
||||
node != (lam_uint64_hash_node_t*)lam_list_get_last(list);
|
||||
node = (lam_uint64_hash_node_t*)lam_list_get_next(list)) {
|
||||
if (node->hn_key == key) {
|
||||
return node->hn_value;
|
||||
}
|
||||
free(htbl->fh_nodes);
|
||||
free(htbl->fh_bucket_cnt);
|
||||
}
|
||||
|
||||
OBJ_DESTRUCT_SUPER(htbl, lam_object_t);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* initialize hash table with fixed size, usually power of 2 or prime */
|
||||
int lam_fh_resize(lam_fast_hash_t *htbl, uint32_t size)
|
||||
int lam_hash_table_set_value_uint64(lam_hash_table_t* ht, uint64_t key, void* value)
|
||||
{
|
||||
uint32_t power2_size;
|
||||
|
||||
/* round up size to power of 2,
|
||||
* if passed size is not power of 2.
|
||||
*/
|
||||
power2_size = 1 << lam_log2(size);
|
||||
htbl->fh_mask = power2_size - 1;
|
||||
htbl->fh_nodes = (lam_fhnode_t **)realloc(htbl->fh_nodes,
|
||||
sizeof(lam_fhnode_t *) * power2_size);
|
||||
if ( 0 == htbl->fh_nodes )
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
|
||||
htbl->fh_bucket_cnt = (uint32_t *)realloc(htbl->fh_bucket_cnt,
|
||||
sizeof(uint32_t) * power2_size);
|
||||
if ( 0 == htbl->fh_bucket_cnt )
|
||||
{
|
||||
free(htbl->fh_nodes);
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
lam_list_t* list = ht->ht_table + (key & ht->ht_mask);
|
||||
lam_uint64_hash_node_t *node;
|
||||
|
||||
if ( power2_size > htbl->fh_size )
|
||||
{
|
||||
/* zero out remaining slots, if adding buckets */
|
||||
memset(htbl->fh_nodes + htbl->fh_size, 0,
|
||||
sizeof(lam_fhnode_t *)*(power2_size - htbl->fh_size));
|
||||
memset(htbl->fh_bucket_cnt + htbl->fh_size, 0,
|
||||
sizeof(uint32_t)*(power2_size - htbl->fh_size));
|
||||
for(node = (lam_uint64_hash_node_t*)lam_list_get_first(list);
|
||||
node != (lam_uint64_hash_node_t*)lam_list_get_last(list);
|
||||
node = (lam_uint64_hash_node_t*)lam_list_get_next(list)) {
|
||||
if (node->hn_key == key) {
|
||||
node->hn_value = value;
|
||||
return LAM_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
node = (lam_uint64_hash_node_t*)lam_list_remove_first(&ht->ht_nodes);
|
||||
if(NULL == node) {
|
||||
node = OBJ_NEW(lam_uint64_hash_node_t);
|
||||
if(NULL == node)
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
htbl->fh_size = power2_size;
|
||||
|
||||
node->hn_key = key;
|
||||
node->hn_value = value;
|
||||
lam_list_append(list, (lam_list_item_t*)node);
|
||||
ht->ht_size++;
|
||||
return LAM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void lam_fh_remove_all(lam_fast_hash_t *htbl)
|
||||
int lam_hash_table_remove_value_uint64(lam_hash_table_t* ht, uint64_t key)
|
||||
{
|
||||
uint32_t i, j;
|
||||
lam_fhnode_t *buckets;
|
||||
|
||||
for ( i = 0; i < htbl->fh_size; i++ )
|
||||
{
|
||||
/* remove all values in nonempty bucket arrays. */
|
||||
if ( htbl->fh_nodes[i] )
|
||||
{
|
||||
buckets = htbl->fh_nodes[i];
|
||||
/* process the bucket array. */
|
||||
for ( j = 0; j < htbl->fh_bucket_cnt[i]; j++ )
|
||||
{
|
||||
if ( true == buckets[j].fhn_is_taken )
|
||||
{
|
||||
buckets[j].fhn_is_taken = false;
|
||||
if ( true == buckets[j].fhn_using_key_ptr )
|
||||
{
|
||||
free(buckets[j].fhn_key.pval);
|
||||
}
|
||||
}
|
||||
} /* end loop over htbl->fh_bucket_cnt[i]. */
|
||||
lam_list_t* list = ht->ht_table + (key & ht->ht_mask);
|
||||
lam_uint64_hash_node_t *node;
|
||||
|
||||
for(node = (lam_uint64_hash_node_t*)lam_list_get_first(list);
|
||||
node != (lam_uint64_hash_node_t*)lam_list_get_last(list);
|
||||
node = (lam_uint64_hash_node_t*)lam_list_get_next(list)) {
|
||||
if (node->hn_key == key) {
|
||||
lam_list_remove_item(list, (lam_list_item_t*)node);
|
||||
lam_list_append(&ht->ht_nodes, (lam_list_item_t*)node);
|
||||
ht->ht_size--;
|
||||
return LAM_SUCCESS;
|
||||
}
|
||||
} /* end loop over htbl->fh_nodes */
|
||||
htbl->fh_count = 0;
|
||||
}
|
||||
return LAM_ERR_BAD_PARAM;
|
||||
}
|
||||
|
||||
|
||||
void *lam_fh_get_value_for_ikey(lam_fast_hash_t *htbl, uint32_t key)
|
||||
{
|
||||
return lam_fh_get_value_nkey(htbl, &key, sizeof(key));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void lam_fh_remove_value_for_ikey(lam_fast_hash_t *htbl, uint32_t key)
|
||||
{
|
||||
lam_fh_remove_value_nkey(htbl, &key, sizeof(key));
|
||||
}
|
||||
|
||||
|
||||
int lam_fh_set_value_for_ikey(lam_fast_hash_t *htbl, void *val, uint32_t key)
|
||||
{
|
||||
return lam_fh_set_value_nkey(htbl, val, &key, sizeof(key));
|
||||
}
|
||||
|
||||
|
||||
void *lam_fh_get_value_for_lkey(lam_fast_hash_t *htbl, uint64_t key)
|
||||
{
|
||||
return lam_fh_get_value_nkey(htbl, &key, sizeof(key));
|
||||
}
|
||||
|
||||
|
||||
void lam_fh_remove_value_for_lkey(lam_fast_hash_t *htbl, uint64_t key)
|
||||
{
|
||||
lam_fh_remove_value_nkey(htbl, &key, sizeof(key));
|
||||
}
|
||||
|
||||
|
||||
int lam_fh_set_value_for_lkey(lam_fast_hash_t *htbl, void *val, uint64_t key)
|
||||
{
|
||||
return lam_fh_set_value_nkey(htbl, val, &key, sizeof(key));
|
||||
}
|
||||
|
||||
|
||||
void *lam_fh_get_value_for_skey(lam_fast_hash_t *htbl, const char *key)
|
||||
{
|
||||
return lam_fh_get_value_ptrkey(htbl, (void *)key, strlen(key)+1);
|
||||
}
|
||||
|
||||
void lam_fh_remove_value_for_skey(lam_fast_hash_t *htbl, const char *key)
|
||||
{
|
||||
lam_fh_remove_value_ptrkey(htbl, (void *)key, strlen(key)+1);
|
||||
}
|
||||
|
||||
int lam_fh_set_value_for_skey(lam_fast_hash_t *htbl, void *val, const char *key)
|
||||
{
|
||||
return lam_fh_set_value_ptrkey(htbl, val, (void *)key, strlen(key)+1);
|
||||
}
|
||||
|
||||
|
@ -8,99 +8,69 @@
|
||||
#include "lam_config.h"
|
||||
#include "lam/stdint.h"
|
||||
#include "lam/types.h"
|
||||
#include "lam/lfc/object.h"
|
||||
#include "lam/lfc/list.h"
|
||||
|
||||
/**
|
||||
* An fhnode stores a hash table item's key and value.
|
||||
*
|
||||
* The struct holds a hash table item's key and value.
|
||||
* It can be reused when a value is removed to store a
|
||||
* different value.
|
||||
*/
|
||||
struct lam_fhnode_t
|
||||
{
|
||||
lam_ptr_t fhn_key; /**< key for looking up value */
|
||||
void *fhn_value; /**< maintains pointer to contained value */
|
||||
bool fhn_using_key_ptr; /**< true-> need to free key when removing item. */
|
||||
bool fhn_is_taken; /**< true-> node is occupied, false-> not occupied */
|
||||
uint32_t fhn_ptr_key_size; /**< size of key when key is ptr */
|
||||
};
|
||||
|
||||
typedef struct lam_fhnode_t lam_fhnode_t;
|
||||
|
||||
/**
|
||||
* Hash table that only allows integer or string keys.
|
||||
*
|
||||
* This version of a hash table is meant to be used when
|
||||
* the key is either an integer or string for faster
|
||||
* processing.
|
||||
*/
|
||||
struct lam_fast_hash_t
|
||||
extern lam_class_info_t lam_hash_table_t_class_info;
|
||||
|
||||
struct lam_hash_table_t
|
||||
{
|
||||
lam_object_t super; /**< subclass of lam_object_t */
|
||||
lam_fhnode_t **fh_nodes; /**< each item is an array of lam_fhnode_t nodes */
|
||||
uint32_t fh_count; /**< number of values on table */
|
||||
uint32_t *fh_bucket_cnt; /**< size of each bucket array */
|
||||
uint32_t fh_mask; /**< used to compute the hash value */
|
||||
uint32_t fh_size;
|
||||
lam_list_t ht_nodes; /**< free list of hash nodes */
|
||||
lam_list_t *ht_table; /**< each item is an array of lam_fhnode_t nodes */
|
||||
size_t ht_table_size; /**< size of table */
|
||||
size_t ht_size; /**< number of values on table */
|
||||
size_t ht_mask;
|
||||
};
|
||||
typedef struct lam_hash_table_t lam_hash_table_t;
|
||||
|
||||
|
||||
typedef struct lam_fast_hash_t lam_fast_hash_t;
|
||||
|
||||
extern lam_class_info_t lam_fast_hash_t_class_info;
|
||||
|
||||
/*
|
||||
*
|
||||
* Fast hash table interface
|
||||
*
|
||||
*/
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A brief description of a simple function
|
||||
* Initializes the table size, must be called before using
|
||||
* the table.
|
||||
*
|
||||
* @param arg An argument
|
||||
* @return The return code
|
||||
* @param table The input hash table (IN).
|
||||
* @param size The size of the table, which will be rounded up
|
||||
* (if required) to the next highest power of two (IN).
|
||||
* @return LAM error code.
|
||||
*
|
||||
* This is a simple function that does not very much. It's just a test
|
||||
* so that I can show what Doxygen does.
|
||||
*/
|
||||
void lam_fh_construct(lam_fast_hash_t *htbl);
|
||||
void lam_fh_destruct(lam_fast_hash_t *htbl);
|
||||
|
||||
/* resize hash table to size */
|
||||
int lam_fh_resize(lam_fast_hash_t *htbl, uint32_t size);
|
||||
|
||||
void lam_fh_remove_all(lam_fast_hash_t *htbl);
|
||||
|
||||
/*
|
||||
* ASSUMPTION: All keys in hash table are of same type, e.g. string, numeric, etc.
|
||||
* For performance reasons, we are not handling mixed key types
|
||||
* in the current implementation (all numeric keys are fine; no mixing of
|
||||
* numeric with strings).
|
||||
*/
|
||||
|
||||
void *lam_fh_get_value_for_ikey(lam_fast_hash_t *htbl, uint32_t key);
|
||||
void lam_fh_remove_value_for_ikey(lam_fast_hash_t *htbl, uint32_t key);
|
||||
int lam_fh_set_value_for_ikey(lam_fast_hash_t *htbl, void *val, uint32_t key);
|
||||
int lam_hash_table_init(lam_hash_table_t* ht, size_t table_size);
|
||||
|
||||
void *lam_fh_get_value_for_lkey(lam_fast_hash_t *htbl, uint64_t key);
|
||||
void lam_fh_remove_value_for_lkey(lam_fast_hash_t *htbl, uint64_t key);
|
||||
int lam_fh_set_value_for_lkey(lam_fast_hash_t *htbl, void *val, uint64_t key);
|
||||
|
||||
void *lam_fh_get_value_for_skey(lam_fast_hash_t *htbl, const char *key);
|
||||
void lam_fh_remove_value_for_skey(lam_fast_hash_t *htbl, const char *key);
|
||||
int lam_fh_set_value_for_skey(lam_fast_hash_t *htbl, void *val, const char *key);
|
||||
/**
|
||||
* Returns the number of elements currently stored in the table.
|
||||
*
|
||||
* @param table The input hash table (IN).
|
||||
* @return The number of elements in the table.
|
||||
*
|
||||
*/
|
||||
|
||||
static inline size_t lam_hash_table_get_size(lam_hash_table_t *ht)
|
||||
{
|
||||
return ht->ht_size;
|
||||
}
|
||||
|
||||
void *lam_hash_table_get_value_uint32(lam_hash_table_t* ht, uint32_t key);
|
||||
int lam_hash_table_set_value_uint32(lam_hash_table_t* ht, uint32_t key, void* value);
|
||||
int lam_hash_table_remove_value_uint32(lam_hash_table_t* ht, uint32_t key);
|
||||
|
||||
void *lam_hash_table_get_value_uint64(lam_hash_table_t *ht, uint64_t key);
|
||||
int lam_hash_table_set_value_uint64(lam_hash_table_t *ht, uint64_t key, void* value);
|
||||
int lam_hash_table_remove_value_uint64(lam_hash_table_t *ht, uint64_t key);
|
||||
|
||||
void *lam_hash_table_get_value_ptr(lam_hash_table_t *ht, void* key, size_t keylen);
|
||||
int lam_hash_table_set_value_ptr(lam_hash_table_t *ht, void* key, size_t keylen, void* value);
|
||||
int lam_hash_table_remove_value_ptr(lam_hash_table_t *ht, void* key, size_t keylen);
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* returns the number of items in the table */
|
||||
static uint32_t lam_fh_count(lam_fast_hash_t *htbl);
|
||||
static inline uint32_t lam_fh_count(lam_fast_hash_t *htbl) {return htbl->fh_count;}
|
||||
|
||||
#endif /* LAM_HASH_TABLE_H */
|
||||
|
@ -11,12 +11,12 @@
|
||||
/*
|
||||
* typedefs
|
||||
*/
|
||||
typedef struct lam_pointer_array lam_pointer_array_t;
|
||||
typedef struct lam_pointer_array_t lam_pointer_array_t;
|
||||
|
||||
/*
|
||||
* dynamic pointer array
|
||||
*/
|
||||
struct lam_pointer_array {
|
||||
struct lam_pointer_array_t {
|
||||
/* synchronization object */
|
||||
lam_mutex_t lock;
|
||||
/* index of lowest free element */
|
||||
|
52
src/lam/lfc/lam_value_array.c
Обычный файл
52
src/lam/lfc/lam_value_array.c
Обычный файл
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "lam/lfc/lam_value_array.h"
|
||||
|
||||
|
||||
static void lam_value_array_construct(lam_value_array_t* array)
|
||||
{
|
||||
OBJ_CONSTRUCT_SUPER(array, lam_object_t);
|
||||
array->array_items = NULL;
|
||||
array->array_size = 0;
|
||||
array->array_item_sizeof = 0;
|
||||
array->array_alloc_size = 0;
|
||||
}
|
||||
|
||||
static void lam_value_array_destruct(lam_value_array_t* array)
|
||||
{
|
||||
if (NULL != array->array_items)
|
||||
free(array->array_items);
|
||||
OBJ_DESTRUCT_SUPER(array, lam_object_t);
|
||||
}
|
||||
|
||||
lam_class_info_t lam_value_array_t_class_info = {
|
||||
"lam_value_array_t",
|
||||
CLASS_INFO(lam_object_t),
|
||||
(lam_construct_t)lam_value_array_construct,
|
||||
(lam_destruct_t)lam_value_array_destruct
|
||||
};
|
||||
|
||||
|
||||
int lam_value_array_set_size(lam_value_array_t* array, size_t size)
|
||||
{
|
||||
#if LAM_ENABLE_DEBUG
|
||||
if(array->array_item_sizeof == 0) {
|
||||
lam_output(0, "lam_value_array_set_size: item size must be initialized");
|
||||
return LAM_ERR_BAD_PARAM;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(array->array_size > array->array_alloc_size) {
|
||||
while(array->array_alloc_size < array->array_size)
|
||||
array->array_alloc_size <<= 1;
|
||||
array->array_items = realloc(array->array_items,
|
||||
array->array_alloc_size * array->array_item_sizeof);
|
||||
if (NULL == array->array_items)
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
array->array_size = size;
|
||||
return LAM_SUCCESS;
|
||||
}
|
||||
|
239
src/lam/lfc/lam_value_array.h
Обычный файл
239
src/lam/lfc/lam_value_array.h
Обычный файл
@ -0,0 +1,239 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#ifndef LAM_VALUE_ARRAY_H
|
||||
#define LAM_VALUE_ARRAY_H
|
||||
|
||||
#include <string.h>
|
||||
#include "lam_config.h"
|
||||
#include "lam/constants.h"
|
||||
#include "lam/types.h"
|
||||
#include "lam/lfc/object.h"
|
||||
#if LAM_ENABLE_DEBUG
|
||||
#include "lam/util/output.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Array of elements maintained by value.
|
||||
*/
|
||||
|
||||
extern lam_class_info_t lam_value_array_t_class_info;
|
||||
|
||||
|
||||
struct lam_value_array_t
|
||||
{
|
||||
lam_object_t super;
|
||||
unsigned char* array_items;
|
||||
size_t array_item_sizeof;
|
||||
size_t array_size;
|
||||
size_t array_alloc_size;
|
||||
};
|
||||
typedef struct lam_value_array_t lam_value_array_t;
|
||||
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initialize the array to hold items by value. This routine must
|
||||
* be called prior to using the array.
|
||||
*
|
||||
* @param array The array to initialize (IN).
|
||||
* @param item_size The sizeof each array element (IN).
|
||||
* @return LAM error code
|
||||
*/
|
||||
|
||||
static inline int lam_value_array_init(lam_value_array_t *array, size_t item_sizeof)
|
||||
{
|
||||
array->array_item_sizeof = item_sizeof;
|
||||
array->array_alloc_size = 1;
|
||||
array->array_items = malloc(item_sizeof * array->array_alloc_size);
|
||||
return (NULL != array->array_items) ? LAM_SUCCESS : LAM_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retreives the number of elements in the array.
|
||||
*
|
||||
* @param array The input array (IN).
|
||||
* @return The number of elements currently in use.
|
||||
*/
|
||||
|
||||
static inline size_t lam_value_array_get_size(lam_value_array_t* array)
|
||||
{
|
||||
return array->array_size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the number of elements in the array.
|
||||
*
|
||||
* @param array The input array (IN).
|
||||
* @param size The new array size.
|
||||
*
|
||||
* @return LAM error code.
|
||||
*
|
||||
* Note that resizing the array to a smaller size may not change
|
||||
* the underlying memory allocated by the array. However, setting
|
||||
* the size larger than the current allocation will grow it. In either
|
||||
* case, if the routine is successful, lam_value_array_get_size() will
|
||||
* return the new size.
|
||||
*/
|
||||
|
||||
int lam_value_array_set_size(lam_value_array_t* array, size_t size);
|
||||
|
||||
|
||||
/**
|
||||
* Macro to retrieve an item from the array by value.
|
||||
*
|
||||
* @param array The input array (IN).
|
||||
* @param item_type The C datatype of the array item (IN).
|
||||
* @param item_index The array index (IN).
|
||||
*
|
||||
* @returns item The requested item.
|
||||
*
|
||||
* Note that this does not change the size of the array - this macro is
|
||||
* strictly for performance - the user assumes the responsibility of
|
||||
* ensuring the array index is valid (0 <= item index < array size).
|
||||
*/
|
||||
|
||||
#define LAM_VALUE_ARRAY_GET_ITEM(array, item_type, item_index) \
|
||||
((item_type*)((array)->array_items))[item_index]
|
||||
|
||||
/**
|
||||
* Retrieve an item from the array by reference.
|
||||
*
|
||||
* @param array The input array (IN).
|
||||
* @param index The array index (IN).
|
||||
*
|
||||
* @return ptr Pointer to the requested item.
|
||||
*
|
||||
* Note that if the specified index is larger than the current
|
||||
* array size, the array is grown to satisfy the request.
|
||||
*/
|
||||
|
||||
static inline void* lam_value_array_get_item(lam_value_array_t *array, size_t index)
|
||||
{
|
||||
if(index >= array->array_size && lam_value_array_set_size(array, index+1) != LAM_SUCCESS)
|
||||
return NULL;
|
||||
return array->array_items + (index * array->array_item_sizeof);
|
||||
}
|
||||
|
||||
/**
|
||||
* Macro to set an array element by value.
|
||||
*
|
||||
* @param array The input array (IN).
|
||||
* @param item_type The C datatype of the array item (IN).
|
||||
* @param item_index The array index (IN).
|
||||
* @param item_value The new value for the specified index (IN).
|
||||
*
|
||||
* Note that this does not change the size of the array - this macro is
|
||||
* strictly for performance - the user assumes the responsibility of
|
||||
* ensuring the array index is valid (0 <= item index < array size).
|
||||
*
|
||||
* It is safe to free the item after returning from this call; it is
|
||||
* copied into the array by value.
|
||||
*/
|
||||
|
||||
#define LAM_VALUE_ARRAY_SET_ITEM(array, item_type, item_index, item_value) \
|
||||
(((item_type*)((array)->array_items))[item_index] = item_value)
|
||||
|
||||
/**
|
||||
* Set an array element by value.
|
||||
*
|
||||
* @param array The input array (IN).
|
||||
* @param item_index The array index (IN).
|
||||
* @param item_value A pointer to the item, which is copied into
|
||||
* the array.
|
||||
*
|
||||
* @return LAM error code.
|
||||
*
|
||||
* It is safe to free the item after returning from this call; it is
|
||||
* copied into the array by value.
|
||||
*/
|
||||
|
||||
static inline int lam_value_array_set_item(lam_value_array_t *array, size_t index, const void* item)
|
||||
{
|
||||
int rc;
|
||||
if(index >= array->array_size &&
|
||||
(rc = lam_value_array_set_size(array, index+1)) != LAM_SUCCESS)
|
||||
return rc;
|
||||
memcpy(array->array_items + (index * array->array_item_sizeof), item, array->array_item_sizeof);
|
||||
return LAM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Appends an item to the end of the array.
|
||||
*
|
||||
* @param array The input array (IN).
|
||||
* @param item A pointer to the item to append, which is copied
|
||||
* into the array.
|
||||
*
|
||||
* @return LAM error code
|
||||
*
|
||||
* This will grow the array if it is not large enough to contain the
|
||||
* item. It is safe to free the item after returning from this call;
|
||||
* it is copied by value into the array.
|
||||
*/
|
||||
|
||||
static inline int lam_value_array_append_item(lam_value_array_t *array, const void *item)
|
||||
{
|
||||
return lam_value_array_set_item(array, array->array_size, item);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a specific item from the array.
|
||||
*
|
||||
* @param array The input array (IN).
|
||||
* @param index The index to remove, which must be less than
|
||||
* the current array size (IN).
|
||||
*
|
||||
* @return LAM error code.
|
||||
*
|
||||
* All elements following this index are shifted down.
|
||||
*/
|
||||
|
||||
static inline int lam_value_array_remove_item(lam_value_array_t *array, size_t index)
|
||||
{
|
||||
#if LAM_ENABLE_DEBUG
|
||||
if (index >= array->array_size) {
|
||||
lam_output(0, "lam_value_array_remove_item: invalid index %d\n", index);
|
||||
return LAM_ERR_BAD_PARAM;
|
||||
}
|
||||
#endif
|
||||
memmove(array->array_items+(array->array_item_sizeof * index),
|
||||
array->array_items+(array->array_item_sizeof * (index+1)),
|
||||
array->array_item_sizeof * (array->array_size - index - 1));
|
||||
array->array_size--;
|
||||
return LAM_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base pointer of the underlying array.
|
||||
*
|
||||
* @param array The input array (IN).
|
||||
* @param array_type The C datatype of the array (IN).
|
||||
*
|
||||
* @returns ptr Pointer to the actual array.
|
||||
*
|
||||
* This function is helpful when you need to iterate through an
|
||||
* entire array; simply get the base value of the array and use native
|
||||
* C to iterate through it manually. This can have better performance
|
||||
* than looping over LAM_VALUE_ARRAY_GET_ITEM() and
|
||||
* LAM_VALUE_ARRAY_SET_ITEM() because it will [potentially] reduce the
|
||||
* number of pointer dereferences.
|
||||
*/
|
||||
|
||||
#define LAM_VALUE_ARRAY_GET_BASE(array, item_type) \
|
||||
((item_type*) ((array)->array_items))
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -8,14 +8,19 @@
|
||||
* List classes
|
||||
*/
|
||||
|
||||
static void lam_list_item_construct(lam_list_item_t*);
|
||||
static void lam_list_item_destruct(lam_list_item_t*);
|
||||
|
||||
lam_class_info_t lam_list_item_t_class_info = {
|
||||
"lam_list_item_t",
|
||||
CLASS_INFO(lam_object_t),
|
||||
(lam_construct_t) lam_list_item_construct,
|
||||
(lam_destruct_t) lam_object_destruct
|
||||
(lam_destruct_t) lam_list_item_destruct
|
||||
};
|
||||
|
||||
static void lam_list_construct(lam_list_t*);
|
||||
static void lam_list_destruct(lam_list_t*);
|
||||
|
||||
lam_class_info_t lam_list_t_class_info = {
|
||||
"lam_list_t",
|
||||
CLASS_INFO(lam_object_t),
|
||||
@ -30,13 +35,18 @@ lam_class_info_t lam_list_t_class_info = {
|
||||
*
|
||||
*/
|
||||
|
||||
void lam_list_item_construct(lam_list_item_t *item)
|
||||
static void lam_list_item_construct(lam_list_item_t *item)
|
||||
{
|
||||
OBJ_CONSTRUCT_SUPER(item, lam_object_t);
|
||||
item->lam_list_next = item->lam_list_prev = NULL;
|
||||
item->lam_list_type = 0;
|
||||
}
|
||||
|
||||
static void lam_list_item_destruct(lam_list_item_t *item)
|
||||
{
|
||||
OBJ_DESTRUCT_SUPER(item, lam_object_t);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
@ -44,7 +54,7 @@ void lam_list_item_construct(lam_list_item_t *item)
|
||||
*
|
||||
*/
|
||||
|
||||
void lam_list_construct(lam_list_t *list)
|
||||
static void lam_list_construct(lam_list_t *list)
|
||||
{
|
||||
OBJ_CONSTRUCT_SUPER(list, lam_object_t);
|
||||
list->lam_list_head.lam_list_prev = NULL;
|
||||
@ -56,7 +66,7 @@ void lam_list_construct(lam_list_t *list)
|
||||
}
|
||||
|
||||
|
||||
void lam_list_destruct(lam_list_t *list)
|
||||
static void lam_list_destruct(lam_list_t *list)
|
||||
{
|
||||
/* release all items in list */
|
||||
lam_list_construct(list);
|
||||
|
@ -34,14 +34,6 @@ typedef struct lam_list_item
|
||||
volatile struct lam_list_item *lam_list_prev;
|
||||
} lam_list_item_t;
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
void lam_list_item_construct(lam_list_item_t *item);
|
||||
void lam_list_item_destruct(lam_list_item_t *item);
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#define lam_list_get_next(item) \
|
||||
((item) ? ((lam_list_item_t*) ((lam_list_item_t*)(item))->lam_list_next) : NULL)
|
||||
@ -65,15 +57,6 @@ typedef struct lam_list
|
||||
} lam_list_t;
|
||||
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
void lam_list_construct(lam_list_t *list);
|
||||
void lam_list_destruct(lam_list_t *list);
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Inlined accessor functions
|
||||
*/
|
||||
|
@ -29,7 +29,7 @@ void lam_sgl_construct(lam_seg_list_t *slist)
|
||||
|
||||
void lam_sgl_destruct(lam_seg_list_t *slist)
|
||||
{
|
||||
lam_list_destruct(&(slist->sgl_list));
|
||||
OBJ_DESTRUCT(&(slist->sgl_list));
|
||||
OBJ_DESTRUCT_SUPER(slist, lam_object_t);
|
||||
}
|
||||
|
||||
|
@ -110,8 +110,8 @@ lam_cmd_line_t *lam_cmd_line_create(void)
|
||||
|
||||
/* Initialize the lists */
|
||||
|
||||
lam_list_construct(&cmd->lcl_options);
|
||||
lam_list_construct(&cmd->lcl_params);
|
||||
OBJ_CONSTRUCT(&cmd->lcl_options, lam_list_t);
|
||||
OBJ_CONSTRUCT(&cmd->lcl_params, lam_list_t);
|
||||
|
||||
/* Initialize the argc/argv pairs */
|
||||
|
||||
@ -225,7 +225,7 @@ int lam_cmd_line_make_opt(lam_cmd_line_t *cmd, char short_name,
|
||||
option = malloc(sizeof(cmd_line_option_t));
|
||||
if (NULL == option)
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
lam_list_item_construct((lam_list_item_t *) option);
|
||||
OBJ_CONSTRUCT((lam_list_item_t *) option, lam_list_item_t);
|
||||
|
||||
option->clo_short_name = short_name;
|
||||
if (NULL != long_name) {
|
||||
@ -393,7 +393,7 @@ int lam_cmd_line_parse(lam_cmd_line_t *cmd, bool ignore_unknown,
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
item = (lam_list_item_t *) param;
|
||||
lam_list_item_construct(item);
|
||||
OBJ_CONSTRUCT(item, lam_list_item_t);
|
||||
param->clp_arg = cmd->lcl_argv[i];
|
||||
param->clp_option = option;
|
||||
param->clp_argc = 0;
|
||||
|
@ -25,7 +25,7 @@
|
||||
#endif
|
||||
|
||||
struct lam_if_t {
|
||||
lam_list_item_t if_item;
|
||||
lam_list_item_t super;
|
||||
char if_name[IF_NAMESIZE];
|
||||
int if_index;
|
||||
int if_flags;
|
||||
@ -72,7 +72,6 @@ static int lam_ifinit(void)
|
||||
struct ifreq* ifr = (struct ifreq*)ptr;
|
||||
lam_if_t intf;
|
||||
lam_if_t *intf_ptr;
|
||||
lam_list_item_construct(&intf.if_item);
|
||||
|
||||
OBJ_CONSTRUCT(&intf, lam_list_item_t);
|
||||
|
||||
|
@ -75,11 +75,11 @@ void lam_reactor_construct(lam_reactor_t* r)
|
||||
OBJ_CONSTRUCT_SUPER(r, lam_object_t);
|
||||
|
||||
lam_mutex_construct(&r->r_mutex);
|
||||
lam_list_construct(&r->r_active);
|
||||
lam_list_construct(&r->r_free);
|
||||
lam_list_construct(&r->r_pending);
|
||||
lam_fh_construct(&r->r_hash);
|
||||
lam_fh_resize(&r->r_hash, 1024);
|
||||
OBJ_CONSTRUCT(&r->r_active, lam_list_t);
|
||||
OBJ_CONSTRUCT(&r->r_free, lam_list_t);
|
||||
OBJ_CONSTRUCT(&r->r_pending, lam_list_t);
|
||||
OBJ_CONSTRUCT(&r->r_hash, lam_hash_table_t);
|
||||
lam_hash_table_init(&r->r_hash, 1024);
|
||||
|
||||
r->r_max = -1;
|
||||
r->r_run = true;
|
||||
@ -93,10 +93,10 @@ void lam_reactor_construct(lam_reactor_t* r)
|
||||
|
||||
void lam_reactor_destruct(lam_reactor_t* r)
|
||||
{
|
||||
lam_list_destruct(&r->r_active);
|
||||
lam_list_destruct(&r->r_free);
|
||||
lam_list_destruct(&r->r_pending);
|
||||
lam_fh_destruct(&r->r_hash);
|
||||
OBJ_DESTRUCT(&r->r_active);
|
||||
OBJ_DESTRUCT(&r->r_free);
|
||||
OBJ_DESTRUCT(&r->r_pending);
|
||||
OBJ_DESTRUCT(&r->r_hash);
|
||||
OBJ_DESTRUCT_SUPER(r, lam_object_t);
|
||||
}
|
||||
|
||||
@ -119,7 +119,7 @@ int lam_reactor_insert(lam_reactor_t* r, int sd, lam_reactor_listener_t* listene
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
lam_list_append(&r->r_pending, &descriptor->super);
|
||||
lam_fh_set_value_for_ikey(&r->r_hash,descriptor,sd);
|
||||
lam_hash_table_set_value_uint32(&r->r_hash,sd,descriptor);
|
||||
}
|
||||
|
||||
descriptor->rd_flags |= flags;
|
||||
@ -154,7 +154,8 @@ int lam_reactor_remove(lam_reactor_t* r, int sd, int flags)
|
||||
#endif
|
||||
|
||||
lam_mutex_lock(&r->r_mutex);
|
||||
lam_reactor_descriptor_t* descriptor = (lam_reactor_descriptor_t*)lam_fh_get_value_for_ikey(&r->r_hash, sd);
|
||||
lam_reactor_descriptor_t* descriptor =
|
||||
(lam_reactor_descriptor_t*)lam_hash_table_get_value_uint32(&r->r_hash, sd);
|
||||
if (NULL == descriptor) {
|
||||
lam_output(0, "lam_reactor_remove(%d): descriptor not registered", sd);
|
||||
lam_mutex_unlock(&r->r_mutex);
|
||||
@ -220,7 +221,7 @@ void lam_reactor_dispatch(lam_reactor_t* r, int cnt, lam_fd_set_t* rset, lam_fd_
|
||||
while(descriptor != 0) {
|
||||
lam_reactor_descriptor_t* next = (lam_reactor_descriptor_t*)lam_list_get_next(&r->r_active);
|
||||
if(descriptor->rd_flags == 0) {
|
||||
lam_fh_remove_value_for_ikey(&r->r_hash, descriptor->rd);
|
||||
lam_hash_table_remove_value_uint32(&r->r_hash, descriptor->rd);
|
||||
lam_list_remove_item(&r->r_active, (lam_list_item_t*)descriptor);
|
||||
if(lam_list_get_size(&r->r_free) < MAX_DESCRIPTOR_POOL_SIZE) {
|
||||
lam_list_append(&r->r_free, &descriptor->super);
|
||||
@ -236,7 +237,7 @@ void lam_reactor_dispatch(lam_reactor_t* r, int cnt, lam_fd_set_t* rset, lam_fd_
|
||||
while(lam_list_get_size(&r->r_pending)) {
|
||||
lam_reactor_descriptor_t* descriptor = (lam_reactor_descriptor_t*)lam_list_remove_first(&r->r_pending);
|
||||
if(descriptor->rd_flags == 0) {
|
||||
lam_fh_remove_value_for_ikey(&r->r_hash, descriptor->rd);
|
||||
lam_hash_table_remove_value_uint32(&r->r_hash, descriptor->rd);
|
||||
if(lam_list_get_size(&r->r_free) < MAX_DESCRIPTOR_POOL_SIZE) {
|
||||
lam_list_append(&r->r_free, &descriptor->super);
|
||||
} else {
|
||||
|
@ -15,6 +15,7 @@ extern const int LAM_REACTOR_NOTIFY_RECV;
|
||||
extern const int LAM_REACTOR_NOTIFY_SEND;
|
||||
extern const int LAM_REACTOR_NOTIFY_EXCEPT;
|
||||
|
||||
extern lam_class_info_t lam_reactor_t_class_info;
|
||||
extern lam_class_info_t lam_reactor_descriptor_t_class_info;
|
||||
|
||||
|
||||
@ -62,7 +63,7 @@ struct lam_reactor_t {
|
||||
lam_list_t r_active;
|
||||
lam_list_t r_free;
|
||||
lam_list_t r_pending;
|
||||
lam_fast_hash_t r_hash;
|
||||
lam_hash_table_t r_hash;
|
||||
int r_max;
|
||||
bool r_run;
|
||||
int r_changes;
|
||||
|
@ -100,13 +100,13 @@ int mca_base_module_find(const char *directory, const char *type,
|
||||
|
||||
/* Find all the modules that were statically linked in */
|
||||
|
||||
lam_list_construct(found_modules);
|
||||
OBJ_CONSTRUCT(found_modules, lam_list_t);
|
||||
for (i = 0; NULL != static_modules[i]; ++i) {
|
||||
mli = malloc(sizeof(mca_base_module_list_item_t));
|
||||
if (NULL == mli) {
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
lam_list_item_construct((lam_list_item_t *) mli);
|
||||
OBJ_CONSTRUCT(mli, lam_list_item_t);
|
||||
mli->mli_module = static_modules[i];
|
||||
lam_list_append(found_modules, (lam_list_item_t *) mli);
|
||||
}
|
||||
@ -172,7 +172,7 @@ static void find_dyn_modules(const char *path, const char *type_name,
|
||||
make a master array of all the matching filenames that we
|
||||
find. */
|
||||
|
||||
lam_list_construct(&found_files);
|
||||
OBJ_CONSTRUCT(&found_files, lam_list_t);
|
||||
dir = path_to_use;
|
||||
do {
|
||||
end = strchr(dir, ':');
|
||||
@ -269,7 +269,7 @@ static int save_filename(const char *filename, lt_ptr data)
|
||||
if (NULL == module_file) {
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
lam_list_item_construct((lam_list_item_t *) module_file);
|
||||
OBJ_CONSTRUCT(module_file, lam_list_item_t);
|
||||
strcpy(module_file->type, params->type);
|
||||
strcpy(module_file->name, basename + prefix_len);
|
||||
strcpy(module_file->basename, basename);
|
||||
@ -332,7 +332,7 @@ static int open_module(module_file_item_t *target_file,
|
||||
them. If we can't load them, then this module must also fail to
|
||||
load. */
|
||||
|
||||
lam_list_construct(&dependencies);
|
||||
OBJ_CONSTRUCT(&dependencies, lam_list_t);
|
||||
if (0 != check_laminfo(target_file, &dependencies, found_modules)) {
|
||||
target_file->status = FAILED_TO_LOAD;
|
||||
free_dependency_list(&dependencies);
|
||||
@ -372,7 +372,7 @@ static int open_module(module_file_item_t *target_file,
|
||||
free_dependency_list(&dependencies);
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
lam_list_item_construct((lam_list_item_t *) mitem);
|
||||
OBJ_CONSTRUCT(mitem, lam_list_item_t);
|
||||
|
||||
module_struct = lt_dlsym(module_handle, struct_name);
|
||||
if (NULL == module_struct) {
|
||||
@ -408,7 +408,7 @@ static int open_module(module_file_item_t *target_file,
|
||||
ditem->di_module_file_item->name);
|
||||
free(ditem);
|
||||
}
|
||||
lam_list_destruct(&dependencies);
|
||||
OBJ_DESTRUCT(&dependencies);
|
||||
|
||||
lam_output_verbose(0, 40, " opened dynamic %s MCA module \"%s\"",
|
||||
target_file->type, target_file->name, NULL);
|
||||
@ -626,7 +626,7 @@ static int check_dependency(char *line, module_file_item_t *target_file,
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
cur = (lam_list_item_t *) ditem;
|
||||
lam_list_item_construct(cur);
|
||||
OBJ_CONSTRUCT(cur, lam_list_item_t);
|
||||
lam_list_append(dependencies, cur);
|
||||
|
||||
/* All done -- all depenencies satisfied */
|
||||
@ -647,5 +647,5 @@ static void free_dependency_list(lam_list_t *dependencies)
|
||||
item = lam_list_remove_first(dependencies)) {
|
||||
free(item);
|
||||
}
|
||||
lam_list_destruct(dependencies);
|
||||
OBJ_DESTRUCT(dependencies);
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ int mca_base_module_registry_construct(void)
|
||||
if (lt_dlinit() != 0)
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
|
||||
lam_list_construct(®istry);
|
||||
OBJ_CONSTRUCT(®istry, lam_list_t);
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
@ -96,12 +96,12 @@ int mca_base_module_registry_retain(char *type, lt_dlhandle module_handle,
|
||||
|
||||
/* Initialize the registry item */
|
||||
|
||||
lam_list_item_construct((lam_list_item_t *) ri);
|
||||
OBJ_CONSTRUCT(ri, lam_list_item_t);
|
||||
strcpy(ri->ri_type, type);
|
||||
ri->ri_dlhandle = module_handle;
|
||||
ri->ri_module_struct = module_struct;
|
||||
ri->ri_refcount = 1;
|
||||
lam_list_construct(&ri->ri_dependencies);
|
||||
OBJ_CONSTRUCT(&ri->ri_dependencies, lam_list_t);
|
||||
|
||||
/* Append the new item to the registry */
|
||||
|
||||
@ -234,7 +234,7 @@ static int link_items(registry_item_t *src, registry_item_t *depend)
|
||||
|
||||
/* Initialize the new dependency item */
|
||||
|
||||
lam_list_item_construct((lam_list_item_t *) di);
|
||||
OBJ_CONSTRUCT((lam_list_item_t *) di, lam_list_item_t);
|
||||
di->di_registry_entry = depend;
|
||||
|
||||
/* Add it to the dependency list on the source registry entry */
|
||||
@ -283,7 +283,7 @@ static void release_registry_item(registry_item_t *ri)
|
||||
pointer is no longer valid because it has [potentially] been
|
||||
unloaded from memory. So don't try to use it. :-) */
|
||||
|
||||
lam_list_destruct(&di->di_registry_entry->ri_dependencies);
|
||||
OBJ_DESTRUCT(&di->di_registry_entry->ri_dependencies);
|
||||
lam_list_remove_item(®istry, (lam_list_item_t *) ri);
|
||||
free(ri);
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ static int open_modules(const char *type_name, int output_id,
|
||||
|
||||
/* Traverse the list of found modules */
|
||||
|
||||
lam_list_construct(modules_available);
|
||||
OBJ_CONSTRUCT(modules_available, lam_list_t);
|
||||
for (item = lam_list_get_first(modules_found);
|
||||
lam_list_get_end(modules_found) != item;
|
||||
item = lam_list_get_next(item)) {
|
||||
@ -254,7 +254,7 @@ static int open_modules(const char *type_name, int output_id,
|
||||
if (NULL == mli) {
|
||||
return LAM_ERROR;
|
||||
}
|
||||
lam_list_item_construct(&mli->super);
|
||||
OBJ_CONSTRUCT(&mli->super, lam_list_item_t);
|
||||
mli->mli_module = module;
|
||||
lam_list_append(modules_available, (lam_list_item_t *) mli);
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ int mca_mpi_init_select_modules(int requested,
|
||||
allow_multi_user_threads |= user_threads;
|
||||
have_hidden_threads |= hidden_threads;
|
||||
|
||||
lam_list_construct(&colls);
|
||||
OBJ_CONSTRUCT(&colls, lam_list_t);
|
||||
if (LAM_SUCCESS != mca_coll_base_select(&colls, &user_threads,
|
||||
&hidden_threads)) {
|
||||
return LAM_ERROR;
|
||||
|
@ -15,10 +15,12 @@ lam_class_info_t mca_pml_base_request_t_class_info = {
|
||||
void mca_pml_base_request_construct(mca_pml_base_request_t* req)
|
||||
{
|
||||
OBJ_CONSTRUCT_SUPER(req, lam_request_t);
|
||||
lam_mutex_construct(&req->req_lock);
|
||||
}
|
||||
|
||||
void mca_pml_base_request_destruct(mca_pml_base_request_t* req)
|
||||
{
|
||||
lam_mutex_destruct(&req->req_lock);
|
||||
OBJ_DESTRUCT_SUPER(req, lam_request_t);
|
||||
}
|
||||
|
||||
|
@ -31,30 +31,32 @@ typedef enum {
|
||||
|
||||
/* MPI pml (point-to-point) request */
|
||||
typedef struct {
|
||||
/* base request */
|
||||
lam_request_t super;
|
||||
/* pointer to application buffer */
|
||||
void *req_addr;
|
||||
/* length of application buffer */
|
||||
size_t req_length;
|
||||
/* peer process - rank w/in this communicator */
|
||||
int32_t req_peer;
|
||||
/* user defined tag */
|
||||
int32_t req_tag;
|
||||
/* communicator pointer */
|
||||
lam_communicator_t *req_communicator;
|
||||
/* pointer to data type */
|
||||
lam_datatype_t *req_datatype;
|
||||
/* MPI request type - used for test */
|
||||
mca_pml_base_request_type_t req_type;
|
||||
/* MPI request status */
|
||||
mca_pml_base_request_status_t req_status;
|
||||
/* persistence indicating if the this is a persistent request */
|
||||
bool req_persistent;
|
||||
/* flag indicating if MPI is done with this request called */
|
||||
bool req_mpi_done;
|
||||
/* flag indicating if the pt-2-pt layer is done with this request */
|
||||
bool req_pml_layer_done;
|
||||
/* base request */
|
||||
lam_request_t super;
|
||||
/* pointer to application buffer */
|
||||
void *req_addr;
|
||||
/* length of application buffer */
|
||||
size_t req_length;
|
||||
/* peer process - rank w/in this communicator */
|
||||
int32_t req_peer;
|
||||
/* user defined tag */
|
||||
int32_t req_tag;
|
||||
/* communicator pointer */
|
||||
lam_communicator_t *req_communicator;
|
||||
/* pointer to data type */
|
||||
lam_datatype_t *req_datatype;
|
||||
/* MPI request type - used for test */
|
||||
mca_pml_base_request_type_t req_type;
|
||||
/* MPI request status */
|
||||
mca_pml_base_request_status_t req_status;
|
||||
/* persistence indicating if the this is a persistent request */
|
||||
bool req_persistent;
|
||||
/* flag indicating if MPI is done with this request called */
|
||||
bool req_mpi_done;
|
||||
/* flag indicating if the pt-2-pt layer is done with this request */
|
||||
bool req_pml_layer_done;
|
||||
/* lock to update request status */
|
||||
lam_mutex_t req_lock;
|
||||
} mca_pml_base_request_t;
|
||||
|
||||
|
||||
|
@ -47,7 +47,7 @@ int mca_pml_base_select(mca_pml_t *selected, bool *allow_multi_user_threads,
|
||||
|
||||
best_priority = -1;
|
||||
best_module = NULL;
|
||||
lam_list_construct(&opened);
|
||||
OBJ_CONSTRUCT(&opened, lam_list_t);
|
||||
for (item = lam_list_get_first(&mca_pml_base_modules_available);
|
||||
lam_list_get_end(&mca_pml_base_modules_available) != item;
|
||||
item = lam_list_get_next(item)) {
|
||||
@ -81,7 +81,7 @@ int mca_pml_base_select(mca_pml_t *selected, bool *allow_multi_user_threads,
|
||||
if (NULL == om) {
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
lam_list_item_construct((lam_list_item_t *) om);
|
||||
OBJ_CONSTRUCT(om, lam_list_item_t);
|
||||
om->om_module = module;
|
||||
lam_list_append(&opened, (lam_list_item_t*) om);
|
||||
}
|
||||
|
@ -58,8 +58,10 @@ static inline int mca_pml_teg_param_register_int(
|
||||
|
||||
int mca_pml_teg_module_open(void)
|
||||
{
|
||||
lam_mutex_construct(&mca_pml_teg.teg_lock);
|
||||
OBJ_CONSTRUCT(&mca_pml_teg.teg_recv_requests, lam_free_list_t);
|
||||
OBJ_CONSTRUCT(&mca_pml_teg.teg_procs, lam_list_t);
|
||||
|
||||
mca_pml_teg.teg_free_list_num =
|
||||
mca_pml_teg_param_register_int("free_list_num", 256);
|
||||
mca_pml_teg.teg_free_list_max =
|
||||
@ -78,6 +80,7 @@ int mca_pml_teg_module_close(void)
|
||||
free(mca_pml_teg.teg_ptls);
|
||||
OBJ_DESTRUCT(&mca_pml_teg.teg_recv_requests);
|
||||
OBJ_DESTRUCT(&mca_pml_teg.teg_procs);
|
||||
lam_mutex_destruct(&mca_pml_teg.teg_lock);
|
||||
return LAM_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ static void mca_pml_ptl_comm_destruct(mca_pml_comm_t* comm)
|
||||
free(comm->c_unexpected_frags_lock);
|
||||
free(comm->c_frags_cant_match);
|
||||
free(comm->c_specific_receives);
|
||||
lam_list_destruct(&comm->c_wild_receives);
|
||||
OBJ_DESTRUCT(&comm->c_wild_receives);
|
||||
OBJ_DESTRUCT_SUPER(comm, lam_object_t);
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ int mca_pml_ptl_comm_init_size(mca_pml_comm_t* comm, size_t size)
|
||||
if(NULL == comm->c_unexpected_frags)
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
for(i=0; i<size; i++)
|
||||
lam_list_construct(comm->c_unexpected_frags+i);
|
||||
OBJ_CONSTRUCT(comm->c_unexpected_frags+i, lam_list_t);
|
||||
|
||||
/* these locks are needed to avoid a probe interfering with a match */
|
||||
comm->c_unexpected_frags_lock = malloc(sizeof(lam_mutex_t) * size);
|
||||
@ -77,14 +77,14 @@ int mca_pml_ptl_comm_init_size(mca_pml_comm_t* comm, size_t size)
|
||||
if(NULL == comm->c_frags_cant_match)
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
for(i=0; i<size; i++)
|
||||
lam_list_construct(comm->c_frags_cant_match+i);
|
||||
OBJ_CONSTRUCT(comm->c_frags_cant_match+i, lam_list_t);
|
||||
|
||||
/* queues of unmatched specific (source process specified) receives */
|
||||
comm->c_specific_receives = malloc(sizeof(lam_list_t) * size);
|
||||
if(NULL == comm->c_specific_receives)
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
for(i=0; i<size; i++)
|
||||
lam_list_construct(comm->c_specific_receives+i);
|
||||
OBJ_CONSTRUCT(comm->c_specific_receives+i, lam_list_t);
|
||||
|
||||
return LAM_SUCCESS;
|
||||
}
|
||||
|
@ -584,7 +584,7 @@ static void mca_ptl_base_check_cantmatch_for_match(lam_list_t *additional_matche
|
||||
*/
|
||||
if(0 == lam_list_get_size(additional_matches))
|
||||
{
|
||||
lam_list_construct(additional_matches);
|
||||
OBJ_CONSTRUCT(additional_matches, lam_list_t);
|
||||
}
|
||||
|
||||
/* We're now expecting the next sequence number. */
|
||||
|
@ -47,7 +47,7 @@ int mca_ptl_base_open(void)
|
||||
iterate over it (even if it's empty, as in the case of
|
||||
laminfo) */
|
||||
|
||||
lam_list_construct(&mca_ptl_base_modules_initialized);
|
||||
OBJ_CONSTRUCT(&mca_ptl_base_modules_initialized, lam_list_t);
|
||||
|
||||
/* All done */
|
||||
|
||||
|
@ -17,7 +17,6 @@ extern lam_class_info_t mca_ptl_base_recv_frag_t_class_info;
|
||||
struct mca_ptl_base_recv_frag_t {
|
||||
mca_ptl_base_frag_t super;
|
||||
mca_ptl_base_recv_request_t *frag_request; /* matched posted receive */
|
||||
struct mca_ptl_base_peer_t* frag_peer; /* peer received from */
|
||||
};
|
||||
typedef struct mca_ptl_base_recv_frag_t mca_ptl_base_recv_frag_t;
|
||||
|
||||
|
@ -76,7 +76,7 @@ int mca_ptl_base_select(bool *allow_multi_user_threads,
|
||||
if (NULL == sm) {
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
}
|
||||
lam_list_item_construct((lam_list_item_t *) sm);
|
||||
OBJ_CONSTRUCT(sm, lam_list_item_t);
|
||||
sm->pbsm_module = module;
|
||||
sm->pbsm_actions = actions[i];
|
||||
lam_list_append(&mca_ptl_base_modules_initialized,
|
||||
|
@ -2,6 +2,7 @@
|
||||
* $HEADER$
|
||||
*/
|
||||
#include "mca/mpi/ptl/base/ptl_base_sendreq.h"
|
||||
#include "mca/mpi/ptl/base/ptl_base_sendfrag.h"
|
||||
|
||||
static void mca_ptl_base_send_request_construct(mca_ptl_base_send_request_t* req);
|
||||
static void mca_ptl_base_send_request_destruct(mca_ptl_base_send_request_t* req);
|
||||
@ -27,3 +28,10 @@ static void mca_ptl_base_send_request_destruct(mca_ptl_base_send_request_t* req)
|
||||
OBJ_DESTRUCT_SUPER(&req->req_unacked_frags, mca_pml_base_request_t);
|
||||
}
|
||||
|
||||
void mca_ptl_base_send_request_progress(
|
||||
mca_ptl_base_send_request_t* req,
|
||||
mca_ptl_base_send_frag_t* frag)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
|
||||
extern lam_class_info_t mca_ptl_base_send_request_t_class_info;
|
||||
struct mca_ptl_base_send_frag_t;
|
||||
|
||||
|
||||
struct mca_ptl_base_send_request_t {
|
||||
@ -47,6 +48,12 @@ struct mca_ptl_base_send_request_t {
|
||||
typedef struct mca_ptl_base_send_request_t mca_ptl_base_send_request_t;
|
||||
|
||||
|
||||
void mca_ptl_base_send_request_progress(
|
||||
mca_ptl_base_send_request_t* request,
|
||||
struct mca_ptl_base_send_frag_t* frag
|
||||
);
|
||||
|
||||
|
||||
static inline void mca_ptl_base_send_request_reinit(
|
||||
mca_ptl_base_send_request_t *request,
|
||||
void *addr,
|
||||
|
@ -1,8 +1,7 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
/** @file
|
||||
*
|
||||
/*
|
||||
* P2P Transport Layer (PTL)
|
||||
*/
|
||||
#ifndef MCA_PTL_H
|
||||
@ -22,8 +21,10 @@
|
||||
struct mca_ptl_t;
|
||||
struct mca_ptl_base_peer_t;
|
||||
struct mca_ptl_base_fragment_t;
|
||||
struct mca_ptl_base_recv_request_t;
|
||||
struct mca_ptl_base_send_request_t;
|
||||
struct mca_ptl_base_recv_frag_t;
|
||||
struct mca_ptl_base_send_frag_t;
|
||||
|
||||
typedef uint64_t mca_ptl_base_sequence_t;
|
||||
typedef uint64_t mca_ptl_base_tstamp_t;
|
||||
@ -139,11 +140,21 @@ typedef int (*mca_ptl_base_send_fn_t)(
|
||||
size_t size
|
||||
);
|
||||
|
||||
typedef int (*mca_ptl_base_recv_fn_t)(
|
||||
typedef void (*mca_ptl_base_recv_fn_t)(
|
||||
struct mca_ptl_t* ptl,
|
||||
struct mca_ptl_base_recv_frag_t* recv_frag
|
||||
);
|
||||
|
||||
typedef void (*mca_ptl_base_recv_progress_fn_t)(
|
||||
struct mca_ptl_base_recv_request_t* recv_request,
|
||||
struct mca_ptl_base_recv_frag_t* recv_frag
|
||||
);
|
||||
|
||||
typedef void (*mca_ptl_base_send_progress_fn_t)(
|
||||
struct mca_ptl_base_send_request_t* send_request,
|
||||
struct mca_ptl_base_send_frag_t* send_frag
|
||||
);
|
||||
|
||||
/**
|
||||
* PTL instance interface functions and common state.
|
||||
*/
|
||||
@ -159,7 +170,7 @@ struct mca_ptl_t {
|
||||
uint32_t ptl_latency; /**< relative ranking of latency used to prioritize ptls */
|
||||
uint32_t ptl_bandwidth; /**< bandwidth (Mbytes/sec) supported by each endpoint */
|
||||
|
||||
/* PTL function table */
|
||||
/* PML->PTL function table */
|
||||
mca_ptl_base_add_proc_fn_t ptl_add_proc;
|
||||
mca_ptl_base_del_proc_fn_t ptl_del_proc;
|
||||
mca_ptl_base_finalize_fn_t ptl_finalize;
|
||||
@ -168,6 +179,10 @@ struct mca_ptl_t {
|
||||
mca_ptl_base_request_alloc_fn_t ptl_request_alloc;
|
||||
mca_ptl_base_request_return_fn_t ptl_request_return;
|
||||
mca_ptl_base_frag_return_fn_t ptl_frag_return;
|
||||
|
||||
/* PTL->PML function table - filled in by PML at init */
|
||||
mca_ptl_base_send_progress_fn_t ptl_send_progress;
|
||||
mca_ptl_base_recv_progress_fn_t ptl_recv_progress;
|
||||
};
|
||||
typedef struct mca_ptl_t mca_ptl_t;
|
||||
|
||||
|
@ -76,7 +76,7 @@ int mca_ptl_tcp_add_proc(struct mca_ptl_t* ptl, struct lam_proc_t *lam_proc, str
|
||||
/* The ptl_proc datastructure is shared by all TCP PTL instances that are trying
|
||||
* to reach this destination. Cache the peer instance on the ptl_proc.
|
||||
*/
|
||||
ptl_peer = OBJ_NEW(mca_ptl_base_peer_t);
|
||||
ptl_peer = OBJ_NEW(mca_ptl_tcp_peer_t);
|
||||
if(NULL == ptl_peer) {
|
||||
THREAD_UNLOCK(&ptl_proc->proc_lock);
|
||||
return LAM_ERR_OUT_OF_RESOURCE;
|
||||
@ -150,10 +150,12 @@ int mca_ptl_tcp_send(
|
||||
}
|
||||
|
||||
|
||||
int mca_ptl_tcp_recv(
|
||||
void mca_ptl_tcp_recv(
|
||||
struct mca_ptl_t* ptl,
|
||||
struct mca_ptl_base_recv_frag_t* frag)
|
||||
{
|
||||
return LAM_ERROR;
|
||||
if(mca_ptl_tcp_recv_frag_cts((mca_ptl_tcp_recv_frag_t*)frag) == false) {
|
||||
lam_list_append(&mca_ptl_tcp_module.tcp_acks, (lam_list_item_t*)frag);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,6 +36,7 @@ struct mca_ptl_tcp_module_1_0_0_t {
|
||||
lam_free_list_t tcp_send_frags;
|
||||
lam_free_list_t tcp_recv_frags;
|
||||
lam_list_t tcp_procs;
|
||||
lam_list_t tcp_acks;
|
||||
struct mca_ptl_tcp_proc_t* tcp_local;
|
||||
lam_mutex_t tcp_lock;
|
||||
};
|
||||
@ -116,7 +117,7 @@ extern int mca_ptl_tcp_send(
|
||||
size_t size
|
||||
);
|
||||
|
||||
extern int mca_ptl_tcp_recv(
|
||||
extern void mca_ptl_tcp_recv(
|
||||
struct mca_ptl_t* ptl,
|
||||
struct mca_ptl_base_recv_frag_t* frag
|
||||
);
|
||||
|
@ -104,6 +104,7 @@ int mca_ptl_tcp_module_open(void)
|
||||
lam_mutex_construct(&mca_ptl_tcp_module.tcp_lock);
|
||||
OBJ_CONSTRUCT(&mca_ptl_tcp_module.tcp_reactor, lam_reactor_t);
|
||||
OBJ_CONSTRUCT(&mca_ptl_tcp_module.tcp_procs, lam_list_t);
|
||||
OBJ_CONSTRUCT(&mca_ptl_tcp_module.tcp_acks, lam_list_t);
|
||||
OBJ_CONSTRUCT(&mca_ptl_tcp_module.tcp_send_requests, lam_free_list_t);
|
||||
OBJ_CONSTRUCT(&mca_ptl_tcp_module.tcp_send_frags, lam_free_list_t);
|
||||
OBJ_CONSTRUCT(&mca_ptl_tcp_module.tcp_recv_frags, lam_free_list_t);
|
||||
@ -139,6 +140,7 @@ int mca_ptl_tcp_module_close(void)
|
||||
|
||||
OBJ_DESTRUCT(&mca_ptl_tcp_module.tcp_reactor);
|
||||
OBJ_DESTRUCT(&mca_ptl_tcp_module.tcp_procs);
|
||||
OBJ_DESTRUCT(&mca_ptl_tcp_module.tcp_acks);
|
||||
OBJ_DESTRUCT(&mca_ptl_tcp_module.tcp_send_requests);
|
||||
OBJ_DESTRUCT(&mca_ptl_tcp_module.tcp_send_frags);
|
||||
OBJ_DESTRUCT(&mca_ptl_tcp_module.tcp_recv_frags);
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "ptl_tcp_proc.h"
|
||||
|
||||
|
||||
static void mca_ptl_tcp_peer_init(mca_ptl_base_peer_t* ptl_peer);
|
||||
static void mca_ptl_tcp_peer_construct(mca_ptl_base_peer_t* ptl_peer);
|
||||
static void mca_ptl_tcp_peer_destruct(mca_ptl_base_peer_t* ptl_peer);
|
||||
static int mca_ptl_tcp_peer_start_connect(mca_ptl_base_peer_t*);
|
||||
static void mca_ptl_tcp_peer_close_i(mca_ptl_base_peer_t*);
|
||||
@ -25,7 +25,7 @@ static void mca_ptl_tcp_peer_except_handler(mca_ptl_base_peer_t*, int sd);
|
||||
|
||||
lam_class_info_t mca_ptl_tcp_peer_t_class_info = {
|
||||
"mca_tcp_ptl_peer_t",
|
||||
CLASS_INFO(lam_list_t),
|
||||
CLASS_INFO(lam_list_item_t),
|
||||
(lam_construct_t)mca_ptl_tcp_peer_construct,
|
||||
(lam_destruct_t)mca_ptl_tcp_peer_destruct
|
||||
};
|
||||
@ -42,9 +42,9 @@ static lam_reactor_listener_t mca_ptl_tcp_peer_listener = {
|
||||
* Initialize state of the peer instance.
|
||||
*/
|
||||
|
||||
void mca_ptl_tcp_peer_construct(mca_ptl_base_peer_t* ptl_peer)
|
||||
static void mca_ptl_tcp_peer_construct(mca_ptl_base_peer_t* ptl_peer)
|
||||
{
|
||||
OBJ_CONSTRUCT_SUPER(ptl_peer, lam_list_t);
|
||||
OBJ_CONSTRUCT_SUPER(ptl_peer, lam_list_item_t);
|
||||
ptl_peer->peer_ptl = 0;
|
||||
ptl_peer->peer_proc = 0;
|
||||
ptl_peer->peer_addr = 0;
|
||||
@ -62,11 +62,11 @@ void mca_ptl_tcp_peer_construct(mca_ptl_base_peer_t* ptl_peer)
|
||||
* Cleanup any resources held by the peer.
|
||||
*/
|
||||
|
||||
void mca_ptl_tcp_peer_destruct(mca_ptl_base_peer_t* ptl_peer)
|
||||
static void mca_ptl_tcp_peer_destruct(mca_ptl_base_peer_t* ptl_peer)
|
||||
{
|
||||
mca_ptl_tcp_proc_remove(ptl_peer->peer_proc, ptl_peer);
|
||||
mca_ptl_tcp_peer_close_i(ptl_peer);
|
||||
OBJ_DESTRUCT_SUPER(ptl_peer, lam_list_t);
|
||||
OBJ_DESTRUCT_SUPER(ptl_peer, lam_list_item_t);
|
||||
}
|
||||
|
||||
|
||||
@ -384,7 +384,7 @@ static void mca_ptl_tcp_peer_complete_connect(mca_ptl_base_peer_t* ptl_peer)
|
||||
int so_error = 0;
|
||||
lam_socklen_t so_length = sizeof(so_error);
|
||||
|
||||
/* unregister for event notifications */
|
||||
/* unregister from receiving event notifications */
|
||||
lam_reactor_remove(&mca_ptl_tcp_module.tcp_reactor, ptl_peer->peer_sd, LAM_REACTOR_NOTIFY_ALL);
|
||||
|
||||
/* check connect completion status */
|
||||
@ -441,7 +441,7 @@ static void mca_ptl_tcp_peer_recv_handler(mca_ptl_base_peer_t* ptl_peer, int sd)
|
||||
mca_ptl_tcp_recv_frag_t* recv_frag = ptl_peer->peer_recv_frag;
|
||||
if(NULL == recv_frag) {
|
||||
int rc;
|
||||
recv_frag = (mca_ptl_tcp_recv_frag_t*)lam_free_list_get(&mca_ptl_tcp_module.tcp_recv_frags, &rc);
|
||||
recv_frag = mca_ptl_tcp_recv_frag_alloc(&rc);
|
||||
if(recv_frag == 0) {
|
||||
THREAD_UNLOCK(&ptl_peer->peer_lock);
|
||||
return;
|
||||
|
@ -26,7 +26,6 @@ typedef enum {
|
||||
} mca_ptl_tcp_state_t;
|
||||
|
||||
|
||||
extern lam_class_info_t mca_ptl_tcp_peer_t_class_info;
|
||||
|
||||
/**
|
||||
* An abstraction that represents a connection to a peer process.
|
||||
@ -50,6 +49,8 @@ struct mca_ptl_base_peer_t {
|
||||
};
|
||||
typedef struct mca_ptl_base_peer_t mca_ptl_base_peer_t;
|
||||
|
||||
extern lam_class_info_t mca_ptl_tcp_peer_t_class_info;
|
||||
typedef struct mca_ptl_base_peer_t mca_ptl_tcp_peer_t;
|
||||
|
||||
void mca_ptl_tcp_peer_close(mca_ptl_base_peer_t*);
|
||||
int mca_ptl_tcp_peer_send(mca_ptl_base_peer_t*, mca_ptl_tcp_send_frag_t*);
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/errno.h>
|
||||
#include "mca/mpi/ptl/base/ptl_base_sendreq.h"
|
||||
#include "ptl_tcp.h"
|
||||
#include "ptl_tcp_peer.h"
|
||||
#include "ptl_tcp_recvfrag.h"
|
||||
@ -107,9 +108,13 @@ static bool mca_ptl_tcp_recv_frag_header(mca_ptl_tcp_recv_frag_t* frag, int sd,
|
||||
|
||||
static bool mca_ptl_tcp_recv_frag_ack(mca_ptl_tcp_recv_frag_t* frag, int sd)
|
||||
{
|
||||
mca_ptl_tcp_send_frag_t* sendfrag;
|
||||
if (frag->frag_hdr_cnt < sizeof(mca_ptl_base_ack_header_t))
|
||||
if (mca_ptl_tcp_recv_frag_header(frag, sd, sizeof(mca_ptl_base_ack_header_t)) == false)
|
||||
return false;
|
||||
sendfrag = (mca_ptl_tcp_send_frag_t*)frag->frag_header.hdr_ack.hdr_src_ptr.pval;
|
||||
mca_ptl_base_send_request_progress(sendfrag->super.frag_request, &sendfrag->super);
|
||||
/* don't return first fragment - it is returned along with the request */
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -144,10 +149,9 @@ static bool mca_ptl_tcp_recv_frag_match(mca_ptl_tcp_recv_frag_t* frag, int sd)
|
||||
if(mca_ptl_tcp_recv_frag_discard(frag, sd) == false)
|
||||
return false;
|
||||
|
||||
if(NULL != frag->super.frag_request) {
|
||||
/* indicate completion status */
|
||||
mca_ptl_base_recv_request_progress(frag->super.frag_request, &frag->super);
|
||||
}
|
||||
/* if match has already been made process the fragment */
|
||||
if(NULL != frag->super.frag_request)
|
||||
mca_ptl_tcp_recv_frag_process(frag);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -244,3 +248,58 @@ static bool mca_ptl_tcp_recv_frag_discard(mca_ptl_tcp_recv_frag_t* frag, int sd)
|
||||
frag->frag_msg_cnt += cnt;
|
||||
return (frag->frag_msg_cnt >= frag->frag_header.hdr_frag.hdr_frag_length);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Queue up an acknowledgment to the peer.
|
||||
*/
|
||||
|
||||
bool mca_ptl_tcp_recv_frag_cts(mca_ptl_tcp_recv_frag_t* frag)
|
||||
{
|
||||
int rc;
|
||||
mca_ptl_tcp_send_frag_t* ack = mca_ptl_tcp_send_frag_alloc(&rc);
|
||||
mca_ptl_base_peer_t* ptl_peer = frag->frag_peer;
|
||||
mca_ptl_base_header_t* hdr;
|
||||
if (NULL == ack)
|
||||
return false;
|
||||
|
||||
hdr = &ack->frag_header;
|
||||
hdr->hdr_type = MCA_PTL_HDR_TYPE_ACK;
|
||||
hdr->hdr_flags = 0;
|
||||
hdr->hdr_size = sizeof(mca_ptl_base_ack_header_t);
|
||||
hdr->hdr_ack.hdr_src_ptr = frag->frag_header.hdr_frag.hdr_src_ptr;
|
||||
hdr->hdr_ack.hdr_dst_ptr.pval = frag->super.frag_request;
|
||||
ack->frag_owner = &ptl_peer->peer_ptl->super;
|
||||
ack->frag_peer = ptl_peer;
|
||||
ack->super.frag_request = 0;
|
||||
ack->super.super.frag_addr = 0;
|
||||
ack->super.super.frag_size = 0;
|
||||
ack->frag_vec_ptr = ack->frag_vec;
|
||||
ack->frag_vec[0].iov_base = (lam_iov_base_ptr_t)hdr;
|
||||
ack->frag_vec[0].iov_len = sizeof(mca_ptl_base_ack_header_t);
|
||||
ack->frag_vec_cnt = 1;
|
||||
frag->frag_acked = (mca_ptl_tcp_peer_send(ptl_peer, ack) == LAM_SUCCESS);
|
||||
return frag->frag_acked;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Copy data into application buffer if required and update
|
||||
* status of the request.
|
||||
*/
|
||||
|
||||
void mca_ptl_tcp_recv_frag_process(mca_ptl_tcp_recv_frag_t* frag)
|
||||
{
|
||||
/* are we done receiving data */
|
||||
if(frag->frag_msg_cnt >= frag->frag_header.hdr_frag.hdr_frag_length) {
|
||||
/* was a temporary buffer allocated */
|
||||
if(frag->frag_addr != frag->super.super.frag_addr) {
|
||||
memcpy(frag->super.super.frag_addr, frag->frag_addr, frag->super.super.frag_size);
|
||||
}
|
||||
mca_ptl_base_recv_request_progress(frag->super.frag_request, &frag->super);
|
||||
if(frag->frag_acked == true) {
|
||||
mca_ptl_tcp_recv_frag_return(frag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <netinet/in.h>
|
||||
#include "mca/mpi/ptl/ptl.h"
|
||||
#include "mca/mpi/ptl/base/ptl_base_recvfrag.h"
|
||||
#include "ptl_tcp.h"
|
||||
|
||||
|
||||
extern lam_class_info_t mca_ptl_tcp_recv_frag_t_class_info;
|
||||
@ -18,10 +19,12 @@ extern lam_class_info_t mca_ptl_tcp_recv_frag_t_class_info;
|
||||
|
||||
struct mca_ptl_tcp_recv_frag_t {
|
||||
mca_ptl_base_recv_frag_t super;
|
||||
mca_ptl_base_ack_header_t frag_ack;
|
||||
unsigned char* frag_addr;
|
||||
size_t frag_size;
|
||||
size_t frag_hdr_cnt;
|
||||
size_t frag_msg_cnt;
|
||||
bool frag_acked;
|
||||
#define frag_peer super.super.frag_peer
|
||||
#define frag_owner super.super.frag_owner
|
||||
#define frag_header super.super.frag_header
|
||||
@ -29,8 +32,22 @@ struct mca_ptl_tcp_recv_frag_t {
|
||||
typedef struct mca_ptl_tcp_recv_frag_t mca_ptl_tcp_recv_frag_t;
|
||||
|
||||
|
||||
static inline mca_ptl_tcp_recv_frag_t* mca_ptl_tcp_recv_frag_alloc(int* rc)
|
||||
{
|
||||
return (mca_ptl_tcp_recv_frag_t*)lam_free_list_get(&mca_ptl_tcp_module.tcp_recv_frags, rc);
|
||||
}
|
||||
|
||||
static inline void mca_ptl_tcp_recv_frag_return(mca_ptl_tcp_recv_frag_t* frag)
|
||||
{
|
||||
if(frag->frag_addr != frag->super.super.frag_addr)
|
||||
free(frag->frag_addr);
|
||||
lam_free_list_return(&mca_ptl_tcp_module.tcp_recv_frags, (lam_list_item_t*)frag);
|
||||
}
|
||||
|
||||
bool mca_ptl_tcp_recv_frag_handler(mca_ptl_tcp_recv_frag_t*, int sd);
|
||||
void mca_ptl_tcp_recv_frag_reinit(mca_ptl_tcp_recv_frag_t* frag, struct mca_ptl_base_peer_t* peer);
|
||||
bool mca_ptl_tcp_recv_frag_cts(mca_ptl_tcp_recv_frag_t* frag);
|
||||
void mca_ptl_tcp_recv_frag_process(mca_ptl_tcp_recv_frag_t* frag);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -11,6 +11,10 @@
|
||||
#include "ptl_tcp_sendfrag.h"
|
||||
|
||||
|
||||
static void mca_ptl_tcp_send_frag_construct(mca_ptl_tcp_send_frag_t* frag);
|
||||
static void mca_ptl_tcp_send_frag_destruct(mca_ptl_tcp_send_frag_t* frag);
|
||||
|
||||
|
||||
lam_class_info_t mca_ptl_tcp_send_frag_t_class_info = {
|
||||
"mca_ptl_tcp_send_frag_t",
|
||||
CLASS_INFO(mca_ptl_base_send_frag_t),
|
||||
@ -19,17 +23,18 @@ lam_class_info_t mca_ptl_tcp_send_frag_t_class_info = {
|
||||
};
|
||||
|
||||
|
||||
void mca_ptl_tcp_send_frag_construct(mca_ptl_tcp_send_frag_t* frag)
|
||||
static void mca_ptl_tcp_send_frag_construct(mca_ptl_tcp_send_frag_t* frag)
|
||||
{
|
||||
OBJ_CONSTRUCT_SUPER(frag, mca_ptl_base_send_frag_t);
|
||||
}
|
||||
|
||||
|
||||
void mca_ptl_tcp_send_frag_destruct(mca_ptl_tcp_send_frag_t* frag)
|
||||
static void mca_ptl_tcp_send_frag_destruct(mca_ptl_tcp_send_frag_t* frag)
|
||||
{
|
||||
OBJ_DESTRUCT_SUPER(frag, mca_ptl_base_send_frag_t);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize the fragment based on the current offset into the users
|
||||
* data buffer, and the indicated size.
|
||||
@ -114,7 +119,7 @@ bool mca_ptl_tcp_send_frag_handler(mca_ptl_tcp_send_frag_t* frag, int sd)
|
||||
return false;
|
||||
default:
|
||||
{
|
||||
lam_output(0, "mca_ptl_tcp_send_frag_handler: writev failedd with errno=%d", errno);
|
||||
lam_output(0, "mca_ptl_tcp_send_frag_handler: writev failed with errno=%d", errno);
|
||||
mca_ptl_tcp_peer_close(frag->frag_peer);
|
||||
return false;
|
||||
}
|
||||
@ -136,6 +141,8 @@ bool mca_ptl_tcp_send_frag_handler(mca_ptl_tcp_send_frag_t* frag, int sd)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* done with this frag? */
|
||||
return (frag->frag_vec_cnt == 0);
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <netinet/in.h>
|
||||
#include "lam_config.h"
|
||||
#include "mca/mpi/ptl/base/ptl_base_sendfrag.h"
|
||||
|
||||
#include "ptl_tcp.h"
|
||||
|
||||
extern lam_class_info_t mca_ptl_tcp_send_frag_t_class_info;
|
||||
|
||||
@ -28,10 +28,19 @@ struct mca_ptl_tcp_send_frag_t {
|
||||
typedef struct mca_ptl_tcp_send_frag_t mca_ptl_tcp_send_frag_t;
|
||||
|
||||
|
||||
void mca_ptl_tcp_send_frag_construct(mca_ptl_tcp_send_frag_t*);
|
||||
void mca_ptl_tcp_send_frag_destruct(mca_ptl_tcp_send_frag_t*);
|
||||
bool mca_ptl_tcp_send_frag_handler(mca_ptl_tcp_send_frag_t*, int sd);
|
||||
static inline mca_ptl_tcp_send_frag_t* mca_ptl_tcp_send_frag_alloc(int* rc)
|
||||
{
|
||||
return (mca_ptl_tcp_send_frag_t*)lam_free_list_get(&mca_ptl_tcp_module.tcp_send_frags, rc);
|
||||
}
|
||||
|
||||
|
||||
static inline void mca_ptl_tcp_send_frag_return(mca_ptl_tcp_send_frag_t* frag)
|
||||
{
|
||||
lam_free_list_return(&mca_ptl_tcp_module.tcp_send_frags, (lam_list_item_t*)frag);
|
||||
}
|
||||
|
||||
|
||||
bool mca_ptl_tcp_send_frag_handler(mca_ptl_tcp_send_frag_t*, int sd);
|
||||
void mca_ptl_tcp_send_frag_reinit(
|
||||
mca_ptl_tcp_send_frag_t*,
|
||||
struct mca_ptl_base_peer_t*,
|
||||
|
@ -17,8 +17,8 @@ lam_class_info_t lam_proc_t_class_info = {
|
||||
void lam_proc_construct(lam_proc_t* proc)
|
||||
{
|
||||
static int init = 0;
|
||||
if(init++ == 0) {
|
||||
lam_list_construct(&lam_proc_list);
|
||||
if(fetchNset(&init,1) == 0) {
|
||||
OBJ_CONSTRUCT(&lam_proc_list, lam_list_t);
|
||||
lam_mutex_construct(&lam_proc_lock);
|
||||
}
|
||||
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user