22#ifndef NM_CORE_TYPES_H
23#define NM_CORE_TYPES_H
28#define NM_ALIGN_FRONTIER sizeof(NM_ALIGN_TYPE)
29#define nm_aligned(x) nm_aligned_n((x), NM_ALIGN_FRONTIER)
33 return (v + a - 1) & ~(a - 1);
40 return (
void*)((uintptr_t)p & ~(a - 1));
43#define nm_offset_of(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
44#define nm_container_of(ptr, type, member) \
45 ((type *)((char *)(__typeof__ (&((type *)0)->member))(ptr)- \
46 nm_offset_of(type,member)))
50#ifdef PIOMAN_MULTITHREAD
51#define NM_IS_THREADED 1
53#define NM_IS_THREADED ((nm_core_get_thread_level(nm_core_get_singleton()) >= NM_THREAD_SERIALIZED) ? 1 : 0)
58#define NM_ALLOCATOR_TYPE(ENAME, TYPE) PUK_ALLOCATOR_TYPE_EXT(ENAME, TYPE, !NM_IS_THREADED)
78#define NM_TRK_SMALL ((nm_trk_id_t)0)
79#define NM_TRK_LARGE ((nm_trk_id_t)1)
80#define NM_TRK_NONE ((nm_trk_id_t)-1)
83#define NM_MAX_TRACKS 2
88#define NM_SEQ_FIRST ((nm_seq_t)1)
106 const nm_seq_t seq1_abs = (seq1 > current) ? (seq1 - current) : (seq1 - current - 1);
107 const nm_seq_t seq2_abs = (seq2 > current) ? (seq2 - current) : (seq2 - current - 1);
108 if(seq1_abs < seq2_abs)
110 else if(seq1_abs > seq2_abs)
124 else if((seq1 < seq2) && (seq2 - seq1 < seq_compare_threshold))
126 else if((seq1 > seq2) && (seq1 - seq2 > 3 * seq_compare_threshold))
128 else if((seq1 > seq2) && (seq1 - seq2 < seq_compare_threshold))
130 else if((seq1 < seq2) && (seq2 - seq1 > 3 * seq_compare_threshold))
134 NM_FATAL(
"cannot compare seq1 = %u; seq2=%u\n", seq1, seq2);
141#define nm_profile_add(COUNTER, VALUE) do { __sync_fetch_and_add(&COUNTER, VALUE); } while(0)
143#define nm_profile_add(COUNTER, VALUE) do {} while(0)
146#define nm_profile_inc(COUNTER) nm_profile_add(COUNTER, 1)
156#define NM_LAZY_INITIALIZER_INIT { .init_done = 0, .initializing = 0 }
163#define NM_LAZY_INITIALIZER(ENAME, CTOR, DTOR) \
164 static struct nm_lazy_initializer_s ENAME ## _lazy_initializer = NM_LAZY_INITIALIZER_INIT; \
166 static void ENAME ## _lazy_init(void) \
168 if(ENAME##_lazy_initializer.init_done == 0) \
170 if(nm_atomic_inc(&ENAME##_lazy_initializer.initializing) == 0) \
173 nm_atomic_inc(&ENAME##_lazy_initializer.init_done); \
177 while(!ENAME##_lazy_initializer.init_done) \
183 else if(ENAME##_lazy_initializer.init_done == -1) \
185 NM_FATAL("trying to use %s after detructor.\n", #ENAME); \
188 static void ENAME ## _lazy_destructor(void) __attribute__((destructor)); \
189 static void ENAME ## _lazy_destructor(void) \
191 if(ENAME##_lazy_initializer.init_done > 0) \
195 ENAME##_lazy_initializer.init_done = -1; \
void(* nm_injector_pull_data_t)(struct nm_req_s *p_req, const struct nm_data_s *p_data, nm_len_t chunk_offset, nm_len_t chunk_len, void *p_ref)
user-supplied function called to pull data to posted request through nmad core p_req is the user requ...
PUK_LFQUEUE_TYPE(nm_pkt_wrap, struct nm_pkt_wrap_s *, NULL, 512)
LF queue type for completed pw.
PUK_LIST_DECLARE_TYPE2(nm_unexpected_wildcard, struct nm_unexpected_s)
static nm_len_t nm_aligned_n(nm_len_t v, nm_len_t a)
PUK_VECT_TYPE(nm_core_monitor, struct nm_core_monitor_s *)
static nm_seq_t nm_seq_next(nm_seq_t seq)
Compute next sequence number.
PUK_LIST_CREATE_FUNCS(nm_req)
static int nm_seq_compare(nm_seq_t current, nm_seq_t seq1, nm_seq_t seq2)
compare to seq numbers, assuming they are in the future returns -1 if seq1 is before seq2,...
#define NM_ALLOCATOR_TYPE(ENAME, TYPE)
static void * nm_aligned_ptr(const void *p, nm_len_t a)
get a pointer aligned to given alignment a
static int nm_seq_fuzzy_compare(nm_seq_t seq1, nm_seq_t seq2)
compare to seq numbers taking into account looping at overflow, assuming they are less than halftrip ...
PUK_LIST_TYPE(nm_core_pending_event, struct nm_core_event_s event;struct nm_core_monitor_s *p_core_monitor;)
a pending event, not dispatched immediately because it was received out of order
assert(p_data->ops.p_traversal !=NULL)
#define NM_FATAL(format,...)
#define NM_SEQ_MAX
largest sequence number
#define NM_SEQ_NONE
Reserved sequence number never used by real packets.
int32_t nm_prio_t
message priority
uint64_t nm_len_t
data length used by nmad
uint32_t nm_seq_t
Sequence number for packets on a given gate/tag.
uint8_t nm_proto_t
protocol flags- not part of the public API, but needed for inline
a chunk to be injected into nmad core
nm_injector_pull_data_t p_pull_data
function to call to actually get data
void * p_ref
user-supplied ref for the above function
an event ready for dispatch (matching already done)
struct nm_monitor_s * p_monitor
struct nm_core_event_s event
An event, generated by the NewMad core.
global monitor for status transitions
asynchronous tasks for nmad core.
Connection to another process.
an incoming chunk of data
nm_seq_t seq
sequence number
nm_core_tag_t tag
full tag
nm_len_t chunk_offset
offset of the chunk in the full message
nm_proto_t flags
proto flags associated with the chunk (NM_PROTO_FLAG_*)
nm_prio_t priority
priority of the incoming data (only for rdv)
nm_len_t chunk_len
length of the chunk itself
nm_gate_t p_gate
gate the chunk arrived from
int initializing
whether init is in progress
int init_done
whether init is already done
containers for matching info, used for caching
generic monitor, used for requests and for global events (with matching)
a generic pack/unpack request
a chunk of unexpected message to be stored
PUK_LIST_LINK(nm_unexpected_gate)
PUK_LIST_LINK(nm_unexpected_gtag)
link for list of unexpected per-tag
struct nm_core_task_s core_task
core task for unpack_next
struct nm_pkt_wrap_s * p_pw
pw this chunk arrived from; may be NULL if data is brought by injector
const union nm_header_generic_s * p_header
raw header in pw buffer
struct nm_matching_container_s matching
cache for matching containers
PUK_LIST_LINK(nm_unexpected_wildcard)
nm_len_t msg_len
length of full message on last chunk, NM_LEN_UNDEFINED if not last chunk
PUK_LIST_LINK(nm_unexpected_tag)
struct nm_chunk_injector_s injector
injector for this chunk
int matched
flag whether the unexpected is already matched (and delayed), and thus only enqueued in gtag matching...
struct nm_in_chunk_s chunk
metadata of the enclosed data chunk