Do not scan instances in dds_{read,take}_instance

Scanning all instances was never good for anything: the RHC is organised
as hash table on instance id (which is an alias for "instance handle")
and it was always designed to do this with a fast lookup.

Signed-off-by: Erik Boasson <eb@ilities.com>
This commit is contained in:
Erik Boasson 2020-04-19 17:36:01 +02:00 committed by eboasson
parent 5f829684ef
commit 9aef05542f
3 changed files with 320 additions and 425 deletions

View file

@ -27,9 +27,8 @@ struct dds_reader;
struct ddsi_tkmap; struct ddsi_tkmap;
typedef dds_return_t (*dds_rhc_associate_t) (struct dds_rhc *rhc, struct dds_reader *reader, const struct ddsi_sertopic *topic, struct ddsi_tkmap *tkmap); typedef dds_return_t (*dds_rhc_associate_t) (struct dds_rhc *rhc, struct dds_reader *reader, const struct ddsi_sertopic *topic, struct ddsi_tkmap *tkmap);
typedef int (*dds_rhc_read_t) (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, struct dds_readcond *cond); typedef int32_t (*dds_rhc_read_take_t) (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, struct dds_readcond *cond);
typedef int (*dds_rhc_take_t) (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, struct dds_readcond *cond); typedef int32_t (*dds_rhc_read_take_cdr_t) (struct dds_rhc *rhc, bool lock, struct ddsi_serdata **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t sample_states, uint32_t view_states, uint32_t instance_states, dds_instance_handle_t handle);
typedef int (*dds_rhc_takecdr_t) (struct dds_rhc *rhc, bool lock, struct ddsi_serdata **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t sample_states, uint32_t view_states, uint32_t instance_states, dds_instance_handle_t handle);
typedef bool (*dds_rhc_add_readcondition_t) (struct dds_rhc *rhc, struct dds_readcond *cond); typedef bool (*dds_rhc_add_readcondition_t) (struct dds_rhc *rhc, struct dds_readcond *cond);
typedef void (*dds_rhc_remove_readcondition_t) (struct dds_rhc *rhc, struct dds_readcond *cond); typedef void (*dds_rhc_remove_readcondition_t) (struct dds_rhc *rhc, struct dds_readcond *cond);
@ -40,9 +39,9 @@ struct dds_rhc_ops {
/* A copy of DDSI rhc ops comes first so we can use either interface without /* A copy of DDSI rhc ops comes first so we can use either interface without
additional indirections */ additional indirections */
struct ddsi_rhc_ops rhc_ops; struct ddsi_rhc_ops rhc_ops;
dds_rhc_read_t read; dds_rhc_read_take_t read;
dds_rhc_take_t take; dds_rhc_read_take_t take;
dds_rhc_takecdr_t takecdr; dds_rhc_read_take_cdr_t takecdr;
dds_rhc_add_readcondition_t add_readcondition; dds_rhc_add_readcondition_t add_readcondition;
dds_rhc_remove_readcondition_t remove_readcondition; dds_rhc_remove_readcondition_t remove_readcondition;
dds_rhc_lock_samples_t lock_samples; dds_rhc_lock_samples_t lock_samples;
@ -76,13 +75,13 @@ DDS_EXPORT inline void dds_rhc_set_qos (struct dds_rhc *rhc, const struct dds_qo
DDS_EXPORT inline void dds_rhc_free (struct dds_rhc *rhc) { DDS_EXPORT inline void dds_rhc_free (struct dds_rhc *rhc) {
rhc->common.ops->rhc_ops.free (&rhc->common.rhc); rhc->common.ops->rhc_ops.free (&rhc->common.rhc);
} }
DDS_EXPORT inline int dds_rhc_read (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, struct dds_readcond *cond) { DDS_EXPORT inline int32_t dds_rhc_read (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, struct dds_readcond *cond) {
return (rhc->common.ops->read) (rhc, lock, values, info_seq, max_samples, mask, handle, cond); return (rhc->common.ops->read) (rhc, lock, values, info_seq, max_samples, mask, handle, cond);
} }
DDS_EXPORT inline int dds_rhc_take (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, struct dds_readcond *cond) { DDS_EXPORT inline int32_t dds_rhc_take (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, struct dds_readcond *cond) {
return rhc->common.ops->take (rhc, lock, values, info_seq, max_samples, mask, handle, cond); return rhc->common.ops->take (rhc, lock, values, info_seq, max_samples, mask, handle, cond);
} }
DDS_EXPORT inline int dds_rhc_takecdr (struct dds_rhc *rhc, bool lock, struct ddsi_serdata **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t sample_states, uint32_t view_states, uint32_t instance_states, dds_instance_handle_t handle) { DDS_EXPORT inline int32_t dds_rhc_takecdr (struct dds_rhc *rhc, bool lock, struct ddsi_serdata **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t sample_states, uint32_t view_states, uint32_t instance_states, dds_instance_handle_t handle) {
return rhc->common.ops->takecdr (rhc, lock, values, info_seq, max_samples, sample_states, view_states, instance_states, handle); return rhc->common.ops->takecdr (rhc, lock, values, info_seq, max_samples, sample_states, view_states, instance_states, handle);
} }
DDS_EXPORT inline bool dds_rhc_add_readcondition (struct dds_rhc *rhc, struct dds_readcond *cond) { DDS_EXPORT inline bool dds_rhc_add_readcondition (struct dds_rhc *rhc, struct dds_readcond *cond) {

View file

@ -40,7 +40,7 @@ static dds_return_t dds_read_impl (bool take, dds_entity_t reader_or_condition,
#define NC_FREE_BUF 2u #define NC_FREE_BUF 2u
#define NC_RESET_BUF 4u #define NC_RESET_BUF 4u
if (buf == NULL || si == NULL || maxs == 0 || bufsz == 0 || bufsz < maxs) if (buf == NULL || si == NULL || maxs == 0 || bufsz == 0 || bufsz < maxs || maxs > INT32_MAX)
return DDS_RETCODE_BAD_PARAMETER; return DDS_RETCODE_BAD_PARAMETER;
if ((ret = dds_entity_pin (reader_or_condition, &entity)) < 0) { if ((ret = dds_entity_pin (reader_or_condition, &entity)) < 0) {
@ -61,14 +61,6 @@ static dds_return_t dds_read_impl (bool take, dds_entity_t reader_or_condition,
thread_state_awake (ts1, &entity->m_domain->gv); thread_state_awake (ts1, &entity->m_domain->gv);
if (hand != DDS_HANDLE_NIL)
{
if (ddsi_tkmap_find_by_id (entity->m_domain->gv.m_tkmap, hand) == NULL) {
ret = DDS_RETCODE_PRECONDITION_NOT_MET;
goto fail_awake_pinned;
}
}
/* Allocate samples if not provided (assuming all or none provided) */ /* Allocate samples if not provided (assuming all or none provided) */
if (buf[0] == NULL) if (buf[0] == NULL)
{ {
@ -142,8 +134,6 @@ static dds_return_t dds_read_impl (bool take, dds_entity_t reader_or_condition,
#undef NC_FREE_BUF #undef NC_FREE_BUF
#undef NC_RESET_BUF #undef NC_RESET_BUF
fail_awake_pinned:
thread_state_asleep (ts1);
fail_pinned: fail_pinned:
dds_entity_unpin (entity); dds_entity_unpin (entity);
fail: fail:
@ -157,12 +147,8 @@ static dds_return_t dds_readcdr_impl (bool take, dds_entity_t reader_or_conditio
struct dds_reader *rd; struct dds_reader *rd;
struct dds_entity *entity; struct dds_entity *entity;
assert (take); if (buf == NULL || si == NULL || maxs == 0 || maxs > INT32_MAX)
assert (buf); return DDS_RETCODE_BAD_PARAMETER;
assert (si);
assert (hand == DDS_HANDLE_NIL);
assert (maxs > 0);
(void)take;
if ((ret = dds_entity_pin (reader_or_condition, &entity)) < 0) { if ((ret = dds_entity_pin (reader_or_condition, &entity)) < 0) {
return ret; return ret;

View file

@ -337,7 +337,7 @@ struct dds_rhc_default {
}; };
struct trigger_info_cmn { struct trigger_info_cmn {
unsigned qminst; uint32_t qminst;
bool has_read; bool has_read;
bool has_not_read; bool has_not_read;
}; };
@ -368,9 +368,9 @@ static bool dds_rhc_default_store (struct dds_rhc_default * __restrict rhc, cons
static void dds_rhc_default_unregister_wr (struct dds_rhc_default * __restrict rhc, const struct ddsi_writer_info * __restrict wrinfo); static void dds_rhc_default_unregister_wr (struct dds_rhc_default * __restrict rhc, const struct ddsi_writer_info * __restrict wrinfo);
static void dds_rhc_default_relinquish_ownership (struct dds_rhc_default * __restrict rhc, const uint64_t wr_iid); static void dds_rhc_default_relinquish_ownership (struct dds_rhc_default * __restrict rhc, const uint64_t wr_iid);
static void dds_rhc_default_set_qos (struct dds_rhc_default *rhc, const struct dds_qos *qos); static void dds_rhc_default_set_qos (struct dds_rhc_default *rhc, const struct dds_qos *qos);
static int dds_rhc_default_read (struct dds_rhc_default *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, dds_readcond *cond); static int32_t dds_rhc_default_read (struct dds_rhc_default *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, dds_readcond *cond);
static int dds_rhc_default_take (struct dds_rhc_default *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, dds_readcond *cond); static int32_t dds_rhc_default_take (struct dds_rhc_default *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, dds_readcond *cond);
static int dds_rhc_default_takecdr (struct dds_rhc_default *rhc, bool lock, struct ddsi_serdata ** values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t sample_states, uint32_t view_states, uint32_t instance_states, dds_instance_handle_t handle); static int32_t dds_rhc_default_takecdr (struct dds_rhc_default *rhc, bool lock, struct ddsi_serdata ** values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t sample_states, uint32_t view_states, uint32_t instance_states, dds_instance_handle_t handle);
static bool dds_rhc_default_add_readcondition (struct dds_rhc_default *rhc, dds_readcond *cond); static bool dds_rhc_default_add_readcondition (struct dds_rhc_default *rhc, dds_readcond *cond);
static void dds_rhc_default_remove_readcondition (struct dds_rhc_default *rhc, dds_readcond *cond); static void dds_rhc_default_remove_readcondition (struct dds_rhc_default *rhc, dds_readcond *cond);
static uint32_t dds_rhc_default_lock_samples (struct dds_rhc_default *rhc); static uint32_t dds_rhc_default_lock_samples (struct dds_rhc_default *rhc);
@ -390,13 +390,13 @@ static void dds_rhc_default_relinquish_ownership_wrap (struct ddsi_rhc * __restr
static void dds_rhc_default_set_qos_wrap (struct ddsi_rhc *rhc, const struct dds_qos *qos) { static void dds_rhc_default_set_qos_wrap (struct ddsi_rhc *rhc, const struct dds_qos *qos) {
dds_rhc_default_set_qos ((struct dds_rhc_default *) rhc, qos); dds_rhc_default_set_qos ((struct dds_rhc_default *) rhc, qos);
} }
static int dds_rhc_default_read_wrap (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, dds_readcond *cond) { static int32_t dds_rhc_default_read_wrap (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, dds_readcond *cond) {
return dds_rhc_default_read ((struct dds_rhc_default *) rhc, lock, values, info_seq, max_samples, mask, handle, cond); return dds_rhc_default_read ((struct dds_rhc_default *) rhc, lock, values, info_seq, max_samples, mask, handle, cond);
} }
static int dds_rhc_default_take_wrap (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, dds_readcond *cond) { static int32_t dds_rhc_default_take_wrap (struct dds_rhc *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, dds_readcond *cond) {
return dds_rhc_default_take ((struct dds_rhc_default *) rhc, lock, values, info_seq, max_samples, mask, handle, cond); return dds_rhc_default_take ((struct dds_rhc_default *) rhc, lock, values, info_seq, max_samples, mask, handle, cond);
} }
static int dds_rhc_default_takecdr_wrap (struct dds_rhc *rhc, bool lock, struct ddsi_serdata **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t sample_states, uint32_t view_states, uint32_t instance_states, dds_instance_handle_t handle) { static int32_t dds_rhc_default_takecdr_wrap (struct dds_rhc *rhc, bool lock, struct ddsi_serdata **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t sample_states, uint32_t view_states, uint32_t instance_states, dds_instance_handle_t handle) {
return dds_rhc_default_takecdr ((struct dds_rhc_default *) rhc, lock, values, info_seq, max_samples, sample_states, view_states, instance_states, handle); return dds_rhc_default_takecdr ((struct dds_rhc_default *) rhc, lock, values, info_seq, max_samples, sample_states, view_states, instance_states, handle);
} }
static bool dds_rhc_default_add_readcondition_wrap (struct dds_rhc *rhc, dds_readcond *cond) { static bool dds_rhc_default_add_readcondition_wrap (struct dds_rhc *rhc, dds_readcond *cond) {
@ -432,12 +432,12 @@ static const struct dds_rhc_ops dds_rhc_default_ops = {
.associate = dds_rhc_default_associate .associate = dds_rhc_default_associate
}; };
static unsigned qmask_of_sample (const struct rhc_sample *s) static uint32_t qmask_of_sample (const struct rhc_sample *s)
{ {
return s->isread ? DDS_READ_SAMPLE_STATE : DDS_NOT_READ_SAMPLE_STATE; return s->isread ? DDS_READ_SAMPLE_STATE : DDS_NOT_READ_SAMPLE_STATE;
} }
static unsigned qmask_of_invsample (const struct rhc_instance *i) static uint32_t qmask_of_invsample (const struct rhc_instance *i)
{ {
return i->inv_isread ? DDS_READ_SAMPLE_STATE : DDS_NOT_READ_SAMPLE_STATE; return i->inv_isread ? DDS_READ_SAMPLE_STATE : DDS_NOT_READ_SAMPLE_STATE;
} }
@ -467,17 +467,17 @@ static bool inst_has_unread (const struct rhc_instance *i)
return inst_nread (i) < inst_nsamples (i); return inst_nread (i) < inst_nsamples (i);
} }
static void topicless_to_clean_invsample (const struct ddsi_sertopic *topic, const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim) static bool topicless_to_clean_invsample (const struct ddsi_sertopic *topic, const struct ddsi_serdata *d, void *sample, void **bufptr, void *buflim)
{ {
/* ddsi_serdata_topicless_to_sample just deals with the key value, without paying any attention to attributes; /* ddsi_serdata_topicless_to_sample just deals with the key value, without paying any attention to attributes;
but that makes life harder for the user: the attributes of an invalid sample would be garbage, but would but that makes life harder for the user: the attributes of an invalid sample would be garbage, but would
nonetheless have to be freed in the end. Zero'ing it explicitly solves that problem. */ nonetheless have to be freed in the end. Zero'ing it explicitly solves that problem. */
ddsi_sertopic_free_sample (topic, sample, DDS_FREE_CONTENTS); ddsi_sertopic_free_sample (topic, sample, DDS_FREE_CONTENTS);
ddsi_sertopic_zero_sample (topic, sample); ddsi_sertopic_zero_sample (topic, sample);
ddsi_serdata_topicless_to_sample (topic, d, sample, bufptr, buflim); return ddsi_serdata_topicless_to_sample (topic, d, sample, bufptr, buflim);
} }
static unsigned qmask_of_inst (const struct rhc_instance *inst); static uint32_t qmask_of_inst (const struct rhc_instance *inst);
static void free_sample (struct dds_rhc_default *rhc, struct rhc_instance *inst, struct rhc_sample *s); static void free_sample (struct dds_rhc_default *rhc, struct rhc_instance *inst, struct rhc_sample *s);
static void get_trigger_info_cmn (struct trigger_info_cmn *info, struct rhc_instance *inst); static void get_trigger_info_cmn (struct trigger_info_cmn *info, struct rhc_instance *inst);
static void get_trigger_info_pre (struct trigger_info_pre *info, struct rhc_instance *inst); static void get_trigger_info_pre (struct trigger_info_pre *info, struct rhc_instance *inst);
@ -1462,7 +1462,7 @@ static rhc_store_result_t rhc_store_new_instance (struct rhc_instance **out_inst
static bool dds_rhc_default_store (struct dds_rhc_default * __restrict rhc, const struct ddsi_writer_info * __restrict wrinfo, struct ddsi_serdata * __restrict sample, struct ddsi_tkmap_instance * __restrict tk) static bool dds_rhc_default_store (struct dds_rhc_default * __restrict rhc, const struct ddsi_writer_info * __restrict wrinfo, struct ddsi_serdata * __restrict sample, struct ddsi_tkmap_instance * __restrict tk)
{ {
const uint64_t wr_iid = wrinfo->iid; const uint64_t wr_iid = wrinfo->iid;
const unsigned statusinfo = sample->statusinfo; const uint32_t statusinfo = sample->statusinfo;
const bool has_data = (sample->kind == SDK_DATA); const bool has_data = (sample->kind == SDK_DATA);
const int is_dispose = (statusinfo & NN_STATUSINFO_DISPOSE) != 0; const int is_dispose = (statusinfo & NN_STATUSINFO_DISPOSE) != 0;
struct rhc_instance dummy_instance; struct rhc_instance dummy_instance;
@ -1845,9 +1845,9 @@ static void dds_rhc_default_relinquish_ownership (struct dds_rhc_default * __res
instance: ANY, ALIVE, NOT_ALIVE, NOT_ALIVE_NO_WRITERS, NOT_ALIVE_DISPOSED instance: ANY, ALIVE, NOT_ALIVE, NOT_ALIVE_NO_WRITERS, NOT_ALIVE_DISPOSED
*/ */
static unsigned qmask_of_inst (const struct rhc_instance *inst) static uint32_t qmask_of_inst (const struct rhc_instance *inst)
{ {
unsigned qm = inst->isnew ? DDS_NEW_VIEW_STATE : DDS_NOT_NEW_VIEW_STATE; uint32_t qm = inst->isnew ? DDS_NEW_VIEW_STATE : DDS_NOT_NEW_VIEW_STATE;
if (inst->isdisposed) if (inst->isdisposed)
qm |= DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE; qm |= DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE;
@ -1905,9 +1905,9 @@ static uint32_t qmask_from_dcpsquery (uint32_t sample_states, uint32_t view_stat
return qminv; return qminv;
} }
static unsigned qmask_from_mask_n_cond (uint32_t mask, dds_readcond* cond) static uint32_t qmask_from_mask_n_cond (uint32_t mask, dds_readcond* cond)
{ {
unsigned qminv; uint32_t qminv;
if (mask == NO_STATE_MASK_SET) { if (mask == NO_STATE_MASK_SET) {
if (cond) { if (cond) {
/* No mask set, use the one from the condition. */ /* No mask set, use the one from the condition. */
@ -1962,12 +1962,11 @@ static void patch_generations (dds_sample_info_t *si, uint32_t last_of_inst)
{ {
if (last_of_inst > 0) if (last_of_inst > 0)
{ {
const unsigned ref = const uint32_t ref =
si[last_of_inst].disposed_generation_count + si[last_of_inst].no_writers_generation_count; si[last_of_inst].disposed_generation_count + si[last_of_inst].no_writers_generation_count;
uint32_t i;
assert (si[last_of_inst].sample_rank == 0); assert (si[last_of_inst].sample_rank == 0);
assert (si[last_of_inst].generation_rank == 0); assert (si[last_of_inst].generation_rank == 0);
for (i = 0; i < last_of_inst; i++) for (uint32_t i = 0; i < last_of_inst; i++)
{ {
si[i].sample_rank = last_of_inst - i; si[i].sample_rank = last_of_inst - i;
si[i].generation_rank = ref - (si[i].disposed_generation_count + si[i].no_writers_generation_count); si[i].generation_rank = ref - (si[i].disposed_generation_count + si[i].no_writers_generation_count);
@ -2014,51 +2013,60 @@ static bool take_sample_update_conditions (struct dds_rhc_default *rhc, struct t
return false; return false;
} }
static int dds_rhc_read_w_qminv (struct dds_rhc_default *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, unsigned qminv, dds_instance_handle_t handle, dds_readcond *cond) typedef bool (*read_take_to_sample_t) (const struct ddsi_serdata * __restrict d, void *__restrict *__restrict sample, void * __restrict * __restrict bufptr, void * __restrict buflim);
{ typedef bool (*read_take_to_invsample_t) (const struct ddsi_sertopic * __restrict topic, const struct ddsi_serdata * __restrict d, void *__restrict * __restrict sample, void * __restrict * __restrict bufptr, void * __restrict buflim);
uint32_t n = 0;
if (lock) static bool read_take_to_sample (const struct ddsi_serdata * __restrict d, void * __restrict * __restrict sample, void * __restrict * __restrict bufptr, void * __restrict buflim)
{ {
ddsrt_mutex_lock (&rhc->lock); return ddsi_serdata_to_sample (d, *sample, (void **) bufptr, buflim);
} }
TRACE ("read_w_qminv(%p,%p,%p,%"PRIu32",%x,%p) - inst %"PRIu32" nonempty %"PRIu32" disp %"PRIu32" nowr %"PRIu32" new %"PRIu32" samples %"PRIu32"+%"PRIu32" read %"PRIu32"+%"PRIu32"\n", static bool read_take_to_invsample (const struct ddsi_sertopic * __restrict topic, const struct ddsi_serdata * __restrict d, void * __restrict * __restrict sample, void * __restrict * __restrict bufptr, void * __restrict buflim)
(void *) rhc, (void *) values, (void *) info_seq, max_samples, qminv, (void *) cond, {
rhc->n_instances, rhc->n_nonempty_instances, rhc->n_not_alive_disposed, return topicless_to_clean_invsample (topic, d, *sample, (void **) bufptr, buflim);
rhc->n_not_alive_no_writers, rhc->n_new, rhc->n_vsamples, rhc->n_invsamples, }
rhc->n_vread, rhc->n_invread);
if (!ddsrt_circlist_isempty (&rhc->nonempty_instances)) static bool read_take_to_sample_ref (const struct ddsi_serdata * __restrict d, void * __restrict * __restrict sample, void * __restrict * __restrict bufptr, void * __restrict buflim)
{ {
const dds_querycond_mask_t qcmask = (cond && cond->m_query.m_filter) ? cond->m_query.m_qcmask : 0; (void) bufptr; (void) buflim;
struct rhc_instance * inst = oldest_nonempty_instance (rhc); *sample = ddsi_serdata_ref (d);
struct rhc_instance * const end = inst; return true;
do }
static bool read_take_to_invsample_ref (const struct ddsi_sertopic * __restrict topic, const struct ddsi_serdata * __restrict d, void * __restrict * __restrict sample, void * __restrict * __restrict bufptr, void * __restrict buflim)
{ {
if (handle == DDS_HANDLE_NIL || inst->iid == handle) (void) topic; (void) bufptr; (void) buflim;
*sample = ddsi_serdata_ref (d);
return true;
}
static int32_t read_w_qminv_inst (struct dds_rhc_default * const __restrict rhc, struct rhc_instance * const __restrict inst, void * __restrict * __restrict values, dds_sample_info_t * __restrict info_seq, const int32_t max_samples, const uint32_t qminv, const dds_querycond_mask_t qcmask, read_take_to_sample_t to_sample, read_take_to_invsample_t to_invsample)
{ {
if (!inst_is_empty (inst) && (qmask_of_inst (inst) & qminv) == 0) assert (max_samples > 0);
if (inst_is_empty (inst) || (qmask_of_inst (inst) & qminv) != 0)
{ {
/* samples present & instance, view state matches */ /* no samples present, or the instance/view state doesn't match */
return 0;
}
struct trigger_info_pre pre; struct trigger_info_pre pre;
struct trigger_info_post post; struct trigger_info_post post;
struct trigger_info_qcond trig_qc; struct trigger_info_qcond trig_qc;
const unsigned nread = inst_nread (inst); const uint32_t nread = inst_nread (inst);
const uint32_t n_first = n; int32_t n = 0;
get_trigger_info_pre (&pre, inst); get_trigger_info_pre (&pre, inst);
init_trigger_info_qcond (&trig_qc); init_trigger_info_qcond (&trig_qc);
/* any valid samples precede a possible invalid sample */
if (inst->latest) if (inst->latest)
{ {
struct rhc_sample *sample = inst->latest->next, * const end1 = sample; struct rhc_sample *sample = inst->latest->next, * const end1 = sample;
do do {
{
if ((qmask_of_sample (sample) & qminv) == 0 && (qcmask == 0 || (sample->conds & qcmask))) if ((qmask_of_sample (sample) & qminv) == 0 && (qcmask == 0 || (sample->conds & qcmask)))
{ {
/* sample state matches too */ /* sample state matches too */
set_sample_info (info_seq + n, inst, sample); set_sample_info (info_seq + n, inst, sample);
ddsi_serdata_to_sample (sample->sample, values[n], 0, 0); to_sample (sample->sample, values + n, 0, 0);
if (!sample->isread) if (!sample->isread)
{ {
TRACE ("s"); TRACE ("s");
@ -2067,20 +2075,17 @@ static int dds_rhc_read_w_qminv (struct dds_rhc_default *rhc, bool lock, void **
inst->nvread++; inst->nvread++;
rhc->n_vread++; rhc->n_vread++;
} }
if (++n == max_samples) ++n;
{
break;
}
} }
sample = sample->next; sample = sample->next;
} } while (n < max_samples && sample != end1);
while (sample != end1);
} }
/* add an invalid sample if it exists, matches and there is room in the result */
if (inst->inv_exists && n < max_samples && (qmask_of_invsample (inst) & qminv) == 0 && (qcmask == 0 || (inst->conds & qcmask))) if (inst->inv_exists && n < max_samples && (qmask_of_invsample (inst) & qminv) == 0 && (qcmask == 0 || (inst->conds & qcmask)))
{ {
set_sample_info_invsample (info_seq + n, inst); set_sample_info_invsample (info_seq + n, inst);
topicless_to_clean_invsample (rhc->topic, inst->tk->m_sample, values[n], 0, 0); to_invsample (rhc->topic, inst->tk->m_sample, values + n, 0, 0);
if (!inst->inv_isread) if (!inst->inv_isread)
{ {
TRACE ("i"); TRACE ("i");
@ -2091,13 +2096,18 @@ static int dds_rhc_read_w_qminv (struct dds_rhc_default *rhc, bool lock, void **
++n; ++n;
} }
/* set generation counts in sample info now that we can compute them; update instance state */
bool inst_became_old = false; bool inst_became_old = false;
if (n > n_first && inst->isnew) if (n > 0)
{
patch_generations (info_seq, (uint32_t) n - 1);
if (inst->isnew)
{ {
inst_became_old = true; inst_became_old = true;
inst->isnew = 0; inst->isnew = 0;
rhc->n_new--; rhc->n_new--;
} }
}
if (nread != inst_nread (inst) || inst_became_old) if (nread != inst_nread (inst) || inst_became_old)
{ {
size_t ntriggers = SIZE_MAX; size_t ntriggers = SIZE_MAX;
@ -2108,62 +2118,22 @@ static int dds_rhc_read_w_qminv (struct dds_rhc_default *rhc, bool lock, void **
assert (trig_qc.inc_conds_sample == 0); assert (trig_qc.inc_conds_sample == 0);
update_conditions_locked (rhc, false, &pre, &post, &trig_qc, inst, NULL, &ntriggers); update_conditions_locked (rhc, false, &pre, &post, &trig_qc, inst, NULL, &ntriggers);
} }
return n;
if (n > n_first) {
patch_generations (info_seq + n_first, n - n_first - 1);
}
}
if (inst->iid == handle)
{
break;
}
}
inst = next_nonempty_instance (inst);
}
while (inst != end && n < max_samples);
}
TRACE ("read: returning %"PRIu32"\n", n);
assert (rhc_check_counts_locked (rhc, true, false));
ddsrt_mutex_unlock (&rhc->lock);
assert (n <= INT_MAX);
return (int)n;
} }
static int dds_rhc_take_w_qminv (struct dds_rhc_default *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, unsigned qminv, dds_instance_handle_t handle, dds_readcond *cond) static int32_t take_w_qminv_inst (struct dds_rhc_default * const __restrict rhc, struct rhc_instance * const __restrict inst, void * __restrict * __restrict values, dds_sample_info_t * __restrict info_seq, const int32_t max_samples, const uint32_t qminv, const dds_querycond_mask_t qcmask, size_t * __restrict ntriggers, read_take_to_sample_t to_sample, read_take_to_invsample_t to_invsample)
{ {
uint64_t iid; assert (max_samples > 0);
uint32_t n = 0; if (inst_is_empty (inst) || (qmask_of_inst (inst) & qminv) != 0)
size_t ntriggers = SIZE_MAX;
if (lock)
{ {
ddsrt_mutex_lock (&rhc->lock); /* no samples present, or the instance/view state doesn't match */
return 0;
} }
TRACE ("take_w_qminv(%p,%p,%p,%"PRIu32",%x) - inst %"PRIu32" nonempty %"PRIu32" disp %"PRIu32" nowr %"PRIu32" new %"PRIu32" samples %"PRIu32"+%"PRIu32" read %"PRIu32"+%"PRIu32"\n",
(void*) rhc, (void*) values, (void*) info_seq, max_samples, qminv,
rhc->n_instances, rhc->n_nonempty_instances, rhc->n_not_alive_disposed,
rhc->n_not_alive_no_writers, rhc->n_new, rhc->n_vsamples,
rhc->n_invsamples, rhc->n_vread, rhc->n_invread);
if (!ddsrt_circlist_isempty (&rhc->nonempty_instances))
{
const dds_querycond_mask_t qcmask = (cond && cond->m_query.m_filter) ? cond->m_query.m_qcmask : 0;
struct rhc_instance *inst = oldest_nonempty_instance (rhc);
unsigned n_insts = rhc->n_nonempty_instances;
while (n_insts-- > 0 && n < max_samples)
{
struct rhc_instance * const inst1 = next_nonempty_instance (inst);
iid = inst->iid;
if (handle == DDS_HANDLE_NIL || iid == handle)
{
if (!inst_is_empty (inst) && (qmask_of_inst (inst) & qminv) == 0)
{
struct trigger_info_pre pre; struct trigger_info_pre pre;
struct trigger_info_post post; struct trigger_info_post post;
struct trigger_info_qcond trig_qc; struct trigger_info_qcond trig_qc;
unsigned nvsamples = inst->nvsamples; int32_t n = 0;
const uint32_t n_first = n;
get_trigger_info_pre (&pre, inst); get_trigger_info_pre (&pre, inst);
init_trigger_info_qcond (&trig_qc); init_trigger_info_qcond (&trig_qc);
@ -2171,10 +2141,10 @@ static int dds_rhc_take_w_qminv (struct dds_rhc_default *rhc, bool lock, void **
{ {
struct rhc_sample *psample = inst->latest; struct rhc_sample *psample = inst->latest;
struct rhc_sample *sample = psample->next; struct rhc_sample *sample = psample->next;
uint32_t nvsamples = inst->nvsamples;
while (nvsamples--) while (nvsamples--)
{ {
struct rhc_sample * const sample1 = sample->next; struct rhc_sample * const sample1 = sample->next;
if ((qmask_of_sample (sample) & qminv) != 0 || (qcmask != 0 && !(sample->conds & qcmask))) if ((qmask_of_sample (sample) & qminv) != 0 || (qcmask != 0 && !(sample->conds & qcmask)))
{ {
/* sample mask doesn't match, or content predicate doesn't match */ /* sample mask doesn't match, or content predicate doesn't match */
@ -2183,34 +2153,26 @@ static int dds_rhc_take_w_qminv (struct dds_rhc_default *rhc, bool lock, void **
else else
{ {
take_sample_update_conditions (rhc, &pre, &post, &trig_qc, inst, sample->conds, sample->isread); take_sample_update_conditions (rhc, &pre, &post, &trig_qc, inst, sample->conds, sample->isread);
set_sample_info (info_seq + n, inst, sample); set_sample_info (info_seq + n, inst, sample);
ddsi_serdata_to_sample (sample->sample, values[n], 0, 0); to_sample (sample->sample, values + n, 0, 0);
rhc->n_vsamples--; rhc->n_vsamples--;
if (sample->isread) if (sample->isread)
{ {
inst->nvread--; inst->nvread--;
rhc->n_vread--; rhc->n_vread--;
} }
if (--inst->nvsamples == 0)
if (--inst->nvsamples > 0) inst->latest = NULL;
else
{ {
if (inst->latest == sample) if (inst->latest == sample)
inst->latest = psample; inst->latest = psample;
psample->next = sample1; psample->next = sample1;
} }
else
{
inst->latest = NULL;
}
free_sample (rhc, inst, sample); free_sample (rhc, inst, sample);
if (++n == max_samples) if (++n == max_samples)
{
break; break;
} }
}
sample = sample1; sample = sample1;
} }
} }
@ -2223,40 +2185,36 @@ static int dds_rhc_take_w_qminv (struct dds_rhc_default *rhc, bool lock, void **
#endif #endif
take_sample_update_conditions (rhc, &pre, &post, &trig_qc, inst, inst->conds, inst->inv_isread); take_sample_update_conditions (rhc, &pre, &post, &trig_qc, inst, inst->conds, inst->inv_isread);
set_sample_info_invsample (info_seq + n, inst); set_sample_info_invsample (info_seq + n, inst);
topicless_to_clean_invsample (rhc->topic, inst->tk->m_sample, values[n], 0, 0); to_invsample (rhc->topic, inst->tk->m_sample, values + n, 0, 0);
inst_clear_invsample (rhc, inst, &dummy_trig_qc); inst_clear_invsample (rhc, inst, &dummy_trig_qc);
++n; ++n;
} }
if (n > n_first && inst->isnew) if (n > 0)
{
patch_generations (info_seq, (uint32_t) n - 1);
if (inst->isnew)
{ {
inst->isnew = 0; inst->isnew = 0;
rhc->n_new--; rhc->n_new--;
} }
/* if nsamples = 0, it won't match anything, so no need to do anything here for drop_instance_noupdate_no_writers */
if (n > n_first)
{
/* if nsamples = 0, it won't match anything, so no need to do
anything here for drop_instance_noupdate_no_writers */
get_trigger_info_cmn (&post.c, inst); get_trigger_info_cmn (&post.c, inst);
assert (trig_qc.dec_conds_invsample == 0); assert (trig_qc.dec_conds_invsample == 0);
assert (trig_qc.dec_conds_sample == 0); assert (trig_qc.dec_conds_sample == 0);
assert (trig_qc.inc_conds_invsample == 0); assert (trig_qc.inc_conds_invsample == 0);
assert (trig_qc.inc_conds_sample == 0); assert (trig_qc.inc_conds_sample == 0);
update_conditions_locked (rhc, false, &pre, &post, &trig_qc, inst, NULL, &ntriggers); update_conditions_locked (rhc, false, &pre, &post, &trig_qc, inst, NULL, ntriggers);
} }
if (inst_is_empty (inst)) if (inst_is_empty (inst))
{ {
remove_inst_from_nonempty_list (rhc, inst); remove_inst_from_nonempty_list (rhc, inst);
if (inst->isdisposed) if (inst->isdisposed)
{
rhc->n_not_alive_disposed--; rhc->n_not_alive_disposed--;
}
if (inst->wrcount == 0) if (inst->wrcount == 0)
{ {
TRACE ("take: iid %"PRIx64" #0,empty,drop\n", iid); TRACE ("take: iid %"PRIx64" #0,empty,drop\n", inst->iid);
if (!inst->isdisposed) if (!inst->isdisposed)
{ {
/* disposed has priority over no writers (why not just 2 bits?) */ /* disposed has priority over no writers (why not just 2 bits?) */
@ -2265,167 +2223,119 @@ static int dds_rhc_take_w_qminv (struct dds_rhc_default *rhc, bool lock, void **
drop_instance_noupdate_no_writers (rhc, inst); drop_instance_noupdate_no_writers (rhc, inst);
} }
} }
return n;
if (n > n_first)
patch_generations (info_seq + n_first, n - n_first - 1);
} }
if (iid == handle)
static int32_t read_w_qminv (struct dds_rhc_default * __restrict rhc, bool lock, void * __restrict * __restrict values, dds_sample_info_t * __restrict info_seq, int32_t max_samples, uint32_t qminv, dds_instance_handle_t handle, dds_readcond * __restrict cond, read_take_to_sample_t to_sample, read_take_to_invsample_t to_invsample)
{ {
break; int32_t n = 0;
} assert (max_samples > 0);
}
inst = inst1;
}
}
TRACE ("take: returning %"PRIu32"\n", n);
assert (rhc_check_counts_locked (rhc, true, false));
ddsrt_mutex_unlock (&rhc->lock);
assert (n <= INT_MAX);
return (int)n;
}
static int dds_rhc_takecdr_w_qminv (struct dds_rhc_default *rhc, bool lock, struct ddsi_serdata ** values, dds_sample_info_t *info_seq, uint32_t max_samples, unsigned qminv, dds_instance_handle_t handle, dds_readcond *cond)
{
uint64_t iid;
uint32_t n = 0;
(void)cond;
if (lock) if (lock)
{ {
ddsrt_mutex_lock (&rhc->lock); ddsrt_mutex_lock (&rhc->lock);
} }
TRACE ("take_w_qminv(%p,%p,%p,%"PRIu32",%x) - inst %"PRIu32" nonempty %"PRIu32" disp %"PRIu32" nowr %"PRIu32" new %"PRIu32" samples %"PRIu32"+%"PRIu32" read %"PRIu32"+%"PRIu32"\n", TRACE ("read_w_qminv(%p,%p,%p,%"PRId32",%x,%"PRIx64",%p) - inst %"PRIu32" nonempty %"PRIu32" disp %"PRIu32" nowr %"PRIu32" new %"PRIu32" samples %"PRIu32"+%"PRIu32" read %"PRIu32"+%"PRIu32"\n",
(void*) rhc, (void*) values, (void*) info_seq, max_samples, qminv, (void *) rhc, (void *) values, (void *) info_seq, max_samples, qminv, handle, (void *) cond,
rhc->n_instances, rhc->n_nonempty_instances, rhc->n_not_alive_disposed,
rhc->n_not_alive_no_writers, rhc->n_new, rhc->n_vsamples, rhc->n_invsamples,
rhc->n_vread, rhc->n_invread);
const dds_querycond_mask_t qcmask = (cond && cond->m_query.m_filter) ? cond->m_query.m_qcmask : 0;
if (handle)
{
struct rhc_instance template, *inst;
template.iid = handle;
if ((inst = ddsrt_hh_lookup (rhc->instances, &template)) != NULL)
n = read_w_qminv_inst (rhc, inst, values, info_seq, max_samples, qminv, qcmask, to_sample, to_invsample);
else
n = DDS_RETCODE_PRECONDITION_NOT_MET;
}
else if (!ddsrt_circlist_isempty (&rhc->nonempty_instances))
{
struct rhc_instance * inst = oldest_nonempty_instance (rhc);
struct rhc_instance * const end = inst;
do {
n += read_w_qminv_inst(rhc, inst, values + n, info_seq + n, max_samples - n, qminv, qcmask, to_sample, to_invsample);
inst = next_nonempty_instance (inst);
} while (inst != end && n < max_samples);
}
TRACE ("read: returning %"PRIu32"\n", n);
assert (rhc_check_counts_locked (rhc, true, false));
// FIXME: conditional "lock" plus unconditional "unlock" is inexcusably bad design
// It appears to have been introduced at some point so another language binding could lock
// the RHC using dds_rhc_default_lock_samples to find out the number of samples present,
// then allocate stuff and call read/take with lock=true. All that needs fixing.
ddsrt_mutex_unlock (&rhc->lock);
return n;
}
static int32_t take_w_qminv (struct dds_rhc_default * __restrict rhc, bool lock, void * __restrict * __restrict values, dds_sample_info_t * __restrict info_seq, int32_t max_samples, uint32_t qminv, dds_instance_handle_t handle, dds_readcond * __restrict cond, read_take_to_sample_t to_sample, read_take_to_invsample_t to_invsample)
{
int32_t n = 0;
size_t ntriggers = SIZE_MAX;
assert (max_samples > 0);
if (lock)
{
ddsrt_mutex_lock (&rhc->lock);
}
TRACE ("take_w_qminv(%p,%p,%p,%"PRId32",%x,%"PRIx64",%p) - inst %"PRIu32" nonempty %"PRIu32" disp %"PRIu32" nowr %"PRIu32" new %"PRIu32" samples %"PRIu32"+%"PRIu32" read %"PRIu32"+%"PRIu32"\n",
(void*) rhc, (void*) values, (void*) info_seq, max_samples, qminv, handle, (void *) cond,
rhc->n_instances, rhc->n_nonempty_instances, rhc->n_not_alive_disposed, rhc->n_instances, rhc->n_nonempty_instances, rhc->n_not_alive_disposed,
rhc->n_not_alive_no_writers, rhc->n_new, rhc->n_vsamples, rhc->n_not_alive_no_writers, rhc->n_new, rhc->n_vsamples,
rhc->n_invsamples, rhc->n_vread, rhc->n_invread); rhc->n_invsamples, rhc->n_vread, rhc->n_invread);
if (!ddsrt_circlist_isempty (&rhc->nonempty_instances))
{
const dds_querycond_mask_t qcmask = (cond && cond->m_query.m_filter) ? cond->m_query.m_qcmask : 0; const dds_querycond_mask_t qcmask = (cond && cond->m_query.m_filter) ? cond->m_query.m_qcmask : 0;
if (handle)
{
struct rhc_instance template, *inst;
template.iid = handle;
if ((inst = ddsrt_hh_lookup (rhc->instances, &template)) != NULL)
n = take_w_qminv_inst (rhc, inst, values, info_seq, max_samples, qminv, qcmask, &ntriggers, to_sample, to_invsample);
else
n = DDS_RETCODE_PRECONDITION_NOT_MET;
}
else if (!ddsrt_circlist_isempty (&rhc->nonempty_instances))
{
struct rhc_instance *inst = oldest_nonempty_instance (rhc); struct rhc_instance *inst = oldest_nonempty_instance (rhc);
unsigned n_insts = rhc->n_nonempty_instances; uint32_t n_insts = rhc->n_nonempty_instances;
while (n_insts-- > 0 && n < max_samples) while (n_insts-- > 0 && n < max_samples)
{ {
struct rhc_instance * const inst1 = next_nonempty_instance (inst); struct rhc_instance * const inst1 = next_nonempty_instance (inst);
iid = inst->iid; n += take_w_qminv_inst (rhc, inst, values + n, info_seq + n, max_samples - n, qminv, qcmask, &ntriggers, to_sample, to_invsample);
if (handle == DDS_HANDLE_NIL || iid == handle)
{
if (!inst_is_empty (inst) && (qmask_of_inst (inst) & qminv) == 0)
{
struct trigger_info_pre pre;
struct trigger_info_post post;
struct trigger_info_qcond trig_qc;
unsigned nvsamples = inst->nvsamples;
const uint32_t n_first = n;
get_trigger_info_pre (&pre, inst);
init_trigger_info_qcond (&trig_qc);
if (inst->latest)
{
struct rhc_sample *psample = inst->latest;
struct rhc_sample *sample = psample->next;
while (nvsamples--)
{
struct rhc_sample * const sample1 = sample->next;
if ((qmask_of_sample (sample) & qminv) != 0 || (qcmask && !(sample->conds & qcmask)))
{
psample = sample;
}
else
{
take_sample_update_conditions (rhc, &pre, &post, &trig_qc, inst, sample->conds, sample->isread);
set_sample_info (info_seq + n, inst, sample);
values[n] = ddsi_serdata_ref(sample->sample);
rhc->n_vsamples--;
if (sample->isread)
{
inst->nvread--;
rhc->n_vread--;
}
if (--inst->nvsamples > 0)
psample->next = sample1;
else
inst->latest = NULL;
free_sample (rhc, inst, sample);
if (++n == max_samples)
{
break;
}
}
sample = sample1;
}
}
if (inst->inv_exists && n < max_samples && (qmask_of_invsample (inst) & qminv) == 0 && (qcmask == 0 || (inst->conds & qcmask) != 0))
{
struct trigger_info_qcond dummy_trig_qc;
#ifndef NDEBUG
init_trigger_info_qcond (&dummy_trig_qc);
#endif
take_sample_update_conditions (rhc, &pre, &post, &trig_qc, inst, inst->conds, inst->inv_isread);
set_sample_info_invsample (info_seq + n, inst);
values[n] = ddsi_serdata_ref(inst->tk->m_sample);
inst_clear_invsample (rhc, inst, &dummy_trig_qc);
++n;
}
if (n > n_first && inst->isnew)
{
inst->isnew = 0;
rhc->n_new--;
}
if (n > n_first)
{
/* if nsamples = 0, it won't match anything, so no need to do
anything here for drop_instance_noupdate_no_writers */
size_t ntriggers = SIZE_MAX;
get_trigger_info_cmn (&post.c, inst);
update_conditions_locked (rhc, false, &pre, &post, &trig_qc, inst, NULL, &ntriggers);
}
if (inst_is_empty (inst))
{
remove_inst_from_nonempty_list (rhc, inst);
if (inst->isdisposed)
{
rhc->n_not_alive_disposed--;
}
if (inst->wrcount == 0)
{
TRACE ("take: iid %"PRIx64" #0,empty,drop\n", iid);
if (!inst->isdisposed)
{
/* disposed has priority over no writers (why not just 2 bits?) */
rhc->n_not_alive_no_writers--;
}
drop_instance_noupdate_no_writers (rhc, inst);
}
}
if (n > n_first)
patch_generations (info_seq + n_first, n - n_first - 1);
}
if (iid == handle)
{
break;
}
}
inst = inst1; inst = inst1;
} }
} }
TRACE ("take: returning %"PRIu32"\n", n); TRACE ("take: returning %"PRIu32"\n", n);
assert (rhc_check_counts_locked (rhc, true, false)); assert (rhc_check_counts_locked (rhc, true, false));
// FIXME: conditional "lock" plus unconditional "unlock" is inexcusably bad design
// It appears to have been introduced at some point so another language binding could lock
// the RHC using dds_rhc_default_lock_samples to find out the number of samples present,
// then allocate stuff and call read/take with lock=true. All that needs fixing.
ddsrt_mutex_unlock (&rhc->lock); ddsrt_mutex_unlock (&rhc->lock);
assert (n <= INT_MAX); return n;
return (int)n; }
static int32_t dds_rhc_read_w_qminv (struct dds_rhc_default *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t qminv, dds_instance_handle_t handle, dds_readcond *cond)
{
assert (max_samples <= INT32_MAX);
return read_w_qminv (rhc, lock, values, info_seq, (int32_t) max_samples, qminv, handle, cond, read_take_to_sample, read_take_to_invsample);
}
static int32_t dds_rhc_take_w_qminv (struct dds_rhc_default *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t qminv, dds_instance_handle_t handle, dds_readcond *cond)
{
assert (max_samples <= INT32_MAX);
return take_w_qminv (rhc, lock, values, info_seq, (int32_t) max_samples, qminv, handle, cond, read_take_to_sample, read_take_to_invsample);
}
static int32_t dds_rhc_takecdr_w_qminv (struct dds_rhc_default *rhc, bool lock, struct ddsi_serdata **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t qminv, dds_instance_handle_t handle, dds_readcond *cond)
{
DDSRT_STATIC_ASSERT (sizeof (void *) == sizeof (struct ddsi_serdata *));
assert (max_samples <= INT32_MAX);
return take_w_qminv (rhc, lock, (void **) values, info_seq, (int32_t) max_samples, qminv, handle, cond, read_take_to_sample_ref, read_take_to_invsample_ref);
} }
/************************* /*************************
@ -2805,21 +2715,21 @@ static bool update_conditions_locked (struct dds_rhc_default *rhc, bool called_f
****** READ/TAKE ****** ****** READ/TAKE ******
*************************/ *************************/
static int dds_rhc_default_read (struct dds_rhc_default *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, dds_readcond *cond) static int32_t dds_rhc_default_read (struct dds_rhc_default *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, dds_readcond *cond)
{ {
unsigned qminv = qmask_from_mask_n_cond (mask, cond); uint32_t qminv = qmask_from_mask_n_cond (mask, cond);
return dds_rhc_read_w_qminv (rhc, lock, values, info_seq, max_samples, qminv, handle, cond); return dds_rhc_read_w_qminv (rhc, lock, values, info_seq, max_samples, qminv, handle, cond);
} }
static int dds_rhc_default_take (struct dds_rhc_default *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, dds_readcond *cond) static int32_t dds_rhc_default_take (struct dds_rhc_default *rhc, bool lock, void **values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t mask, dds_instance_handle_t handle, dds_readcond *cond)
{ {
unsigned qminv = qmask_from_mask_n_cond(mask, cond); uint32_t qminv = qmask_from_mask_n_cond(mask, cond);
return dds_rhc_take_w_qminv (rhc, lock, values, info_seq, max_samples, qminv, handle, cond); return dds_rhc_take_w_qminv (rhc, lock, values, info_seq, max_samples, qminv, handle, cond);
} }
static int dds_rhc_default_takecdr (struct dds_rhc_default *rhc, bool lock, struct ddsi_serdata ** values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t sample_states, uint32_t view_states, uint32_t instance_states, dds_instance_handle_t handle) static int32_t dds_rhc_default_takecdr (struct dds_rhc_default *rhc, bool lock, struct ddsi_serdata ** values, dds_sample_info_t *info_seq, uint32_t max_samples, uint32_t sample_states, uint32_t view_states, uint32_t instance_states, dds_instance_handle_t handle)
{ {
unsigned qminv = qmask_from_dcpsquery (sample_states, view_states, instance_states); uint32_t qminv = qmask_from_dcpsquery (sample_states, view_states, instance_states);
return dds_rhc_takecdr_w_qminv (rhc, lock, values, info_seq, max_samples, qminv, handle, NULL); return dds_rhc_takecdr_w_qminv (rhc, lock, values, info_seq, max_samples, qminv, handle, NULL);
} }
@ -2835,11 +2745,11 @@ static int rhc_check_counts_locked (struct dds_rhc_default *rhc, bool check_cond
return 1; return 1;
const uint32_t ncheck = rhc->nconds < CHECK_MAX_CONDS ? rhc->nconds : CHECK_MAX_CONDS; const uint32_t ncheck = rhc->nconds < CHECK_MAX_CONDS ? rhc->nconds : CHECK_MAX_CONDS;
unsigned n_instances = 0, n_nonempty_instances = 0; uint32_t n_instances = 0, n_nonempty_instances = 0;
unsigned n_not_alive_disposed = 0, n_not_alive_no_writers = 0, n_new = 0; uint32_t n_not_alive_disposed = 0, n_not_alive_no_writers = 0, n_new = 0;
unsigned n_vsamples = 0, n_vread = 0; uint32_t n_vsamples = 0, n_vread = 0;
unsigned n_invsamples = 0, n_invread = 0; uint32_t n_invsamples = 0, n_invread = 0;
unsigned cond_match_count[CHECK_MAX_CONDS]; uint32_t cond_match_count[CHECK_MAX_CONDS];
dds_querycond_mask_t enabled_qcmask = 0; dds_querycond_mask_t enabled_qcmask = 0;
struct rhc_instance *inst; struct rhc_instance *inst;
struct ddsrt_hh_iter iter; struct ddsrt_hh_iter iter;
@ -2860,7 +2770,7 @@ static int rhc_check_counts_locked (struct dds_rhc_default *rhc, bool check_cond
for (inst = ddsrt_hh_iter_first (rhc->instances, &iter); inst; inst = ddsrt_hh_iter_next (&iter)) for (inst = ddsrt_hh_iter_first (rhc->instances, &iter); inst; inst = ddsrt_hh_iter_next (&iter))
{ {
unsigned n_vsamples_in_instance = 0, n_read_vsamples_in_instance = 0; uint32_t n_vsamples_in_instance = 0, n_read_vsamples_in_instance = 0;
bool a_sample_free = true; bool a_sample_free = true;
n_instances++; n_instances++;