From e2ada4d0d6ae99d4a6cf7617e6fa21f1d1023b04 Mon Sep 17 00:00:00 2001 From: Takashi Mori Date: Tue, 14 Jan 2025 09:32:37 +0900 Subject: [PATCH] fix #36 --- src/hako/data/hako_base_data.hpp | 1 + src/hako/data/hako_pdu_data.hpp | 36 ++++++++++++++++++++++++++++++++ src/hako/hako_asset_impl.cpp | 20 ++++++++++++++++++ src/hako/hako_asset_impl.hpp | 2 ++ src/include/hako_asset.hpp | 2 ++ 5 files changed, 61 insertions(+) diff --git a/src/hako/data/hako_base_data.hpp b/src/hako/data/hako_base_data.hpp index c2abe2f..4e35f41 100644 --- a/src/hako/data/hako_base_data.hpp +++ b/src/hako/data/hako_base_data.hpp @@ -71,6 +71,7 @@ namespace hako::data { int32_t channel_num; bool is_dirty[HAKO_PDU_CHANNEL_MAX]; bool is_rbusy[HAKO_DATA_MAX_ASSET_NUM][HAKO_PDU_CHANNEL_MAX]; + bool is_rbusy_for_external[HAKO_PDU_CHANNEL_MAX]; bool is_wbusy[HAKO_PDU_CHANNEL_MAX]; HakoPduChannelType channel[HAKO_PDU_CHANNEL_MAX]; diff --git a/src/hako/data/hako_pdu_data.hpp b/src/hako/data/hako_pdu_data.hpp index 0a9c814..7b05933 100644 --- a/src/hako/data/hako_pdu_data.hpp +++ b/src/hako/data/hako_pdu_data.hpp @@ -120,6 +120,9 @@ namespace hako::data { bool is_pdu_rbusy(HakoPduChannelIdType channel_id) { bool ret = false; + if (this->pdu_meta_data_->is_rbusy_for_external[channel_id]) { + return true; + } for (int i = 0; i < HAKO_DATA_MAX_ASSET_NUM; i++) { if (this->pdu_meta_data_->is_rbusy[i][channel_id]) { ret = true; @@ -136,6 +139,10 @@ namespace hako::data { { this->pdu_meta_data_->is_rbusy[asset_id][channel_id] = busy_status; } + void set_pdu_rbusy_status_for_external(HakoPduChannelIdType channel_id, bool busy_status) + { + this->pdu_meta_data_->is_rbusy_for_external[channel_id] = busy_status; + } /* * writers: only one! */ @@ -198,6 +205,35 @@ namespace hako::data { this->set_pdu_rbusy_status(asset_id, channel_id, false); return true; } + bool read_pdu_for_external(HakoPduChannelIdType channel_id, char *pdu_data, size_t len) + { + if (channel_id >= HAKO_PDU_CHANNEL_MAX) { + HAKO_LOG_ERROR("channel_id >= MAX(%d) channel_id = %d len = %d", HAKO_PDU_CHANNEL_MAX, channel_id, len); + return false; + } + else if (len > this->pdu_meta_data_->channel[channel_id].size) { + HAKO_LOG_ERROR("len > channel_size(%d) channel_id = %d len = %d", this->pdu_meta_data_->channel[channel_id].size, channel_id, len); + return false; + } + else if (this->pdu_ == nullptr) { + this->load(); + } + //READER wait until WRITER has done with rbusy flag=false + //in order to avoid deadlock situation for waiting each other... + while (true) { + this->set_pdu_rbusy_status_for_external(channel_id, true); + if (this->is_pdu_wbusy(channel_id)) { + this->set_pdu_rbusy_status_for_external(channel_id, false); + //usleep(1000); /* 1msec sleep */ + continue; + } + break; + } + int off = this->pdu_meta_data_->channel[channel_id].offset; + memcpy(pdu_data, &this->pdu_[off], len); + this->set_pdu_rbusy_status_for_external(channel_id, false); + return true; + } bool read_pdu_nolock(HakoPduChannelIdType channel_id, char *pdu_data, size_t len) { if (channel_id >= HAKO_PDU_CHANNEL_MAX) { diff --git a/src/hako/hako_asset_impl.cpp b/src/hako/hako_asset_impl.cpp index e6075db..5cec1c8 100644 --- a/src/hako/hako_asset_impl.cpp +++ b/src/hako/hako_asset_impl.cpp @@ -167,6 +167,16 @@ bool hako::HakoAssetControllerImpl::write_pdu(const std::string& asset_name, con return this->master_data_->get_pdu_data()->write_pdu(channel_id, pdu_data, len); } } +bool hako::HakoAssetControllerImpl::write_pdu_for_external(const std::string& robo_name, HakoPduChannelIdType channel_id, const char *pdu_data, size_t len) +{ + HakoPduChannelIdType real_id = this->master_data_->get_pdu_data()->get_pdu_channel(robo_name, channel_id); + if (real_id >= 0) { + return this->master_data_->get_pdu_data()->write_pdu(real_id, pdu_data, len); + } + else { + return this->master_data_->get_pdu_data()->write_pdu(channel_id, pdu_data, len); + } +} bool hako::HakoAssetControllerImpl::read_pdu(const std::string& asset_name, const std::string& robo_name, HakoPduChannelIdType channel_id, char *pdu_data, size_t len) { @@ -183,6 +193,16 @@ bool hako::HakoAssetControllerImpl::read_pdu(const std::string& asset_name, cons return this->master_data_->get_pdu_data()->read_pdu(asset->id, channel_id, pdu_data, len); } } +bool hako::HakoAssetControllerImpl::read_pdu_for_external(const std::string& robo_name, HakoPduChannelIdType channel_id, char *pdu_data, size_t len) +{ + HakoPduChannelIdType real_id = this->master_data_->get_pdu_data()->get_pdu_channel(robo_name, channel_id); + if (real_id >= 0) { + return this->master_data_->get_pdu_data()->read_pdu_for_external(real_id, pdu_data, len); + } + else { + return this->master_data_->get_pdu_data()->read_pdu_for_external(channel_id, pdu_data, len); + } +} bool hako::HakoAssetControllerImpl::write_pdu_nolock(const std::string& robo_name, HakoPduChannelIdType channel_id, const char *pdu_data, size_t len) { HakoPduChannelIdType real_id = this->master_data_->get_pdu_data()->get_pdu_channel(robo_name, channel_id); diff --git a/src/hako/hako_asset_impl.hpp b/src/hako/hako_asset_impl.hpp index 1800959..193fdc8 100644 --- a/src/hako/hako_asset_impl.hpp +++ b/src/hako/hako_asset_impl.hpp @@ -41,7 +41,9 @@ namespace hako { HakoPduChannelIdType get_pdu_channel(const std::string& robo_name, HakoPduChannelIdType channel_id); bool is_pdu_dirty(const std::string& asset_name, const std::string& robo_name, HakoPduChannelIdType channel_id); bool write_pdu(const std::string& asset_name, const std::string& robo_name, HakoPduChannelIdType channel_id, const char *pdu_data, size_t len); + bool write_pdu_for_external(const std::string& robo_name, HakoPduChannelIdType channel_id, const char *pdu_data, size_t len); bool read_pdu(const std::string& asset_name, const std::string& robo_name, HakoPduChannelIdType channel_id, char *pdu_data, size_t len); + bool read_pdu_for_external(const std::string& robo_name, HakoPduChannelIdType channel_id, char *pdu_data, size_t len); void notify_read_pdu_done(const std::string& asset_name); void notify_write_pdu_done(const std::string& asset_name); bool is_pdu_sync_mode(const std::string& asset_name); diff --git a/src/include/hako_asset.hpp b/src/include/hako_asset.hpp index f3afc36..696826e 100644 --- a/src/include/hako_asset.hpp +++ b/src/include/hako_asset.hpp @@ -36,7 +36,9 @@ namespace hako { virtual HakoPduChannelIdType get_pdu_channel(const std::string& robo_name, HakoPduChannelIdType channel_id) = 0; virtual bool is_pdu_dirty(const std::string& asset_name, const std::string& robo_name, HakoPduChannelIdType channel_id) = 0; virtual bool write_pdu(const std::string& asset_name, const std::string& robo_name, HakoPduChannelIdType channel_id, const char *pdu_data, size_t len) = 0; + virtual bool write_pdu_for_external(const std::string& robo_name, HakoPduChannelIdType channel_id, const char *pdu_data, size_t len) = 0; virtual bool read_pdu(const std::string& asset_name, const std::string& robo_name, HakoPduChannelIdType channel_id, char *pdu_data, size_t len) = 0; + virtual bool read_pdu_for_external(const std::string& robo_name, HakoPduChannelIdType channel_id, char *pdu_data, size_t len) = 0; virtual void notify_read_pdu_done(const std::string& asset_name) = 0; virtual void notify_write_pdu_done(const std::string& asset_name) = 0; virtual bool is_pdu_sync_mode(const std::string& asset_name) = 0;