Commit 1d46dc5d authored by Jonathan Jenkins's avatar Jonathan Jenkins

Merge branch 'map-context-api'

parents e2c478a9 ee48256f
......@@ -52,6 +52,23 @@ struct codes_cb_params {
(_cb_info_ptr)->cb_ret_offset = offsetof(_event_type, _cb_ret_field); \
} while (0)
#define CB_HO(_cb_params_ptr) ((_cb_params_ptr)->info.header_offset)
#define CB_TO(_cb_params_ptr) ((_cb_params_ptr)->info.tag_offset)
#define CB_RO(_cb_params_ptr) ((_cb_params_ptr)->info.cb_ret_offset)
/* Declare return variables at the right byte offsets from a codes_cb_params.
* Additionally, set the header and tag vars */
#define GET_INIT_CB_PTRS(_cb_params_ptr, _data_ptr, _sender_gid_val, _header_nm, _tag_nm, _rtn_name, _rtn_type) \
msg_header * _header_nm = \
(msg_header*)((char*)(_data_ptr) + CB_HO(_cb_params_ptr)); \
int * _tag_nm = \
(int*)((char*)(_data_ptr) + CB_TO(_cb_params_ptr));\
_rtn_type * _rtn_name = \
(_rtn_type*)((char*)(_data_ptr) + CB_RO(_cb_params_ptr)); \
msg_set_header((_cb_params_ptr)->h.magic, (_cb_params_ptr)->h.event_type, \
_sender_gid_val, _header_nm); \
*_tag_nm = (_cb_params_ptr)->tag
#define SANITY_CHECK_CB(_cb_info_ptr, _ret_type) \
do { \
int _total_size = sizeof(_ret_type) + sizeof(int) + sizeof(msg_header);\
......
/*
* Copyright (C) 2015 University of Chicago.
* See COPYRIGHT notice in top-level directory.
*
*/
/* SUMMARY - data structure and utilities to direct LP mappings. As opposed to
* the codes-mapping API, this defines metadata necessary to allow implicit
* mappings based on LP type and configuration specification
* (see modelnet, LSM, etc)
* mctx stands for mapping context */
#ifndef CODES_MAPPING_CONTEXT_H
#define CODES_MAPPING_CONTEXT_H
#include <stdbool.h>
#include <ross.h>
/* for convenience - an annotation-ignoring "group_modulo" context,
* matching previous mapping behavior in most interfaces (modelnet and such) */
extern struct codes_mctx const * const CODES_MCTX_DEFAULT;
/* types of map contexts */
enum codes_mctx_type {
// instructs those using the context to map directly to an LP
CODES_MCTX_GLOBAL_DIRECT,
// instructs those using the context to map into the same group/repetition
// and compute the callee offset as the modulus of the caller offset and
// the number of callees in the group, to provide simple wraparound
// behaviour
CODES_MCTX_GROUP_MODULO,
// instructs those using the context to map into the same group/repetition
// and directly to a callee offset
CODES_MCTX_GROUP_DIRECT,
// unknown/uninitialized context
CODES_MCTX_UNKNOWN
};
/* defines whether to specialize by destination annotation, and if so, which
* one.
*
* NOTE: this structure does not "own" the annotation, and makes no attempt to
* clean it up. */
struct codes_mctx_annotation {
char const * annotation;
bool ignore_annotations;
};
/* parameters for each mapping context type */
struct codes_mctx_global_direct {
tw_lpid lpid;
};
struct codes_mctx_group_modulo {
struct codes_mctx_annotation anno;
};
struct codes_mctx_group_direct {
struct codes_mctx_annotation anno;
int offset;
};
struct codes_mctx {
enum codes_mctx_type type;
union {
struct codes_mctx_global_direct global_direct;
struct codes_mctx_group_modulo group_modulo;
struct codes_mctx_group_direct group_direct;
} u;
};
/* simple setter functions */
struct codes_mctx codes_mctx_set_global_direct(tw_lpid lpid);
struct codes_mctx codes_mctx_set_group_modulo(
char const * annotation,
bool ignore_annotations);
struct codes_mctx codes_mctx_set_group_direct(
int offset,
char const * annotation,
bool ignore_annotations);
/* helper function to do a codes mapping - this function is subject to change
* based on what types of ctx exist
* NOTE: in GLOBAL_DIRECT mode, dest_lp_name and sender_gid are ignored */
tw_lpid codes_mctx_to_lpid(
struct codes_mctx const * ctx,
char const * dest_lp_name,
tw_lpid sender_gid);
/* helper function to extract which annotation a various map context maps to.
* annotation is allocated or NULL if unused */
char const * codes_mctx_get_annotation(
struct codes_mctx const *ctx,
char const * dest_lp_name,
tw_lpid sender_id);
#endif /* end of include guard: CODES_MAPPING_CONTEXT_H */
/*
* Local variables:
* c-indent-level: 4
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*
* vim: ts=8 sts=4 sw=4 expandtab
*/
......@@ -9,6 +9,9 @@
#include <ross.h>
#include "codes-callback.h"
#include "codes-mapping-context.h"
#define LSM_NAME "lsm"
/* HACK: problems arise when some LP sends multiple messages as part of an
......@@ -38,73 +41,58 @@ typedef enum lsm_event_e
LSM_READ_COMPLETION = 4
} lsm_event_t;
/*
* return type for lsm events (in the codes-callback sense)
*/
typedef struct {
int rc;
} lsm_return_t;
/*
* Prototypes
*/
/* given LP sender, find the LSM device LP in the same group */
tw_lpid lsm_find_local_device(
const char * annotation,
int ignore_annotations,
struct codes_mctx const * map_ctx,
tw_lpid sender_gid);
/*
* lsm_event_new
* lsm_io_event
* - creates a new event that is targeted for the corresponding
* LSM LP.
* - this event will allow wrapping the callers completion event
* - category: string name to identify the traffic category
* - dest_gid: the gid to send the callers event to
* - lp_io_category: string name to identify the traffic category for use in
* lp-io
* - gid_offset: relative offset of the LSM LP to the originating LP
* - io_object: id of byte stream the caller will modify
* - io_offset: offset into byte stream
* - io_size_bytes: size in bytes of IO request
* - io_type: read or write request
* - message_bytes: size of the event message the caller will have
* - sender: id of the sender
*/
tw_event* lsm_event_new(const char* category,
tw_lpid dest_gid,
uint64_t io_object,
int64_t io_offset,
uint64_t io_size_bytes,
int io_type,
size_t message_bytes,
tw_lp *sender,
tw_stime delay);
/* equivalent to lsm_event_new, except it allows to specify an annotation to
* filter by. If ignore_annotations is nonzero, A null annotation parameter
* indicates that the lsm LP to issue to has no annotation */
tw_event* lsm_event_new_annotated(
const char* category,
tw_lpid dest_gid,
void lsm_io_event(
const char * lp_io_category,
uint64_t io_object,
int64_t io_offset,
uint64_t io_size_bytes,
int io_type,
size_t message_bytes,
tw_lp *sender,
tw_stime delay,
const char * annotation,
int ignore_annotations);
void lsm_event_new_reverse(tw_lp *sender);
/*
* lsm_event_data
* - returns the pointer to the message data for the callers data
* - event: a lsm_event_t event
*/
void* lsm_event_data(tw_event *event);
tw_lp *sender,
struct codes_mctx const * map_ctx,
int return_tag,
msg_header const * return_header,
struct codes_cb_info const * cb);
void lsm_io_event_rc(tw_lp *sender);
/* get the priority count for the LSM scheduler.
* returns 0 if priorities aren't being used, -1 if no LSMs were configured,
* and >0 otherwise.
* This should not be called before lsm_configure */
int lsm_get_num_priorities(
char const * annotation,
int ignore_annotations);
struct codes_mctx const * map_ctx,
tw_lpid sender_id);
/* set a request priority for the following lsm_event_*.
* - tw_error will be called if the priority ends up being out-of-bounds
......@@ -120,15 +108,6 @@ void lsm_register(void);
/* configures the LSM model(s) */
void lsm_configure(void);
/*
* Macros
*/
#define lsm_write_event_new(cat,gid,obj,off,sz,mb,s) \
lsm_event_new((cat),(gid),(obj),(off),(sz),LSM_WRITE_REQUEST,(mb),(s),0.0)
#define lsm_read_event_new(cat,gid,obj,off,sz,mb,s) \
lsm_event_new((cat),(gid),(obj),(off),(sz),LSM_READ_REQUEST,(mb),(s),0.0)
#define LSM_DEBUG 0
#endif
......
......@@ -11,11 +11,14 @@
#ifndef RESOURCE_LP_H
#define RESOURCE_LP_H
#include "ross.h"
#include "codes/lp-msg.h"
#include "codes/resource.h"
#include <ross.h>
#include <stdint.h>
#include "lp-msg.h"
#include "resource.h"
#include "codes-callback.h"
#include "codes-mapping-context.h"
#define RESOURCE_MAX_CALLBACK_PAYLOAD 64
#define RESOURCE_LP_NM "resource"
......@@ -24,7 +27,7 @@ typedef struct {
int ret;
/* in the case of a reserve, need to return the token */
resource_token_t tok;
} resource_callback;
} resource_return;
/* registers the resource LP with CODES/ROSS */
......@@ -42,57 +45,43 @@ void resource_lp_configure();
*
* block_on_unavail - flag whether to wait to message the requester if
* request cannot be satisfied
* msg_size - size of the requester event structure
* msg_header_offset - offset in the requester event to place the resource's
* msg_header
* msg_callback_offset - offset in the requester event struct to place the
* resource-provided resource_callback data
* msg_callback_misc_size - size of requester-provided callback data
* msg_callback_misc_offset - offset in the requester event struct to place the
* requester-provided callback data
* msg_callback_misc_data - requester-provided callback data
*
* return_tag, return_header - set in the return client event, using the offsets in cb
*/
void resource_lp_get(
msg_header *header,
uint64_t req,
uint64_t req,
int block_on_unavail,
int msg_size,
int msg_header_offset,
int msg_callback_offset,
int msg_callback_misc_size,
int msg_callback_misc_offset,
void *msg_callback_misc_data,
tw_lp *sender);
tw_lp *sender,
struct codes_mctx const * map_ctx,
int return_tag,
msg_header const *return_header,
struct codes_cb_info const *cb);
/* no callback for frees thus far */
void resource_lp_free(uint64_t req, tw_lp *sender);
void resource_lp_free(
uint64_t req,
tw_lp *sender,
struct codes_mctx const * map_ctx);
void resource_lp_reserve(
msg_header *header,
uint64_t req,
int block_on_unavail,
int msg_size,
int msg_header_offset,
int msg_callback_offset,
int msg_callback_misc_size,
int msg_callback_misc_offset,
void *msg_callback_misc_data,
tw_lp *sender);
tw_lp *sender,
struct codes_mctx const * map_ctx,
int return_tag,
msg_header const *return_header,
struct codes_cb_info const *cb);
void resource_lp_get_reserved(
msg_header *header,
uint64_t req,
resource_token_t tok,
int block_on_unavail,
int msg_size,
int msg_header_offset,
int msg_callback_offset,
int msg_callback_misc_size,
int msg_callback_misc_offset,
void *msg_callback_misc_data,
tw_lp *sender);
tw_lp *sender,
struct codes_mctx const * map_ctx,
int return_tag,
msg_header const *return_header,
struct codes_cb_info const *cb);
void resource_lp_free_reserved(
uint64_t req,
resource_token_t tok,
tw_lp *sender);
tw_lp *sender,
struct codes_mctx const * map_ctx);
/* rc functions - thankfully, they only use codes-local-latency, so no need
* to pass in any arguments */
......
......@@ -59,7 +59,8 @@ nobase_include_HEADERS = \
codes/local-storage-model.h \
codes/rc-stack.h \
codes/codes-jobmap.h \
codes/codes-callback.h
codes/codes-callback.h \
codes/codes-mapping-context.h
#codes/codes-nw-workload.h
......@@ -102,6 +103,7 @@ src_libcodes_base_a_SOURCES = \
src/util/jobmap-impl/jobmap-dummy.c \
src/util/jobmap-impl/jobmap-list.c\
src/util/jobmap-impl/jobmap-identity.c\
src/util/codes-mapping-context.c \
src/workload/codes-workload.c \
src/workload/codes-workload-method.h \
src/workload/methods/codes-iolang-wrkld.c \
......
/*
* Copyright (C) 2015 University of Chicago.
* See COPYRIGHT notice in top-level directory.
*
*/
#include <codes/codes-mapping-context.h>
#include <codes/codes_mapping.h>
static struct codes_mctx const CODES_MCTX_DEFAULT_VAL = {
.type = CODES_MCTX_GROUP_MODULO,
.u = {
.group_modulo = {
.anno = {
.annotation = NULL,
.ignore_annotations = true
}
}
}
};
struct codes_mctx const * const CODES_MCTX_DEFAULT = &CODES_MCTX_DEFAULT_VAL;
struct codes_mctx codes_mctx_set_global_direct(tw_lpid lpid)
{
struct codes_mctx rtn;
rtn.type = CODES_MCTX_GLOBAL_DIRECT;
rtn.u.global_direct.lpid = lpid;
return rtn;
}
struct codes_mctx codes_mctx_set_group_modulo(
char const * annotation,
bool ignore_annotations)
{
struct codes_mctx rtn;
rtn.type = CODES_MCTX_GROUP_MODULO;
rtn.u.group_modulo.anno.annotation = annotation;
rtn.u.group_modulo.anno.ignore_annotations = ignore_annotations;
return rtn;
}
struct codes_mctx codes_mctx_set_group_direct(
int offset,
char const * annotation,
bool ignore_annotations)
{
struct codes_mctx rtn;
rtn.type = CODES_MCTX_GROUP_DIRECT;
rtn.u.group_direct.offset = offset;
rtn.u.group_direct.anno.annotation = annotation;
rtn.u.group_direct.anno.ignore_annotations = ignore_annotations;
return rtn;
}
/* helper function to do a codes mapping - this function is subject to change
* based on what types of ctx exist */
tw_lpid codes_mctx_to_lpid(
struct codes_mctx const * ctx,
char const * dest_lp_name,
tw_lpid sender_gid)
{
struct codes_mctx_annotation const *anno;
// short circuit for direct mappings
switch (ctx->type) {
case CODES_MCTX_GLOBAL_DIRECT:
return ctx->u.global_direct.lpid;
case CODES_MCTX_GROUP_MODULO:
anno = &ctx->u.group_modulo.anno;
break;
case CODES_MCTX_GROUP_DIRECT:
anno = &ctx->u.group_direct.anno;
break;
default:
assert(0);
}
char sender_group[MAX_NAME_LENGTH];
int unused, rep_id, offset;
// get sender info
codes_mapping_get_lp_info(sender_gid, sender_group, &unused, NULL, &unused,
NULL, &rep_id, &offset);
int dest_offset;
if (ctx->type == CODES_MCTX_GROUP_MODULO) {
int num_dest_lps = codes_mapping_get_lp_count(sender_group, 1,
dest_lp_name, anno->annotation, anno->ignore_annotations);
if (num_dest_lps == 0)
tw_error(TW_LOC,
"ERROR: Found no LPs of type %s in group %s "
"(source lpid %lu) with annotation: %s\n",
dest_lp_name, sender_group, sender_gid,
anno->ignore_annotations ? "ignored" :
(anno->annotation ? anno->annotation : "none"));
dest_offset = offset % num_dest_lps;
}
else if (ctx->type == CODES_MCTX_GROUP_DIRECT) {
dest_offset = ctx->u.group_direct.offset;
}
else
assert(0);
tw_lpid rtn;
codes_mapping_get_lp_id(sender_group, dest_lp_name, anno->annotation,
anno->ignore_annotations, rep_id, dest_offset, &rtn);
return rtn;
}
char const * codes_mctx_get_annotation(
struct codes_mctx const *ctx,
char const * dest_lp_name,
tw_lpid sender_id)
{
switch(ctx->type) {
case CODES_MCTX_GLOBAL_DIRECT:
return codes_mapping_get_annotation_by_lpid(sender_id);
case CODES_MCTX_GROUP_MODULO:
// if not ignoring the annotation, just return what's in the
// context
if (!ctx->u.group_modulo.anno.ignore_annotations)
return ctx->u.group_modulo.anno.annotation;
break;
case CODES_MCTX_GROUP_DIRECT:
if (!ctx->u.group_direct.anno.ignore_annotations)
return ctx->u.group_direct.anno.annotation;
break;
default:
tw_error(TW_LOC, "unrecognized or uninitialized context type: %d",
ctx->type);
return NULL;
}
// at this point, we must be a group-wise mapping ignoring annotations
char group[MAX_NAME_LENGTH];
int dummy;
// only need the group name
codes_mapping_get_lp_info(sender_id, group, &dummy, NULL, &dummy, NULL,
&dummy, &dummy);
return codes_mapping_get_annotation_by_name(group, dest_lp_name);
}
/*
* Local variables:
* c-indent-level: 4
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*
* vim: ts=8 sts=4 sw=4 expandtab
*/
......@@ -21,18 +21,6 @@
int lsm_in_sequence = 0;
tw_stime lsm_msg_offset = 0.0;
/*
* wrapped_event_t
* - holds the callers event and data they want sent upon
* completion of a IO operation.
*/
typedef struct wrapped_event_s
{
tw_lpid id;
size_t size;
char message[1];
} wrapped_event_t;
/* holds statistics about disk traffic on each LP */
typedef struct lsm_stats_s
{
......@@ -143,7 +131,7 @@ typedef struct lsm_message_s
int64_t prev_offset;
uint64_t prev_object;
lsm_message_data_t data;
wrapped_event_t wrap;
struct codes_cb_params cb;
} lsm_message_t;
/*
......@@ -266,82 +254,55 @@ static tw_stime transfer_time_table (lsm_state_t *ns,
return time;
}
void lsm_event_new_reverse(tw_lp *sender)
void lsm_io_event_rc(tw_lp *sender)
{
codes_local_latency_reverse(sender);
return;
}
static tw_lpid lsm_find_local_device_default(
const char * annotation,
int ignore_annotations,
tw_lpid sender_gid) {
char group_name[MAX_NAME_LENGTH];
int dummy, mapping_rep, mapping_offset;
int num_lsm_lps;
tw_lpid rtn;
codes_mapping_get_lp_info(sender_gid, group_name, &dummy, NULL, &dummy,
NULL, &mapping_rep, &mapping_offset);
num_lsm_lps = codes_mapping_get_lp_count(group_name, 1, LSM_NAME,
annotation, ignore_annotations);
codes_mapping_get_lp_id(group_name, LSM_NAME, annotation,
ignore_annotations, mapping_rep, mapping_offset % num_lsm_lps,
&rtn);
return rtn;
}
tw_lpid lsm_find_local_device(
const char * annotation,
int ignore_annotations,
tw_lpid sender_gid) {
return lsm_find_local_device_default(annotation, ignore_annotations,
sender_gid);
struct codes_mctx const * map_ctx,
tw_lpid sender_gid)
{
return codes_mctx_to_lpid(map_ctx, LSM_NAME, sender_gid);
}
static tw_event* lsm_event_new_base(
const char* category,
tw_lpid dest_gid,
void lsm_io_event(
const char * lp_io_category,
uint64_t io_object,
int64_t io_offset,
uint64_t io_size_bytes,
int io_type,
size_t message_bytes,
tw_lp *sender,
tw_stime delay,
const char * annotation,
int ignore_annotations)
tw_lp *sender,
struct codes_mctx const * map_ctx,
int return_tag,
msg_header const * return_header,
struct codes_cb_info const * cb)
{
tw_event *e;
lsm_message_t *m;
tw_lpid lsm_gid;
tw_stime delta;
assert(strlen(category) < CATEGORY_NAME_MAX-1);
assert(strlen(category) > 0);
assert(strlen(lp_io_category) < CATEGORY_NAME_MAX-1);
assert(strlen(lp_io_category) > 0);
SANITY_CHECK_CB(cb, lsm_return_t);
/* Generate an event for the local storage model, and send the
* event to an lsm LP.
*/
lsm_gid = lsm_find_local_device(annotation, ignore_annotations, sender->gid);
tw_lpid lsm_id = codes_mctx_to_lpid(map_ctx, LSM_NAME, sender->gid);
delta = codes_local_latency(sender) + delay;
tw_stime delta = delay + codes_local_latency(sender);
if (lsm_in_sequence) {
tw_stime tmp = lsm_msg_offset;
lsm_msg_offset += delta;
delta += tmp;
}
e = codes_event_new(lsm_gid, delta, sender);
m = (lsm_message_t*)tw_event_data(e);
tw_event *e = tw_event_new(lsm_id, delta, sender);
lsm_message_t *m = tw_event_data(e);
m->magic = lsm_magic;
m->event = (lsm_event_t)io_type;
m->event = (lsm_event_t) io_type;
m->data.object = io_object;
m->data.offset = io_offset;
m->data.size = io_size_bytes;
strcpy(m->data.category, category);
strcpy(m->data.category, lp_io_category);
// get the priority count for checking
int num_prios = lsm_get_num_priorities(annotation, ignore_annotations);
int num_prios = lsm_get_num_priorities(map_ctx, sender->gid);
// prio checks and sets
if (num_prios <= 0) // disabled scheduler - ignore
m->data.prio = 0;
......@@ -352,105 +313,34 @@ static tw_event* lsm_event_new_base(
else
tw_error(TW_LOC,
"LP %lu, LSM LP %lu: Bad priority (%d supplied, %d lanes)\n",
sender->gid, dest_gid, temp_prio, num_prios);
sender->gid, lsm_id, temp_prio, num_prios);
// reset temp_prio
temp_prio = -1;
/* save callers dest_gid and message size */
m->wrap.id = dest_gid;
m->wrap.size = message_bytes;
return e;
}
m->cb.info = *cb;
m->cb.h = *return_header;
m->cb.tag = return_tag;
/*
* lsm_event_new
* - creates a new event that is targeted for the corresponding
* LSM LP.
* - this event will allow wrapping the callers completion event
* - category: string name to identify the traffic category
* - dest_gid: the gid to send the callers event to
* - gid_offset: relative offset of the LSM LP to the originating LP
* - io_object: id of byte stream the caller will modify
* - io_offset: offset into byte stream
* - io_size_bytes: size in bytes of IO request
* - io_type: read or write request
* - message_bytes: size of the event message the caller will have
* - sender: id of the sender
*/
tw_event* lsm_event_new(
const char* category,
tw_lpid dest_gid,
uint64_t io_object,
int64_t io_offset,
uint64_t io_size_bytes,
int io_type,
size_t message_bytes,
tw_lp *sender,
tw_stime delay) {
return lsm_event_new_base(category, dest_gid, io_object, io_offset,
io_size_bytes, io_type, message_bytes, sender, delay, NULL, 1);
}
tw_event* lsm_event_new_annotated(
const char* category,
tw_lpid dest_gid,
uint64_t io_object,
int64_t io_offset,
uint64_t io_size_bytes,
int io_type,
size_t message_bytes,
tw_lp *sender,
tw_stime delay,
const char * annotation,
int ignore_annotations) {
return lsm_event_new_base(category, dest_gid, io_object, io_offset,
io_size_bytes, io_type, message_bytes, sender, delay, annotation,
ignore_annotations);
}
/*
* lsm_event_data
* - returns the pointer to the message data for the callers data
* - event: a lsm_event_t event
*/
void* lsm_event_data(tw_event *event)
{
lsm_message_t *m;
/* return a pointer to space for caller to store event message
* space was allocated in lsm_event_new
*/
m = (lsm_message_t *) tw_event_data(event);
return m->wrap.message;
tw_event_send(e);