1
1

cleanup for new object changes

This commit was SVN r681.
Этот коммит содержится в:
Tim Woodall 2004-02-10 16:53:41 +00:00
родитель c4c07e755d
Коммит 6453116b31
40 изменённых файлов: 780 добавлений и 572 удалений

Просмотреть файл

@ -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 Обычный файл
Просмотреть файл

@ -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 Обычный файл
Просмотреть файл

@ -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(&registry);
OBJ_CONSTRUCT(&registry, 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(&registry, (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);
}