22#ifndef NM_CORE_TYPES_H
23#define NM_CORE_TYPES_H
29#define NM_ALIGN_FRONTIER sizeof(NM_ALIGN_TYPE)
30#define nm_aligned(x) nm_aligned_n((x), NM_ALIGN_FRONTIER)
34 return (v + a - 1) & ~(a - 1);
41 return (
void*)((uintptr_t)p & ~(a - 1));
44#define nm_offset_of(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
45#define nm_container_of(ptr, type, member) \
46 ((type *)((char *)(__typeof__ (&((type *)0)->member))(ptr)- \
47 nm_offset_of(type,member)))
51#ifdef PIOMAN_MULTITHREAD
52#define NM_IS_THREADED 1
54#define NM_IS_THREADED ((nm_core_get_thread_level(nm_core_get_singleton()) >= NM_THREAD_SERIALIZED) ? 1 : 0)
59#define NM_ALLOCATOR_TYPE(ENAME, TYPE) PUK_ALLOCATOR_TYPE_EXT(ENAME, TYPE, !NM_IS_THREADED)
72#define NM_TRK_SMALL ((nm_trk_id_t)0)
73#define NM_TRK_LARGE ((nm_trk_id_t)1)
74#define NM_TRK_NONE ((nm_trk_id_t)-1)
77#define NM_MAX_TRACKS 2
82#define NM_SEQ_FIRST ((nm_seq_t)1)
100 const nm_seq_t seq1_abs = (seq1 > current) ? (seq1 - current) : (seq1 - current - 1);
101 const nm_seq_t seq2_abs = (seq2 > current) ? (seq2 - current) : (seq2 - current - 1);
102 if(seq1_abs < seq2_abs)
104 else if(seq1_abs > seq2_abs)
118 else if((seq1 < seq2) && (seq2 - seq1 < seq_compare_threshold))
120 else if((seq1 > seq2) && (seq1 - seq2 > 3 * seq_compare_threshold))
122 else if((seq1 > seq2) && (seq1 - seq2 < seq_compare_threshold))
124 else if((seq1 < seq2) && (seq2 - seq1 > 3 * seq_compare_threshold))
128 NM_FATAL(
"cannot compare seq1 = %u; seq2=%u\n", seq1, seq2);
135#define nm_profile_add(COUNTER, VALUE) do { __sync_fetch_and_add(&COUNTER, VALUE); } while(0)
137#define nm_profile_add(COUNTER, VALUE) do {} while(0)
140#define nm_profile_inc(COUNTER) nm_profile_add(COUNTER, 1)
150#define NM_LAZY_INITIALIZER_INIT { .init_done = 0, .initializing = 0 }
157#define NM_LAZY_INITIALIZER(ENAME, CTOR, DTOR) \
158 static struct nm_lazy_initializer_s ENAME ## _lazy_initializer = NM_LAZY_INITIALIZER_INIT; \
160 static void ENAME ## _lazy_init(void) \
162 if(ENAME##_lazy_initializer.init_done == 0) \
164 if(nm_atomic_inc(&ENAME##_lazy_initializer.initializing) == 0) \
167 nm_atomic_inc(&ENAME##_lazy_initializer.init_done); \
171 while(!ENAME##_lazy_initializer.init_done) \
177 else if(ENAME##_lazy_initializer.init_done == -1) \
179 NM_FATAL("trying to use %s after detructor.\n", #ENAME); \
182 static void ENAME ## _lazy_destructor(void) __attribute__((destructor)); \
183 static void ENAME ## _lazy_destructor(void) \
185 if(ENAME##_lazy_initializer.init_done > 0) \
189 ENAME##_lazy_initializer.init_done = -1; \
284 struct nm_refcount_holder_list_s holders;
291 nm_refcount_holder_itor_t i;
292 puk_list_foreach(nm_refcount_holder, i, &p_refcount->holders)
294 NM_WARN(
"pending ref- object = %s; p_holder = %p; %s:%d %s()\n",
295 p_refcount->object_id, i->p_holder, i->file, i->line, i->func);
305 padico_free(p_refcount->object_id);
306 nm_refcount_holder_list_destroy(&p_refcount->holders);
312 return atomic_load(&p_refcount->
refcount);
315#define nm_refcount_inc(REFCOUNT, HOLDER) \
316 nm_refcount_inc_internal(REFCOUNT, HOLDER, __FUNCTION__, __FILE__, __LINE__)
319static inline void nm_refcount_add_holder(
struct nm_refcount_s*p_refcount,
const void*p_holder,
320 const char*func,
const char*file,
const int line)
322 struct nm_refcount_holder_s*
h = nm_refcount_holder_new();
323 h->p_holder = p_holder;
327 nm_refcount_holder_list_push_back(&p_refcount->holders,
h);
330static inline int nm_refcount_count_holder(
struct nm_refcount_s*p_refcount,
const void*p_holder)
333 nm_refcount_holder_itor_t i;
334 puk_list_foreach(nm_refcount_holder, i, &p_refcount->holders)
336 if(i->p_holder == p_holder)
349 atomic_fetch_add(&p_refcount->
refcount, 1);
355 if(nm_refcount_count_holder(p_refcount, p_holder) > 0)
357 nm_refcount_holder_itor_t i;
358 PUK_LIST_FIND(nm_refcount_holder, i, &p_refcount->holders, (i->p_holder == p_holder));
359 NM_WARN(
"p_holder = %p already holding a ref to p_refcount = %p (%s)\n"
360 " new holder: %s:%d %s()\n"
361 " previous holder: %s:%d %s()\n",
362 p_holder, p_refcount, p_refcount->object_id,
363 file, line, func, i->file, i->line, i->func);
366 nm_refcount_add_holder(p_refcount, p_holder, func, file, line);
375 const int nb_ref = atomic_fetch_sub(&p_refcount->
refcount, 1) - 1;
381 const int count = nm_refcount_count_holder(p_refcount, p_holder);
382 nm_refcount_holder_itor_t i;
383 PUK_LIST_FIND(nm_refcount_holder, i, &p_refcount->holders, (i->p_holder == p_holder));
386 NM_FATAL(
"p_holder = %p not holding ref to p_refcount = %p (%s); cannot release\n",
387 p_holder, p_refcount, p_refcount->object_id);
391 nm_refcount_holder_list_remove(&p_refcount->holders, i);
392 nm_refcount_holder_delete(i);
394 assert(nm_refcount_count_holder(p_refcount, p_holder) ==
count - 1);
407 atomic_store(&p_refcount->
refcount, 1);
409 p_refcount->object_id = p_object_id;
411 nm_refcount_holder_list_init(&p_refcount->holders);
412 if(p_init_holder != NULL)
414 nm_refcount_add_holder(p_refcount, p_init_holder, __FUNCTION__, __FILE__, __LINE__);
417 if(p_object_id != NULL)
418 padico_free(p_object_id);
struct nm_core_event_s __attribute__
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...
static void nm_spin_init(nm_spinlock_t *p_spin)
init the spin lock
static void nm_spin_destroy(nm_spinlock_t *p_spin)
destroy the spin lock
static void nm_spin_lock(nm_spinlock_t *p_spin)
acquire the spin lock
static void nm_spin_unlock(nm_spinlock_t *p_spin)
release the spin lock
without even the implied warranty of !MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE See the GNU !General Public License for more details !mpif h
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 void nm_refcount_inc_internal(struct nm_refcount_s *p_refcount, const void *p_holder __attribute__((unused)), const char *func __attribute__((unused)), const char *file __attribute__((unused)), const int line __attribute__((unused)))
static nm_seq_t nm_seq_next(nm_seq_t seq)
Compute next sequence number.
PUK_LIST_CREATE_FUNCS(nm_req)
static void nm_refcount_init(struct nm_refcount_s *p_refcount, char *p_object_id, const void *p_init_holder)
initialize a new refcount object; get the object ID to make debugging easier; we take ownership of ob...
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,...
PUK_LFQUEUE_TYPE(nm_core_dispatching_event, struct nm_core_dispatching_event_s *, NULL, 1024)
#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 ...
static void nm_refcount_dump(struct nm_refcount_s *p_refcount __attribute__((unused)))
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
static void nm_refcount_destroy(struct nm_refcount_s *p_refcount __attribute__((unused)))
static int nm_refcount_dec(struct nm_refcount_s *p_refcount, const void *p_holder __attribute__((unused)))
decrement refcount for holder; returns refcount (if 0, caller may free ref-counted resource)
static int nm_refcount_get(struct nm_refcount_s *p_refcount)
assert(p_data->ops.p_traversal !=NULL)
#define NM_FATAL(format,...)
#define NM_WARN(format,...)
nm_mpi_count_t count
number of elements to be exchanged
#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 reference-counter that keeps trace of who increments/decrements in debug: full reference tracking i...
atomic_int refcount
the counter itself
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