Commit 680a0d91 authored by Philip Carns's avatar Philip Carns

convert mplex_id to provider_id revise technique

- mplex_id terminology no lonter in api, replaced by provider_id
- no longer uses target_id hook in Mercury API, but instead multiplexes
  into underlying hg_id_t
- adds provider_id argument to margo_forward

This is untested; examples and test programs have not been updated to
use it yet.
parent 72eec057
......@@ -23,6 +23,10 @@ extern "C" {
#include <mercury_macros.h>
#include <abt.h>
/* determine how much of the Mercury ID space to use for Margo provider IDs */
#define __MARGO_PROVIDER_ID_SIZE (sizeof(hg_id_t)/4)
#define __MARGO_RPC_HASH_SIZE (__MARGO_PROVIDER_ID_SIZE * 3)
#undef MERCURY_REGISTER
struct margo_instance;
......@@ -34,7 +38,8 @@ typedef ABT_eventual margo_request;
#define MARGO_REQUEST_NULL ABT_EVENTUAL_NULL
#define MARGO_CLIENT_MODE 0
#define MARGO_SERVER_MODE 1
#define MARGO_DEFAULT_MPLEX_ID 0
#define MARGO_DEFAULT_PROVIDER_ID 0
#define MARGO_MAX_PROVIDER_ID (1 << __MARGO_PROVIDER_ID_SIZE)
#define MARGO_PARAM_PROGRESS_TIMEOUT_UB 1
......@@ -167,25 +172,25 @@ hg_id_t margo_register_name(
hg_rpc_cb_t rpc_cb);
/**
* Registers an RPC with margo that is associated with a multiplexed service
* Registers an RPC with margo that is associated with a provider instance
*
* \param [in] mid Margo instance
* \param [in] func_name unique function name for RPC
* \param [in] in_proc_cb pointer to input proc callback
* \param [in] out_proc_cb pointer to output proc callback
* \param [in] rpc_cb RPC callback
* \param [in] mplex_id multiplexing identifier
* \param [in] provider_id provider identifier
* \param [in] pool Argobots pool the handler will execute in
*
* \return unique ID associated to the registered function
*/
hg_id_t margo_register_name_mplex(
hg_id_t margo_register_name_provider(
margo_instance_id mid,
const char *func_name,
hg_proc_cb_t in_proc_cb,
hg_proc_cb_t out_proc_cb,
hg_rpc_cb_t rpc_cb,
uint8_t mplex_id,
uint16_t provider_id,
ABT_pool pool);
/*
......@@ -206,20 +211,20 @@ hg_return_t margo_registered_name(
hg_bool_t *flag);
/**
* Indicate whether the given RPC name has been registered with the given multiplex id.
* Indicate whether the given RPC name has been registered with the given provider id.
*
* @param [in] mid Margo instance
* @param [in] func_name function name
* @param [in] mplex_id multiplex id
* @param [in] provider_id provider id
* @param [out] id registered RPC ID
* @param [out] flag pointer to boolean
*
* @return HG_SUCCESS or corresponding HG error code
*/
hg_return_t margo_registered_name_mplex(
hg_return_t margo_registered_name_provider(
margo_instance_id mid,
const char *func_name,
uint8_t mplex_id,
uint16_t provider_id,
hg_id_t *id,
hg_bool_t *flag);
......@@ -256,39 +261,39 @@ void* margo_registered_data(
/**
* Register and associate user data to registered function for
* a given multiplex id.
* a given provider id.
* When HG_Finalize() is called free_callback (if defined) is called
* to free the registered data.
*
* \param [in] mid Margo instance
* \param [in] id registered function ID
* \param [in] mplex_id Margo multiplex ID
* \param [in] provider_id Margo provider ID
* \param [in] data pointer to data
* \param [in] free_callback pointer to free function
*
* \return HG_SUCCESS or corresponding HG error code
*/
int margo_register_data_mplex(
int margo_register_data_provider(
margo_instance_id mid,
hg_id_t id,
uint8_t mplex_id,
uint16_t provider_id,
void* data,
void (*free_callback)(void *));
/**
* Indicate whether margo_register_data_mplex() has been called
* Indicate whether margo_register_data_provider() has been called
* and return associated data.
*
* \param [in] mid Margo instance
* \param [in] id registered function ID
* \param [in] mplex_id Margo multiplex ID
* \param [in] provider_id Margo provider ID
*
* \return Pointer to data or NULL
*/
void* margo_registered_data_mplex(
void* margo_registered_data_provider(
margo_instance_id mid,
hg_id_t id,
uint8_t mplex_id);
uint16_t provider_id);
/**
* Disable response for a given RPC ID.
......@@ -463,34 +468,28 @@ hg_return_t margo_destroy(
*/
#define margo_free_output HG_Free_output
/**
* Set target ID that will receive and process RPC request.
*
* \param [in] handle Mercury handle
* \param [in] target_id user-defined target ID
*
* \return HG_SUCCESS or corresponding HG error code
*/
#define margo_set_target_id HG_Set_target_id
/**
* Forward an RPC request to a remote host
* @param [in] provider ID (may be MARGO_DEFAULT_PROVIDER_ID)
* @param [in] handle identifier for the RPC to be sent
* @param [in] in_struct input argument struct for RPC
* @returns 0 on success, hg_return_t values on error
*/
hg_return_t margo_forward(
uint16_t provider_id,
hg_handle_t handle,
void *in_struct);
/**
* Forward (without blocking) an RPC request to a remote host
* @param [in] provider ID (may be MARGO_DEFAULT_PROVIDER_ID)
* @param [in] handle identifier for the RPC to be sent
* @param [in] in_struct input argument struct for RPC
* @param [out] req request to wait on using margo_wait
* @returns 0 on success, hg_return_t values on error
*/
hg_return_t margo_iforward(
uint16_t provider_id,
hg_handle_t handle,
void* in_struct,
margo_request* req);
......@@ -772,24 +771,6 @@ hg_class_t* margo_get_class(margo_instance_id mid);
*/
margo_instance_id margo_hg_handle_get_instance(hg_handle_t h);
/**
* Get the margo_instance_id from a received RPC handle.
*
* \param [in] info RPC info structure pointer
*
* \return Margo instance
*/
margo_instance_id margo_hg_info_get_instance(const struct hg_info *info);
/**
* Maps an RPC id and mplex id to the pool that it should execute on
* @param [in] mid Margo instance
* @param [in] id Mercury RPC identifier
* @param [in] mplex_id multiplexing identifier
* @param [out] pool Argobots pool the handler will execute in
*/
int margo_lookup_mplex(margo_instance_id mid, hg_id_t id, uint8_t mplex_id, ABT_pool *pool);
/**
* Enables diagnostic collection on specified Margo instance
*
......@@ -835,17 +816,18 @@ void margo_get_param(margo_instance_id mid, int option, void *param);
* macro that registers a function as an RPC.
*/
#define MARGO_REGISTER(__mid, __func_name, __in_t, __out_t, __handler) \
margo_register_name(__mid, __func_name, \
margo_register_name_provider(__mid, __func_name, \
BOOST_PP_CAT(hg_proc_, __in_t), \
BOOST_PP_CAT(hg_proc_, __out_t), \
__handler##_handler);
__handler##_handler, \
MARGO_DEFAULT_PROVIDER_ID, ABT_POOL_NULL);
#define MARGO_REGISTER_MPLEX(__mid, __func_name, __in_t, __out_t, __handler, __mplex_id, __pool) \
margo_register_name_mplex(__mid, __func_name, \
#define MARGO_REGISTER_PROVIDER(__mid, __func_name, __in_t, __out_t, __handler, __provider_id, __pool) \
margo_register_name_provider(__mid, __func_name, \
BOOST_PP_CAT(hg_proc_, __in_t), \
BOOST_PP_CAT(hg_proc_, __out_t), \
__handler##_handler, \
__mplex_id, __pool);
__provider_id, __pool);
#define NULL_handler NULL
......@@ -858,18 +840,9 @@ hg_return_t __name##_handler(hg_handle_t handle) { \
int __ret; \
ABT_pool __pool; \
margo_instance_id __mid; \
const struct hg_info *__hgi; \
__hgi = HG_Get_info(handle); \
__mid = margo_hg_handle_get_instance(handle); \
if(__mid == MARGO_INSTANCE_NULL) { \
return(HG_OTHER_ERROR); \
} \
__ret = margo_lookup_mplex(__mid, __hgi->id, __hgi->target_id, (&__pool)); \
if(__ret != 0) { \
return(HG_INVALID_PARAM); \
}\
if(__pool == ABT_POOL_NULL) \
margo_get_handler_pool(__mid, &__pool); \
__mid = margo_hg_handle_get_instance(handle); \
if(__mid == MARGO_INSTANCE_NULL) { return(HG_OTHER_ERROR); } \
__pool = margo_hg_handle_get_handler_pool(handle); \
__ret = ABT_thread_create(__pool, (void (*)(void *))__name, handle, ABT_THREAD_ATTR_NULL, NULL); \
if(__ret != 0) { \
return(HG_NOMEM_ERROR); \
......
......@@ -26,15 +26,9 @@
#define DEFAULT_MERCURY_PROGRESS_TIMEOUT_UB 100 /* 100 milliseconds */
#define DEFAULT_MERCURY_HANDLE_CACHE_SIZE 32
struct mplex_key
struct provider_element
{
hg_id_t id;
uint8_t mplex_id;
};
struct mplex_element
{
struct mplex_key key;
ABT_pool pool;
void* user_data;
void(*user_free_callback)(void*);
......@@ -106,8 +100,8 @@ struct margo_instance
/* timer data */
struct margo_timer_list* timer_list;
/* hash table to track multiplexed rpcs registered with margo */
struct mplex_element *mplex_table;
/* hash table to track provider IDs registered with margo */
struct provider_element *provider_table;
/* linked list of free hg handles and a hash of in-use handles */
struct margo_handle_cache_el *free_handle_list;
......@@ -141,14 +135,52 @@ static void margo_rpc_data_free(void* ptr);
static void remote_shutdown_ult(hg_handle_t handle);
DECLARE_MARGO_RPC_HANDLER(remote_shutdown_ult);
static inline void demux_id(hg_id_t in, hg_id_t* base_id, uint16_t *provider_id)
{
/* retrieve low bits for provider */
*provider_id = 0;
*provider_id += (in & (((1<<(__MARGO_PROVIDER_ID_SIZE*8))-1)));
/* clear low order bits */
*base_id = (in >> (__MARGO_PROVIDER_ID_SIZE*8)) <<
(__MARGO_PROVIDER_ID_SIZE*8);
return;
}
static inline hg_id_t mux_id(hg_id_t base_id, uint16_t provider_id)
{
hg_id_t id;
id = (base_id >> (__MARGO_PROVIDER_ID_SIZE*8)) <<
(__MARGO_PROVIDER_ID_SIZE*8);
id |= provider_id;
return id;
}
static inline hg_id_t gen_id(const char* func_name, uint16_t provider_id)
{
hg_id_t id;
unsigned hashval;
HASH_JEN(func_name, strlen(func_name), hashval);
id = hashval << (__MARGO_PROVIDER_ID_SIZE*8);
id |= provider_id;
return id;
}
static hg_return_t margo_handle_cache_init(margo_instance_id mid);
static void margo_handle_cache_destroy(margo_instance_id mid);
static hg_return_t margo_handle_cache_get(margo_instance_id mid,
hg_addr_t addr, hg_id_t id, hg_handle_t *handle);
static hg_return_t margo_handle_cache_put(margo_instance_id mid,
hg_handle_t handle);
static void delete_multiplexing_hash(margo_instance_id mid);
static void delete_provider_hash(margo_instance_id mid);
static int margo_lookup_provider(margo_instance_id mid, hg_id_t id, uint16_t provider_id, ABT_pool *pool);
static hg_id_t margo_register_internal(margo_instance_id mid, const char *func_name,
hg_proc_cb_t in_proc_cb, hg_proc_cb_t out_proc_cb, hg_rpc_cb_t rpc_cb, uint16_t provider_id);
margo_instance_id margo_init(const char *addr_str, int mode,
int use_progress_thread, int rpc_thread_count)
......@@ -311,7 +343,7 @@ margo_instance_id margo_init_pool(ABT_pool progress_pool, ABT_pool handler_pool,
mid->hg_class = HG_Context_get_class(hg_context);
mid->hg_context = hg_context;
mid->hg_progress_timeout_ub = DEFAULT_MERCURY_PROGRESS_TIMEOUT_UB;
mid->mplex_table = NULL;
mid->provider_table = NULL;
mid->refcount = 1;
mid->finalize_cb = NULL;
mid->enable_remote_shutdown = 0;
......@@ -359,8 +391,8 @@ static void margo_cleanup(margo_instance_id mid)
margo_timer_list_free(mid->timer_list);
/* delete the hash used for multiplexing */
delete_multiplexing_hash(mid);
/* delete the hash used for provider IDs */
delete_provider_hash(mid);
ABT_mutex_free(&mid->finalize_mutex);
ABT_cond_free(&mid->finalize_cond);
......@@ -464,38 +496,6 @@ void margo_push_finalize_callback(
mid->finalize_cb = fcb;
}
hg_id_t margo_register_name(margo_instance_id mid, const char *func_name,
hg_proc_cb_t in_proc_cb, hg_proc_cb_t out_proc_cb, hg_rpc_cb_t rpc_cb)
{
struct margo_rpc_data* margo_data;
hg_return_t hret;
hg_id_t id;
id = HG_Register_name(mid->hg_class, func_name, in_proc_cb, out_proc_cb, rpc_cb);
if(id <= 0)
return(0);
/* register the margo data with the RPC */
margo_data = (struct margo_rpc_data*)HG_Registered_data(mid->hg_class, id);
if(!margo_data)
{
margo_data = (struct margo_rpc_data*)malloc(sizeof(struct margo_rpc_data));
if(!margo_data)
return(0);
margo_data->mid = mid;
margo_data->user_data = NULL;
margo_data->user_free_callback = NULL;
hret = HG_Register_data(mid->hg_class, id, margo_data, margo_rpc_data_free);
if(hret != HG_SUCCESS)
{
free(margo_data);
return(0);
}
}
return(id);
}
void margo_enable_remote_shutdown(margo_instance_id mid)
{
mid->enable_remote_shutdown = 1;
......@@ -512,7 +512,7 @@ int margo_shutdown_remote_instance(
mid->shutdown_rpc_id, &handle);
if(hret != HG_SUCCESS) return -1;
hret = margo_forward(handle, NULL);
hret = margo_forward(MARGO_DEFAULT_PROVIDER_ID, handle, NULL);
if(hret != HG_SUCCESS)
{
margo_destroy(handle);
......@@ -533,37 +533,32 @@ int margo_shutdown_remote_instance(
return out.ret;
}
hg_id_t margo_register_name_mplex(margo_instance_id mid, const char *func_name,
hg_id_t margo_register_name_provider(margo_instance_id mid, const char *func_name,
hg_proc_cb_t in_proc_cb, hg_proc_cb_t out_proc_cb, hg_rpc_cb_t rpc_cb,
uint8_t mplex_id, ABT_pool pool)
uint16_t provider_id, ABT_pool pool)
{
struct mplex_key key;
struct mplex_element *element;
struct provider_element *element;
hg_id_t id;
id = margo_register_name(mid, func_name, in_proc_cb, out_proc_cb, rpc_cb);
id = margo_register_internal(mid, func_name, in_proc_cb, out_proc_cb, rpc_cb, provider_id);
if(id <= 0)
return(0);
/* nothing to do, we'll let the handler pool take this directly */
if(mplex_id == MARGO_DEFAULT_MPLEX_ID)
if(provider_id == MARGO_DEFAULT_PROVIDER_ID)
return(id);
memset(&key, 0, sizeof(key));
key.id = id;
key.mplex_id = mplex_id;
HASH_FIND(hh, mid->mplex_table, &key, sizeof(key), element);
HASH_FIND(hh, mid->provider_table, &id, sizeof(id), element);
if(element)
return(id);
element = calloc(1,sizeof(*element));
if(!element)
return(0);
element->key = key;
element->id = id;
element->pool = pool;
HASH_ADD(hh, mid->mplex_table, key, sizeof(key), element);
HASH_ADD(hh, mid->provider_table, id, sizeof(id), element);
return(id);
}
......@@ -571,35 +566,35 @@ hg_id_t margo_register_name_mplex(margo_instance_id mid, const char *func_name,
hg_return_t margo_registered_name(margo_instance_id mid, const char *func_name,
hg_id_t *id, hg_bool_t *flag)
{
return(HG_Registered_name(mid->hg_class, func_name, id, flag));
*id = gen_id(func_name, 0);
return(HG_Registered(mid->hg_class, *id, flag));
}
hg_return_t margo_registered_name_mplex(margo_instance_id mid, const char *func_name,
uint8_t mplex_id, hg_id_t *id, hg_bool_t *flag)
hg_return_t margo_registered_name_provider(margo_instance_id mid, const char *func_name,
uint16_t provider_id, hg_id_t *id, hg_bool_t *flag)
{
hg_bool_t b;
hg_return_t ret = margo_registered_name(mid, func_name, id, &b);
hg_return_t ret;
*id = gen_id(func_name, provider_id);
ret = HG_Registered(mid->hg_class, *id, &b);
if(ret != HG_SUCCESS)
return ret;
if((!b) || (!mplex_id)) {
if((!b) || (!provider_id)) {
*flag = b;
return ret;
}
struct mplex_key key;
struct mplex_element *element;
struct provider_element *element;
memset(&key, 0, sizeof(key));
key.id = *id;
key.mplex_id = mplex_id;
HASH_FIND(hh, mid->mplex_table, &key, sizeof(key), element);
HASH_FIND(hh, mid->provider_table, id, sizeof(*id), element);
if(!element) {
*flag = 0;
return HG_SUCCESS;
}
assert(element->key.id == *id && element->key.mplex_id == mplex_id);
assert(element->id == *id);
*flag = 1;
return HG_SUCCESS;
......@@ -765,18 +760,20 @@ static hg_return_t margo_cb(const struct hg_cb_info *info)
}
hg_return_t margo_forward(
uint16_t provider_id,
hg_handle_t handle,
void *in_struct)
{
hg_return_t hret;
margo_request req;
hret = margo_iforward(handle, in_struct, &req);
hret = margo_iforward(provider_id, handle, in_struct, &req);
if(hret != HG_SUCCESS)
return hret;
return margo_wait(req);
}
hg_return_t margo_iforward(
uint16_t provider_id,
hg_handle_t handle,
void *in_struct,
margo_request* req)
......@@ -784,6 +781,40 @@ hg_return_t margo_iforward(
hg_return_t hret = HG_TIMEOUT;
ABT_eventual eventual;
int ret;
const struct hg_info* hgi;
hg_id_t id;
hg_proc_cb_t in_cb, out_cb;
hg_bool_t flag;
assert(provider_id <= MARGO_MAX_PROVIDER_ID);
hgi = HG_Get_info(handle);
/* make sure bottom bits of id are clear */
id = (hgi->id >> (__MARGO_PROVIDER_ID_SIZE*8)) <<
(__MARGO_PROVIDER_ID_SIZE*8);
id |= provider_id;
/* TODO: if we reset the handle here, is there any reason to do so in
* the handle cache?
*/
ret = HG_Reset(handle, hgi->addr, id);
if(ret == HG_NO_MATCH)
{
/* if Mercury does not recognize this ID (with provider id included)
* then register it now
*/
/* find encoders for base ID */
ret = HG_Registered_proc_cb(hgi->hg_class, hgi->id, &flag, &in_cb, &out_cb);
if(ret != HG_SUCCESS)
return(ret);
if(!flag)
return(HG_NO_MATCH);
/* register new ID that includes provider id */
ret = HG_Register(hgi->hg_class, id, in_cb, out_cb, NULL);
if(ret != HG_SUCCESS)
return(ret);
}
ret = ABT_eventual_create(sizeof(hret), &eventual);
if(ret != 0)
......@@ -1052,65 +1083,55 @@ hg_class_t* margo_get_class(margo_instance_id mid)
return(mid->hg_class);
}
margo_instance_id margo_hg_handle_get_instance(hg_handle_t h)
{
const struct hg_info* info = HG_Get_info(h);
if(!info) return MARGO_INSTANCE_NULL;
return margo_hg_info_get_instance(info);
}
margo_instance_id margo_hg_info_get_instance(const struct hg_info *info)
ABT_pool margo_hg_handle_get_handler_pool(hg_handle_t h)
{
struct margo_rpc_data* data =
(struct margo_rpc_data*) HG_Registered_data(info->hg_class, info->id);
if(!data) return MARGO_INSTANCE_NULL;
return data->mid;
}
struct margo_rpc_data* data;
const struct hg_info* info;
hg_id_t base_id;
uint16_t provider_id;
int ret;
ABT_pool pool;
info = HG_Get_info(h);
if(!info) return ABT_POOL_NULL;
int margo_lookup_mplex(margo_instance_id mid, hg_id_t id, uint8_t mplex_id, ABT_pool *pool)
{
struct mplex_key key;
struct mplex_element *element;
data = (struct margo_rpc_data*) HG_Registered_data(info->hg_class, info->id);
if(!data) return ABT_POOL_NULL;
if(!mplex_id)
{
*pool = mid->handler_pool;
return(0);
}
demux_id(info->id, &base_id, &provider_id);
memset(&key, 0, sizeof(key));
key.id = id;
key.mplex_id = mplex_id;
ret = margo_lookup_provider(data->mid, base_id, provider_id, &pool);
if(ret != 0) return ABT_POOL_NULL;
HASH_FIND(hh, mid->mplex_table, &key, sizeof(key), element);
if(!element) {
if(mplex_id == 0) // element does not exist and mplex is 0, return default handler
*pool = mid->handler_pool;
else // otherwise it is an error
return(-1);
}
return pool;
}
assert(element->key.id == id && element->key.mplex_id == mplex_id);
margo_instance_id margo_hg_handle_get_instance(hg_handle_t h)
{
struct margo_rpc_data* data;
const struct hg_info* info;
info = HG_Get_info(h);
if(!info) return MARGO_INSTANCE_NULL;
*pool = element->pool;
data = (struct margo_rpc_data*) HG_Registered_data(info->hg_class, info->id);
if(!data) return MARGO_INSTANCE_NULL;
return(0);
return data->mid;
}
int margo_register_data_mplex(margo_instance_id mid, hg_id_t id, uint8_t mplex_id, void* data, void (*free_callback)(void *))
int margo_register_data_provider(margo_instance_id mid, hg_id_t id, uint16_t provider_id, void* data, void (*free_callback)(void *))
{
struct mplex_key key;
struct mplex_element *element;
struct provider_element *element;
hg_id_t muxed_id;
memset(&key, 0, sizeof(key));
key.id = id;
key.mplex_id = mplex_id;
muxed_id = mux_id(id, provider_id);
HASH_FIND(hh, mid->mplex_table, &key, sizeof(key), element);
HASH_FIND(hh, mid->provider_table, &muxed_id, sizeof(muxed_id), element);
if(!element)
return -1;
assert(element->key.id == id && element->key.mplex_id == mplex_id);
assert(element->id == muxed_id);
if(element->user_data && element->user_free_callback)
(element->user_free_callback)(element->user_data);
......@@ -1121,20 +1142,18 @@ int margo_register_data_mplex(margo_instance_id mid, hg_id_t id, uint8_t mplex_i
return(0);
}
void* margo_registered_data_mplex(margo_instance_id mid, hg_id_t id, uint8_t mplex_id)
void* margo_registered_data_provider(margo_instance_id mid, hg_id_t id, uint16_t provider_id)
{
struct mplex_key key;
struct mplex_element *element;
struct provider_element *element;
hg_id_t muxed_id;
memset(&key, 0, sizeof(key));
key.id = id;
key.mplex_id = mplex_id;
muxed_id = mux_id(id, provider_id);
HASH_FIND(hh, mid->mplex_table, &key, sizeof(key), element);
HASH_FIND(hh, mid->provider_table, &muxed_id, sizeof(muxed_id), element);
if(!element)
return NULL;
assert(element->key.id == id && element->key.mplex_id == mplex_id);
assert(element->id == muxed_id);
return element->user_data;
}
......@@ -1147,14 +1166,14 @@ static void margo_rpc_data_free(void* ptr)
free(ptr);
}
static void delete_multiplexing_hash(margo_instance_id mid)
static void delete_provider_hash(margo_instance_id mid)
{
struct mplex_element *current_element, *tmp;
struct provider_element *current_element, *tmp;
HASH_ITER(hh, mid->mplex_table, current_element, tmp) {
HASH_ITER(hh, mid->provider_table, current_element, tmp) {
if(current_element->user_data && current_element->user_free_callback)
(current_element->user_free_callback)(current_element->user_data);
HASH_DEL(mid->mplex_table, current_element);
HASH_DEL(mid->provider_table, current_element);
free(current_element);
}
}
......@@ -1466,9 +1485,6 @@ static hg_return_t margo_handle_cache_get(margo_instance_id mid,
hret = HG_Reset(el->handle, addr, id);
if(hret == HG_SUCCESS)
{
/* XXX: Mercury doesn't reset the target_id so we need to do that manually for now */
HG_Set_target_id(el->handle, 0);
/* put on in-use list and pass back handle */
HASH_ADD(hh, mid->used_handle_hash, handle, sizeof(hg_handle_t), el);
*handle = el->handle;
......@@ -1533,3 +1549,66 @@ static void remote_shutdown_ult(hg_handle_t handle)
}
}
DEFINE_MARGO_RPC_HANDLER(remote_shutdown_ult)
static int margo_lookup_provider(margo_instance_id mid, hg_id_t id, uint16_t provider_id, ABT_pool *pool)
{
struct provider_element *element;
hg_id_t muxed_id;
if(!provider_id)
{
*pool = mid->handler_pool;
return(0);
}
muxed_id = mux_id(id, provider_id);
HASH_FIND(hh, mid->provider_table, &muxed_id, sizeof(muxed_id), element);
if(!element) {
return(-1);
}
assert(element->id == muxed_id);
*pool = element->pool;
return(0);
}
static hg_id_t margo_register_internal(margo_instance_id mid, const char *func_name,
hg_proc_cb_t in_proc_cb, hg_proc_cb_t out_proc_cb, hg_rpc_cb_t rpc_cb, uint16_t provider_id)
{
struct margo_rpc_data* margo_data;
hg_return_t hret;
hg_id_t id;
assert(provider_id <= MARGO_MAX_PROVIDER_ID);
id = gen_id(func_name, provider_id);
hret = HG_Register(mid->hg_class, id, in_proc_cb, out_proc_cb, rpc_cb);
if(hret != HG_SUCCESS)
return(hret);
/* register the margo data with the RPC */
margo_data = (struct margo_rpc_data*)HG_Registered_data(mid->hg_class, id);
if(!margo_data)
{
margo_data = (struct margo_rpc_data*)malloc(sizeof(struct margo_rpc_data));
if(!margo_data)
return(0);
margo_data->mid = mid;
margo_data->user_data = NULL;
margo_data->user_free_callback = NULL;
hret = HG_Register_data(mid->hg_class, id, margo_data, margo_rpc_data_free);
if(hret != HG_SUCCESS)
{
free(margo_data);
return(0);
}
}