diff options
author | ToshikazuOhiwa <toshikazu_ohiwa@mail.toyota.co.jp> | 2020-03-30 09:34:56 +0900 |
---|---|---|
committer | ToshikazuOhiwa <toshikazu_ohiwa@mail.toyota.co.jp> | 2020-03-30 09:34:56 +0900 |
commit | d2f16e50f31f796b952bba80c2a3a5618cce8c21 (patch) | |
tree | 116a810527ff4b7a08ac084bf8c4dad9d250ea1c /event_library | |
parent | 706ad73eb02caf8532deaf5d38995bd258725cb8 (diff) |
os-eventlibrary branch
Diffstat (limited to 'event_library')
-rw-r--r-- | event_library/LICENSE | 177 | ||||
-rw-r--r-- | event_library/Makefile.client | 18 | ||||
-rw-r--r-- | event_library/library/Makefile | 37 | ||||
-rw-r--r-- | event_library/library/include/other_service/ev_lib.h | 1856 | ||||
-rw-r--r-- | event_library/library/include/other_service/event_library.h | 39 | ||||
-rw-r--r-- | event_library/library/libev.ver | 41 | ||||
-rw-r--r-- | event_library/library/src/ev_lib.c | 1551 |
7 files changed, 3719 insertions, 0 deletions
diff --git a/event_library/LICENSE b/event_library/LICENSE new file mode 100644 index 00000000..f433b1a5 --- /dev/null +++ b/event_library/LICENSE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/event_library/Makefile.client b/event_library/Makefile.client new file mode 100644 index 00000000..87153df3 --- /dev/null +++ b/event_library/Makefile.client @@ -0,0 +1,18 @@ +# +# @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +SUBDIRS := library + +include ../other_service.mk diff --git a/event_library/library/Makefile b/event_library/library/Makefile new file mode 100644 index 00000000..cd270f74 --- /dev/null +++ b/event_library/library/Makefile @@ -0,0 +1,37 @@ +# +# @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +INST_SHLIBS = libev +libev_SRCS := src/ev_lib.c +VPATH = ./src ./include/$(COMPONENT_NAME)/ +INST_HEADERS = ev_lib.h event_library.h + +CPPFLAGS = -I./include + +FDLAGS += -Wl,--no-undefined +CPPFLAGS += -Werror=implicit-function-declaration +CPPFLAGS += -Werror=format-security + +CPPFLAGS += -Wconversion +CPPFLAGS += -Wpointer-to-int-cast +CPPFLAGS += -Wint-to-pointer-cast +CPPFLAGS += -Wpointer-arith +CPPFLAGS += -Wformat + +LDFLAGS += -Wl,--no-as-needed +LDLIBS := -lpthread + +include ../../other_service.mk diff --git a/event_library/library/include/other_service/ev_lib.h b/event_library/library/include/other_service/ev_lib.h new file mode 100644 index 00000000..a7da113b --- /dev/null +++ b/event_library/library/include/other_service/ev_lib.h @@ -0,0 +1,1856 @@ +/* + * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file ev_lib.h + * @brief \~english Event library -- API define head file + */ + +#ifndef OTHERSERVICE_EV_LIB_H_ // NOLINT(build/header_guard) +#define OTHERSERVICE_EV_LIB_H_ // NOLINT(build/header_guard) + +#include <agl_types_obsoluted.h> +#include <agldd/ev_common.h> +/** @addtogroup BaseSystem + * @{ + */ +/** @addtogroup other_service + * @ingroup BaseSystem + * @{ + */ +/** @addtogroup event_library + * @ingroup other_service + * @{ + */ + +#ifndef __KERNEL__ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Create/Delete flag and message queue */ +///////////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_create_flag +/// \~english @par Brief +/// Create flag for event flag by the flag_id. +/// \~english @param [in] flag_id +/// EV_ID - Flag ID of the flag event +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid flag_id +/// \~english @retval EV_ERR_Thread_Over The MAX of event thread. +/// \~english @retval EV_ERR_Exist Duplication Error +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// There is no prerequisite +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error (specifying incorrect flag_id) +/// --incorrect flag_id: The ID is not created by function of EV_moduleID_to_flagID(). +/// - EV_ERR_Invalid_ID +/// - Startup thread upper limit (16) error +/// - EV_ERR_Thread_Over +/// - flag_id registered in launch thread +/// - Flag corresponding to flag_id already exists +/// - EV_ERR_Exist +/// - Securing free space of thread information management table (malloc) Failure +/// - Flag pool is NULL +/// - Flag generation corresponding to flag_id failed +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Creates flag with ID specified by the argument. +/// An error occurs if flag of the specified ID already exists. +/// \~english @see evk_open, evk_close, evk_ioctl, evk_create_flag, evk_set_poll +//////////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_create_flag(EV_ID flag_id); // NOLINT (readability/nolint) + +///////////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_create_flag64 +/// \~english @par Brief +/// Create flag for event flag by the flag_id. +/// \~english @param [in] flag_id +/// EV_ID - Flag ID of the flag event +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid flag_id +/// \~english @retval EV_ERR_Thread_Over The MAX of event thread. +/// \~english @retval EV_ERR_Exist Duplication Error +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// There is no prerequisite +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error (specifying incorrect flag_id) +/// --incorrect flag_id: The ID is not created by function of EV_moduleID_to_flag64ID (). +/// - EV_ERR_Invalid_ID +/// - Startup thread upper limit (16) error +/// - EV_ERR_Thread_Over +/// - flag_id registered in launch thread +/// - Flag corresponding to flag_id already exists +/// - EV_ERR_Exist +/// - Securing free space of thread information management table (malloc) Failure +/// - Flag pool is NULL +/// - Flag generation corresponding to flag_id failed +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Creates flag with ID specified by the argument. +/// An error occurs if flag of the specified ID already exists. +/// \~english @see evk_open, evk_close, evk_ioctl, evk_create_flag, evk_set_poll +//////////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_create_flag64(EV_ID flag_id); // NOLINT (readability/nolint) + +///////////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_create_queue +/// \~english @par Brief +/// Create message queue with the queue_id. +/// \~english @param [in] queue_id +/// EV_ID - queue_id of message event +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @param [in] length +/// UINT8 - length of message queue (Maximum accumulated number of the messages) +/// \~english @param [in] max_bytes +/// UINT16 - the maximum number of bytes per 1 message(MAX 2048) +/// \~english @param [in] type +/// EV_Message_Queue_Type - classification of the processing when the queue received more event +/// - in the queue full state. +/// \~english @par +/// EV_Message_Queue_Type +/// \~english @code +/// typedef UINT8 EV_Message_Queue_Type; +/// - EV_MESSAGE_QUEUE_TYPE_BUSY = 0 // Return error(EV_ERR_Busy) to origin of message transmission +/// - EV_MESSAGE_QUEUE_TYPE_FIFO = 1 // Delete the top message of the queue, and shift message +/// // (Delete the oldest message) +/// - EV_MESSAGE_QUEUE_TYPE_REPLACE = 2 // Overwrite the last message of the queue +/// // (Overwrite the newest message) +/// @endcode +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid queue_id +/// \~english @retval EV_ERR_Thread_Over The MAX of event thread. +/// \~english @retval EV_ERR_Exist Duplication Error +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// There is no prerequisite +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error (specifying incorrect queue_id) +/// --incorrect queue_id:The queue_id is not created by function of EV_moduleID_to_queueID (). +/// - EV_ERR_Invalid_ID +/// - Startup thread upper limit (16) error +/// - EV_ERR_Thread_Over +/// - queue_id registered in launch thread +/// - Message queue corresponding to queue_id already exists +/// - EV_ERR_Exist +/// - Securing free space of thread information management table (malloc) Failure +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - Message queue pool is NULL +/// - Message queue generation corresponding to queue_id failed +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Creates message queue with ID specified by the argument. +/// When queue is created, a memory area corresponding to "length" x "max_bytes" is dynamically secured. +/// An error occurs if queue of the specified ID already exists. +/// \~english @see evk_open, evk_close, evk_ioctl, evk_create_message_queue, evk_set_poll +//////////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_create_queue(EV_ID queue_id, // NOLINT (readability/nolint) + UINT8 length, // NOLINT (readability/nolint) + UINT16 max_bytes, // NOLINT (readability/nolint) + EV_Message_Queue_Type type); // NOLINT (readability/nolint) + +///////////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_create_flag_auto_id +/// \~english @par Brief +/// Automatically assign flag ID, and creates flag with flag ID. +/// \~english @param [out] flag_id +/// EV_ID* - flag_id assigned automatically +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Thread_Over The MAX of event thread +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// There is no prerequisite +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Startup thread upper limit (16) error +/// - EV_ERR_Thread_Over +/// - Securing free space of thread information management table (malloc) Failure +/// - Flag pool is NULL +/// - Flag generation corresponding to flag_id failed +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Automatically assign flag ID, and creates flag with flag ID. +/// It is the same as "EV_create_flag" except that flag ID is automatically allocated. +/// \~english @see EV_create_flag, evk_open, evk_close, evk_ioctl, evk_create_flag, evk_alloc_flag_id, evk_set_poll +//////////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_create_flag_auto_id(/* OUT */EV_ID *flag_id); // NOLINT (readability/nolint) + +///////////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_create_flag64_auto_id +/// \~english @par Brief +/// Automatically assign flag ID, and creates flag with flag ID. +/// \~english @param [out] flag_id +/// EV_ID* - flag_id assigned automatically +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Thread_Over The MAX of event thread +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// There is no prerequisite +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Startup thread upper limit (16) error +/// - EV_ERR_Thread_Over +/// - Securing free space of thread information management table (malloc) Failure +/// - Flag pool is NULL +/// - Flag generation corresponding to flag_id failed +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Automatically assign flag ID, and creates flag with flag ID. +/// It is the same as "EV_create_flag" except that flag ID is automatically allocated. +/// \~english @see EV_create_flag, evk_open, evk_close, evk_ioctl, evk_create_flag, evk_alloc_flag_id, evk_set_poll +//////////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_create_flag64_auto_id(/* OUT */EV_ID *flag_id); // NOLINT (readability/nolint) + +///////////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_create_queue_auto_id +/// \~english @par Brief +/// Automatically assign queue ID, and creates message queue with queue ID. +/// It stores queue_id assigned automatically in argument. +/// \~english @param [out] queue_id +/// EV_ID* - queue_id assigned automatically +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @param [in] length +/// UINT8 - length of message queue (Maximum accumulated number of the messages) +/// \~english @param [in] max_bytes +/// UINT16 - the maximum number of bytes per 1 message(MAX 2048) +/// \~english @param [in] type +/// EV_Message_Queue_Type - classification of the processing when the queue received more event +/// in the queue full state. +/// \~english @par +/// EV_Message_Queue_Type +/// \~english @code +/// typedef UINT8 EV_Message_Queue_Type; +/// - EV_MESSAGE_QUEUE_TYPE_BUSY = 0 // Return error(EV_ERR_Busy) to origin of message transmission +/// - EV_MESSAGE_QUEUE_TYPE_FIFO = 1 // Delete the top message of the queue, and shift message +/// // (Delete the oldest message) +/// - EV_MESSAGE_QUEUE_TYPE_REPLACE = 2 // Overwrite the last message of the queue +/// // (Overwrite the newest message) +/// @endcode +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Thread_Over The MAX of event thread +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// There is no prerequisite +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Thread is unregistered and threads started up to the maximum of event thread(16 threads) +/// - EV_ERR_Thread_Over +/// - Message queue corresponding to queue_id already exists +/// - Securing free space of thread information management table (malloc) Failure +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - Message queue pool is NULL +/// - Message queue generation corresponding to queue_id failed +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Automatically assign queue id, and creates message queue with queue id, It stores queue_id +/// assigned automatically in argument. +/// It is the same as "EV_queue_flag" except that queue ID is automatically allocated. +/// \~english @see EV_create_queue, evk_open, evk_close, evk_ioctl, evk_create_message_queue, +/// evk_alloc_queueID, evk_set_poll +//////////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_create_queue_auto_id(/* OUT */EV_ID *queue_id, // NOLINT (readability/nolint) + UINT8 length, // NOLINT (readability/nolint) + UINT16 max_bytes, // NOLINT (readability/nolint) + EV_Message_Queue_Type type); // NOLINT (readability/nolint) + +///////////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_destroy_flag +/// \~english @par Brief +/// Deletes flag with ID specified by the argument. +/// \~english @param [in] flag_id +/// EV_ID - Flag ID of the flag event +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid queue_id +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// Execute EV_create_flag(),EV_create_flag_auto_id() and flag has already been created. +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error (specifying incorrect queue_id) +/// --incorrect queue_id:The queue_id of essage which has not been created. +/// - Flag corresponding to queue_id doesn't exist +/// - EV_ERR_Invalid_ID +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Deletes flag with ID specified by the argument. +/// The user can only delete flag created by user process. +/// Due to deletion, program waiting for this flag (poll or wait) wakes up. +/// \~english @see evk_close, evk_ioctl, evk_destroy_queue +//////////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_destroy_flag(EV_ID queue_id); // NOLINT (readability/nolint) + +///////////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_destroy_queue +/// \~english @par Brief +/// Delete queue for message event by the queue_id. +/// \~english @param [in] queue_id +/// EV_ID - queue_id of the message event +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid queue_id +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// Execute EV_create_queue(),EV_create_queue_auto_id() and message queue has already been created. +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error (specifying incorrect queue_id) +/// --incorrect queue_id:The queue_id of essage which has not been created. +/// - Message queue corresponding to flag_id doesn't exist +/// - EV_ERR_Invalid_ID +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Deletes message queue with ID specified by the argument. +/// The user can only delete message queue created by user process. +/// Due to deletion, program waiting for this message queue (poll or wait) wakes up. +/// \~english @see EV_destroy_flag, evk_close, evk_ioctl, evk_destroy_queue +//////////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_destroy_queue(EV_ID queue_id); // NOLINT (readability/nolint) + +/* Send event */ +///////////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_set_flag +/// \~english @par Brief +/// Set Event flag +/// \~english @param [in] flag_id +/// EV_ID - Flag ID of the event flag +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @param [in] bits +/// UINT32 - event flag bit pattern +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid flag_id +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// Execute EV_create_flag(),EV_create_flag_auto_id() and flag has already been created. +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error (specifying incorrect flag_id) +/// --incorrect flag_id:The flag_id of event which has not been created. +/// - Flag corresponding to flag_id doesn't exist +/// - EV_ERR_Invalid_ID +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Sets bit pattern specified by argument to flag of ID specified by argument. +/// When setting a plurality of bit patterns in the same flag, "only OR +/// operation result of all bit patterns" is held in flag. +/// \~english @see evk_open, evk_close, evk_ioctl, evk_store_flag +//////////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_set_flag(EV_ID flag_id, UINT32 bits); // NOLINT (readability/nolint) + +/* Send event */ +///////////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_set_flag64 +/// \~english @par Brief +/// Set Event flag +/// \~english @param [in] flag_id +/// EV_ID - Flag ID of the event flag +/// \~english @par +/// EV_ID type parameter +/// @code + +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @param [in] bits +/// UINT32 - event flag bit pattern +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid flag_id +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// Execute EV_create_flag(),EV_create_flag_auto_id() and flag has already been created. +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error (specifying incorrect flag_id) +/// --incorrect flag_id:The flag_id of event which has not been created. +/// - Flag corresponding to flag_id doesn't exist +/// - EV_ERR_Invalid_ID +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Sets bit pattern specified by argument to flag of ID specified by argument. +/// When setting a plurality of bit patterns in the same flag, "only OR operation +/// result of all bit patterns" is held in flag. +/// \~english @see evk_open, evk_close, evk_ioctl, evk_store_flag +//////////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_set_flag64(EV_ID flag_id, UINT64 bits); // NOLINT (readability/nolint) + +///////////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_send_message +/// \~english @par Brief +/// Send Message event +/// \~english @param [in] queue_id +/// EV_ID - Queue ID of the message destination +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @param [in] bytes +/// UINT16 - The bytes of the send message +/// \~english @param [in] message +/// const void * - Pointer to a transmitting byte line +/// \~english @param [in] senderInfo +/// UINT32 - Message Source(It is specified when it is used for application identification. +/// When do not use it, appoint 0.) +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid queue_id +/// \~english @retval EV_ERR_Busy Queue overflow +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// Execute EV_create_queue(),EV_create_queue_auto_id() and message queue has already been created. +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error (specifying incorrect queue_id) +/// --incorrect queue_id:The queue_id of essage which has not been created. +/// - Message queue corresponding to queue_id doesn't exist +/// - EV_ERR_Invalid_ID +/// - Queue overflow in kernel space +/// - EV_ERR_Busy +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - Invalid queue types +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Sends message specified by argument to message queue of ID specified by argument. +/// An error occurs when message queue of the specified ID doesn't exist or +/// message size exceeds the specified size. +/// When message queue is FULL, the processing differs depending on the type of message queue specified +/// at the time of creation message queue. +/// \~english @see evk_open, evk_close, evk_ioctl, evk_store_message +//////////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_send_message(EV_ID queue_id, // NOLINT (readability/nolint) + UINT16 bytes, // NOLINT (readability/nolint) + const void *message, // NOLINT (readability/nolint) + UINT32 senderInfo); // NOLINT (readability/nolint) + +/* \~english Get events in the order of arrivals */ +//////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_get_next_event +/* \~english get events by reaching time */ +/// \~english @par Brief get the first reached event(non-block) +/// \~english @param [out] ev +/// event Structure +/// \~english @par +/// EV_Event struct +/// @code +/// typedef unsigned int UINT32; +/// typedef UINT32 EV_Type; +/// typedef UINT32 EV_ID; +/// #define EV_MAX_MESSAGE_LENGTH 2048 +/// enum ev_message_queue_type { +/// EV_MESSAGE_QUEUE_TYPE_BUSY, +/// EV_MESSAGE_QUEUE_TYPE_FIFO, +/// EV_MESSAGE_QUEUE_TYPE_REPLACE, +/// }; +/// +/// typedef struct { +/// EV_ID flagID; +/// UINT32 bits; +/// } EV_Flag; +/// +/// typedef struct { +/// EV_ID flagID; +/// UINT64 bits; +/// } EV_Flag64; +/// +/// typedef struct { +/// EV_ID queueID; +/// UINT32 senderInfo; +/// UINT32 length; +/// UINT32 dummy; +/// UINT8 message[EV_MAX_MESSAGE_LENGTH]; +/// } EV_Message; +/// +/// typedef struct { +/// EV_Type type; // please reference ev_message_queue_type. +/// union { +/// EV_Flag flag; +/// EV_Flag64 flag64; +/// EV_Message message; +/// } u; +/// } EV_Event; +/// +/// @endcode + +/// \~english @retval EV_OK: normal termination +/// \~english @retval EV_ERR_Invalid_Thread: unregistered thread +/// \~english @retval EV_ERR_Fatal: Fatal error +/// \~english @par Prerequisite +/// - none +/// \~english @par Change of internal state +/// - none +/// \~english @par Conditions of processing failure +/// - unregistered thread +/// - EV_ERR_Invalid_Thread +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Get the first reached event which occurred for +/// flags or message queues created in current process. +/// If there is no event, set ev->type to EV_EVENT_None, then return immediately. +/// The event is flag or message is decided by +/// the ev->type is EV_EVENT_Flag or EV_EVENT_Message. +// \~english @see none +//////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_get_next_event(/* OUT */EV_Event *ev); // NOLINT (readability/nolint) + +//////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_peek_next_event +/// \~english @par Brief get the first reached event(non-destructive) +/// \~english @param [out] ev +/// event Structure +/// @code +/// typedef unsigned int UINT32; +/// typedef UINT32 EV_Type; +/// typedef UINT32 EV_ID; +/// #define EV_MAX_MESSAGE_LENGTH 2048 +/// enum ev_message_queue_type { +/// EV_MESSAGE_QUEUE_TYPE_BUSY, +/// EV_MESSAGE_QUEUE_TYPE_FIFO, +/// EV_MESSAGE_QUEUE_TYPE_REPLACE, +/// }; +/// +/// typedef struct { +/// EV_ID flagID; +/// UINT32 bits; +/// } EV_Flag; +/// +/// typedef struct { +/// EV_ID flagID; +/// UINT64 bits; +/// } EV_Flag64; +/// +/// typedef struct { +/// EV_ID queueID; +/// UINT32 senderInfo; +/// UINT32 length; +/// UINT32 dummy; +/// UINT8 message[EV_MAX_MESSAGE_LENGTH]; +/// } EV_Message; +/// +/// typedef struct { +/// EV_Type type; // please reference ev_message_queue_type. +/// union { +/// EV_Flag flag; +/// EV_Flag64 flag64; +/// EV_Message message; +/// } u; +/// } EV_Event; +/// +/// @endcode +/// \~english @retval EV_OK: normal termination +/// \~english @retval EV_ERR_Invalid_Thread: unregistered thread +/// \~english @retval EV_ERR_Fatal: Fatal error +/// \~english @par Prerequisite +/// - none +/// \~english @par Change of internal state +/// - none +/// \~english @par Conditions of processing failure +/// - unregistered thread +/// - EV_ERR_Invalid_Thread +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Get the first reached event which occurred for +/// flags or message queues created in current process non-destructively. +/// If the event is not getted from other processes, then call the function of +/// EV_get_next_event() or EV_peek_next_event(), it will return a same event. +/// If there is no event, set ev->type to EV_EVENT_None, then return immediately. +/// The event is flag or message is decided by +/// ev->type is EV_EVENT_Flag or EV_EVENT_Message. +// \~english @see none +//////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_peek_next_event(/* OUT */EV_Event *ev); // NOLINT (readability/nolint) + +/* Get eventflag (ID specified) */ +///////////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_get_flag +/// \~english @par Brief +/// Get event flag(non-block) +/// \~english @param [in] flag_id +/// EV_ID - Flag ID +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @param [out] flag +/// EV_Flag * - event flag structure +/// \~english @par +/// EV_Flag structure +/// \~english @code +/// typedef struct { +/// EV_ID flagID; // Flag ID +/// UINT32 bits; // event flag bit pattern +/// } EV_Flag; +/// @endcode +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid flag_id +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// Execute EV_create_flag(),EV_create_flag_auto_id() and flag has already been created. +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error +/// - Flag corresponding to flag_id doesn't exist +/// --incorrect flag_id:The flag_id of event which has not been created. +/// - EV_ERR_Invalid_ID +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Gets bit pattern specified by argument to flag of ID specified by argument. +/// The user can only get flag created by user process, and clear bit pattern of acquired flag. +/// An error occurs if flag of the specified ID doesn't exist. +/// \~english @see +/// evk_ioctl, evk_get_event +//////////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_get_flag(EV_ID flag_id, /* OUT */EV_Flag *flag); // NOLINT (readability/nolint) + +///////////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_wait_flag +/// \~english @par Brief +/// Get event flag(block) +/// \~english @param [in] flag_id +/// EV_ID - Flag ID +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @param [out] flag +/// EV_Flag * - event flag structure +/// \~english @par +/// EV_Flag structure +/// \~english @code +/// typedef struct { +/// EV_ID flagID; // Flag ID +/// UINT32 bits; // event flag bit pattern +/// } EV_Flag; +/// @endcode +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid flag_id +/// \~english @retval EV_ERR_Interrupted signal interrupt +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// Execute EV_create_flag(),EV_create_flag_auto_id() and flag has already been created. +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error +/// - Flag corresponding to flag_id doesn't exist +/// --incorrect flag_id:The flag_id of event which has not been created. +/// - EV_ERR_Invalid_ID +/// - Task blocking was canceled by signal interrupt +/// - EV_ERR_Interrupted +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Gets bit pattern specified by argument to flag of ID specified by argument. +/// The user can only get flag created by user process, and clear bit pattern of acquired flag. +/// An error occurs if flag of the specified ID doesn't exist. +/// If bit pattern is not set in flag, block until bit pattern is set. +/// However, if a signal interrupt or corresponding flag is deleted, it will abort and return an error. +/// \~english @see +/// evk_ioctl, evk_get_event +//////////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_wait_flag(EV_ID flag_id, /* OUT */EV_Flag *flag); // NOLINT (readability/nolint) + +//////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_peek_flag +/// \~english @par Brief get flag event(non-destructive) +/// \~english @param [in] flag_id +/// ID of message event queue +/// \~english @param [out] flag +/// flag struct +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @par +/// EV_Flag Structure +/// @code +/// typedef struct { +/// EV_ID flagID; +/// UINT32 bits; +/// } EV_Flag; +/// @endcode +/// \~english @retval EV_OK: normal termination +/// \~english @retval EV_ERR_Invalid_ID: The specified flag ID is not existing, +/// or it is not created in current process. +/// \~english @retval EV_ERR_Fatal: Fatal error +/// \~english @par Prerequisite +/// - none +/// \~english @par Change of internal state +/// - none +/// \~english @par Conditions of processing failure +/// - Input parameter error +/// - Flag corresponding to flag_id doesn't exist +/// --incorrect flag_id:The flag_id of event which has not been created. +/// - EV_ERR_Invalid_ID +/// - Task blocking was canceled by signal interrupt +/// - EV_ERR_Interrupted +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Get a flag event whose ID is specified non-destructively. +/// If there is no event, just return. +/// If there is no event, set flag->flagID to EV_NO_ID. +/// You can judge that there is no event, even though flag->bits is 0. +// \~english @see none +//////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_peek_flag(EV_ID flag_id, /* OUT */EV_Flag *flag); // NOLINT (readability/nolint) + +/* Get eventflag (ID specified) */ +///////////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_get_flag64 +/// \~english @par Brief +/// Get event flag(non-block) +/// \~english @param [in] flag_id +/// EV_ID - Flag ID +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @param [out] flag +/// EV_Flag * - event flag structure +/// \~english @par +/// EV_Flag structure +/// \~english @code +/// typedef unsigned int UINT32; +/// typedef UINT32 EV_ID +/// +/// typedef struct { +/// EV_ID flagID; // Flag ID +/// UINT32 bits; // event flag bit pattern +/// } EV_Flag; +/// @endcode +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid flag_id +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// Execute EV_create_flag(),EV_create_flag_auto_id() and flag has already been created. +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error +/// - Flag corresponding to flag_id doesn't exist +/// --incorrect flag_id:The flag_id of event which has not been created. +/// - EV_ERR_Invalid_ID +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Gets bit pattern specified by argument to flag of ID specified by argument. +/// The user can only get flag created by user process, and clear bit pattern of acquired flag. +/// An error occurs if flag of the specified ID doesn't exist. +/// \~english @see +/// evk_ioctl, evk_get_event +//////////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_get_flag64(EV_ID flag_id, /* OUT */EV_Flag64 *flag); // NOLINT (readability/nolint) + +///////////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_wait_flag64 +/// \~english @par Brief +/// Get event flag(block) +/// \~english @param [in] flag_id +/// EV_ID - Flag ID +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @param [out] flag +/// EV_Flag * - event flag structure +/// \~english @par +/// EV_Flag structure +/// \~english @code +/// typedef unsigned int UINT32; +/// typedef UINT32 EV_ID +/// +/// typedef struct { +/// EV_ID flagID; // Flag ID +/// UINT32 bits; // event flag bit pattern +/// } EV_Flag; +/// @endcode +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid flag_id +/// \~english @retval EV_ERR_Interrupted signal interrupt +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// Execute EV_create_flag(),EV_create_flag_auto_id() and flag has already been created. +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error +/// - Flag corresponding to flag_id doesn't exist +/// --incorrect flag_id:The flag_id of event which has not been created. +/// - EV_ERR_Invalid_ID +/// - Task blocking was canceled by signal interrupt +/// - EV_ERR_Interrupted +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Gets bit pattern specified by argument to flag of ID specified by argument. +/// The user can only get flag created by user process, and clear bit pattern of acquired flag. +/// An error occurs if flag of the specified ID doesn't exist. +/// If bit pattern is not set in flag, block until bit pattern is set. +/// However, if a signal interrupt or corresponding flag is deleted, it will abort and return an error. +/// \~english @see +/// evk_ioctl, evk_get_event +//////////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_wait_flag64(EV_ID flag_id, /* OUT */EV_Flag64 *flag); // NOLINT (readability/nolint) + +//////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_peek_flag64 +/// \~english @par Brief get flag event(non-destructive) +/// \~english @param [in] flag_id +/// ID of message event queue +/// \~english @param [out] flag +/// flag struct +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @par +/// EV_Flag Structure +/// @code +/// typedef struct { +/// EV_ID flagID; +/// UINT32 bits; +/// } EV_Flag; +/// @endcode +/// \~english @retval EV_OK: normal termination +/// \~english @retval EV_ERR_Invalid_ID: The specified flag ID is not existing, +/// or it is not created in current process. +/// \~english @retval EV_ERR_Fatal: Fatal error +/// \~english @par Prerequisite +/// - none +/// \~english @par Change of internal state +/// - none +/// \~english @par Conditions of processing failure +/// - Input parameter error +/// - Flag corresponding to flag_id doesn't exist +/// --incorrect flag_id:The flag_id of event which has not been created. +/// - EV_ERR_Invalid_ID +/// - Task blocking was canceled by signal interrupt +/// - EV_ERR_Interrupted +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Get a flag event whose ID is specified non-destructively. +/// If there is no event, just return. +/// If there is no event, set flag->flagID to EV_NO_ID. +/// You can judge that there is no event, even though flag->bits is 0. +// \~english @see none +//////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_peek_flag64(EV_ID flag_id, /* OUT */EV_Flag64 *flag); // NOLINT (readability/nolint) + +/* Get Message Event (ID specified) */ +///////////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_get_message +/// \~english @par Brief +/// Get message event(non-block) +/// \~english @param [in] queue_id +/// EV_ID - Message queue ID +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @param [out] message +/// EV_Message * - Message event structure +/// \~english @par +/// EV_Message structure +/// \~english @code +/// typedef unsigned int UINT32; +/// typedef UINT32 EV_ID +/// +/// #define EV_MAX_MESSAGE_LENGTH 2048 +/// typedef struct { +/// EV_ID queueID; // ID of message queue +/// UINT32 senderInfo; // Message Source +/// UINT32 length; // length of message +/// UINT32 dummy; // dummy for padding +/// UINT8 message[EV_MAX_MESSAGE_LENGTH]; // message +/// } EV_Message; +/// @endcode +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid queue_id +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// Execute EV_create_queue(),EV_create_queue_auto_id() and message queue has already been created. +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error +/// - Message queue corresponding to queue_id doesn't exist +/// --incorrect queue_id:The queue_id of essage which has not been created. +/// - EV_ERR_Invalid_ID +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Gets 1 message specified by argument to message queue of ID specified by argument. +/// The user can only get message queue created by user process, and clear 1 message of acquired message queue. +/// An error occurs if message queue of the specified ID doesn't exist. +/// \~english @see +/// evk_ioctl, evk_get_event +//////////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_get_message(EV_ID queue_id, /* OUT */EV_Message *message); // NOLINT (readability/nolint) + +///////////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_wait_message +/// \~english @par Brief +/// Get message event(block) +/// \~english @param [in] queue_id +/// EV_ID - Message queue ID +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @param [out] message +/// EV_Message * - Message event structure +/// \~english @par +/// EV_Message structure +/// \~english @code +/// typedef unsigned int UINT32; +/// typedef UINT32 EV_ID +/// +/// #define EV_MAX_MESSAGE_LENGTH 2048 +/// typedef struct { +/// EV_ID queueID; // ID of message queue +/// UINT32 senderInfo; // Message Source +/// UINT32 length; // length of message +/// UINT32 dummy; // dummy for padding +/// UINT8 message[EV_MAX_MESSAGE_LENGTH]; // message +/// } EV_Message; +/// @endcode +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid queue_id +/// \~english @retval EV_ERR_Interrupted signal interrupt +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// Execute EV_create_queue(),EV_create_queue_auto_id() and message queue has already been created. +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error +/// - Message queue corresponding to queue_id doesn't exist +/// --incorrect queue_id:The queue_id of essage which has not been created. +/// - EV_ERR_Invalid_ID +/// - Task blocking was canceled by signal interrupt +/// - EV_ERR_Interrupted +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Gets 1 message specified by argument to message queue of ID specified by argument. +/// The user can only get message queue created by user process, and clear 1 message of acquired message queue. +/// An error occurs if message queue of the specified ID doesn't exist. +/// If message is not set in message queue, block until message is sent. +/// However, if a signal interrupt or corresponding message queue is deleted, it will abort and return an error. +/// \~english @see +/// evk_ioctl, evk_get_event +//////////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_wait_message(EV_ID queue_id, /* OUT */EV_Message *message); // NOLINT (readability/nolint) + +//////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_peek_message +/// \~english @par Brief get message event(non-destructive) +/// \~english @param [in] queue_id +/// ID of message event queue +/// \~english @param [out] message +/// message event queue struct +/// \~english @par +/// EV_ID define +/// @code +/// typedef UINT32 EV_ID +/// @endcode + +/// \~english @par +/// EV_Message struct +/// @code +/// #define EV_MAX_MESSAGE_LENGTH 2048 +/// typedef struct { +/// EV_ID queueID; +/// UINT32 senderInfo; +/// UINT32 length; +/// UINT32 dummy; +/// UINT8 message[EV_MAX_MESSAGE_LENGTH]; +/// } EV_Message; +/// @endcode +/// \~english @retval EV_OK: normal termination +/// \~english @retval EV_ERR_Invalid_ID: The specified queue ID is not existing, +/// or it is not created in current process. +/// \~english @retval EV_ERR_Fatal: Fatal error +/// \~english @par Prerequisite +/// - none +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error +/// - Message queue corresponding to queue_id doesn't exist +/// --incorrect queue_id:The queue_id of essage which has not been created. +/// - EV_ERR_Invalid_ID +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Get a message event queue whose ID is specified non-destructively. +/// If there is no event, just return. +/// If there is no event, set message->queueID to EV_NO_ID. +/// It is the same with EV_get_message(), except the message is remained in the queue. +// \~english @see none +//////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_peek_message(EV_ID queue_id, /* OUT */EV_Message *message); // NOLINT (readability/nolint) + +/* \~english Get events(with search criteria) */ + +//////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_find_message_by_sender +/* \~english get event(with search sender infomation condition) */ +/// \~english @param [in] queue_id +/// ID of message event queue +/// \~english @param [in] senderInfo +/// sender information +/// \~english @param [out] message +/// message event struct +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @par +/// EV_Message struct +/// @code +/// #define EV_MAX_MESSAGE_LENGTH 2048 +/// typedef struct { +/// EV_ID queueID; +/// UINT32 senderInfo; +/// UINT32 length; +/// UINT32 dummy; +/// UINT8 message[EV_MAX_MESSAGE_LENGTH]; +/// } EV_Message; +/// @endcode +/// \~english @retval EV_OK: normal termination +/// \~english @retval EV_ERR_Invalid_ID: The specified queue ID is not existing, +/// or it is not created in current process. +/// \~english @retval EV_ERR_Fatal: Fatal error +/// \~english @par Prerequisite +/// - none +/// \~english @par Change of internal state +/// - none +/// \~english @par Conditions of processing failure +/// - Input parameter error (specifying incorrect queue_id) +/// --incorrect queue_id:The queue_id of essage which has not been created. +/// - Not find same sender information's message according to input sender information information +/// - EV_ERR_Invalid_ID +/// - Securing free space of thread information management table (malloc) Failure +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - Message queue pool is NULL +/// - Message queue generation corresponding to queue_id failed +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// If there is a event whose sender information is same with +/// any event in message event queue whose ID is specified, get the event and delete it from queue. +/// If such a message is not existing, +/// set message->queueID to EV_NO_ID, then return. +// \~english @see none +//////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_find_message_by_sender(EV_ID queue_id, UINT32 senderInfo, EV_Message *message); // NOLINT (readability/nolint) + +//////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_find_message_by_content +/// \~english @par Brief get message event(search with contents) +/// \~english @param [in] queue_id +/// ID of message event queue +/// \~english @param [in] bytes +/// size of compare bytes +/// \~english @param [in] compare_bytes +/// bytes that used to campare the contents +/// \~english @param [out] message +/// message event struct +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @par +/// EV_Message struct +/// @code +/// #define EV_MAX_MESSAGE_LENGTH 2048 +/// typedef struct { +/// EV_ID queueID; +/// UINT32 senderInfo; +/// UINT32 length; +/// UINT32 dummy; +/// UINT8 message[EV_MAX_MESSAGE_LENGTH]; +/// } EV_Message; +/// @endcode +/// \~english @retval EV_OK: normal termination +/// \~english @retval EV_ERR_Invalid_ID: The specified queue ID is not existing, +/// or it is not created in current process. +/// \~english @retval EV_ERR_Fatal: Fatal error +/// \~english @par Prerequisite +/// - none +/// \~english @par Change of internal state +/// - none +/// \~english @par Conditions of processing failure +/// - Input parameter error (specifying incorrect queue_id) +/// --incorrect queue_id:The queue_id of essage which has not been created. +/// - Not find contents's message according to input contents information +/// - EV_ERR_Invalid_ID +/// - Securing free space of thread information management table (malloc) Failure +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - Message queue pool is NULL +/// - Message queue generation corresponding to queue_id failed +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// If the event in compare bytes is same with +/// any event in message event queue whose ID is specified, +/// get the event and delete it from queue. +/// If such a message is not existing, set message->queueID to EV_NO_ID, then return. +// \~english @see none +//////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_find_message_by_content(EV_ID queue_id, // NOLINT (readability/nolint) + UINT16 length, // NOLINT (readability/nolint) + const void *compare_bytes, // NOLINT (readability/nolint) + /* OUT */EV_Message *message); // NOLINT (readability/nolint) + +///////////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_get_flag_fd +/// \~english @par Brief +/// Obtain fd for polling flag event +/// \~english @param [in] flag_id +/// EV_ID - Flag ID +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @param [out] fd +/// int * - event flag queue fd for Polling +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid flag_id +/// \~english @par Prerequisite +/// Execute EV_create_flag(),EV_create_flag_auto_id() and flag has already been created. +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error +/// --incorrect flag_id:The flag_id of event which has not been created. +/// - Flag corresponding to flag_id doesn't exist +/// - EV_ERR_Invalid_ID +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Gets fd(File Descriptor) corresponding to flag of ID specified by argument. +/// The user can only get flag created by user process . +/// This fd(File Descriptor) can be used only for designation to poll / select, and operation when other +/// operations are performed is not guaranteed. +/// At the time of poll, only POLLIN can be specified, and at the time of select, +/// it is possible to check only whether it can be read. +/// Also, if flag is deleted in poll / select, it exits poll / select. * In case of poll, POLLERR is set. +/// When calling the same ID more than once, it returns the same fd(File Descriptor) +/// each time (unless destroy / create is done). +/// \~english @see +/// nothing +//////////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_get_flag_fd(EV_ID flag_id, /* OUT */int *fd); // NOLINT (readability/nolint) + +///////////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_get_queue_fd +/// \~english @par Brief +/// Obtain fd for polling message event +/// \~english @param [in] flag_id +/// EV_ID - Flag ID +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @param [out] fd +/// int * - Message queue fd for Polling +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid queue_id +/// \~english @par Prerequisite +/// Execute EV_create_queue(),EV_create_queue_auto_id() and message queue has already been created. +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error +/// - Message queue corresponding to queue_id doesn't exist +/// --incorrect queue_id:The queue_id of essage which has not been created. +/// - EV_ERR_Invalid_ID +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Gets fd(File Descriptor) corresponding to message queue of ID specified by argument. +/// The user can only get message queue created by user process . +/// This fd(File Descriptor) can be used only for designation to poll / select, +/// and operation when other operations are performed is not guaranteed. +/// At the time of poll, only POLLIN can be specified, and at the time of select, +/// it is possible to check only whether it can be read. +/// Also, if message queue is deleted in poll / select, it exits poll / select. +/// * In case of poll, POLLERR is set. +/// When calling the same ID more than once, it returns the same fd(File Descriptor) +/// each time (unless destroy / create is done). +/// \~english @see +/// nothing +//////////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_get_queue_fd(EV_ID queue_id, /* OUT */int *fd); // NOLINT (readability/nolint) + +/* \~english Functions that specify the module ID (16 bits) instead of the flag ID and queue ID */ + +//////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_moduleID_to_flag_id +/* \~english function group used to specify moduleID(16bit) instead of flag_id, queue_id */ +/// \~english @par Brief change from moduleID to flag_id +/// \~english @param [in] m_id +/// moduleID +/// \~english @retval flag_id +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @par Prerequisite +/// - none +/// \~english @par Change of internal state +/// - none +/// \~english @par Conditions of processing failure +/// - none +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// You can not use this function to +/// create a multiple of flags with one moduleID. return error:EV_ERR_Exist. +/// This function is only used for generating one event by one module ID. +// \~english @see none +//////////////////////////////////////////////////////////////////////////////// + +EV_ID EV_moduleID_to_flagID(UINT16 m_id); // NOLINT (readability/nolint) + +//////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_moduleID_to_flag64ID +/// \~english @par Brief change from moduleID to 64bit flag_id +/// \~english @param [in] m_id +/// moduleID +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @retval 64bit flag_id +/// \~english @par Prerequisite +/// - none +/// \~english @par Change of internal state +/// - none +/// \~english @par Conditions of processing failure +/// - none +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// You can not use this function to +/// create a multiple of flags with one moduleID. return error:EV_ERR_Exist. +/// This function is only used for generating one event by one module ID. +// \~english @see none +//////////////////////////////////////////////////////////////////////////////// + +EV_ID EV_moduleID_to_flag64ID(UINT16 m_id); // NOLINT (readability/nolint) + +//////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_moduleID_to_queueID +/// \~english @par Brief change from moduleID to queue_id +/// \~english @param [in] m_id +/// moduleID +/// \~english @par +/// EV_ID type parameter +/// @code +/// typedef UINT32 EV_ID +/// @endcode +/// \~english @retval queue_id +/// \~english @par Prerequisite +/// - none +/// \~english @par Change of internal state +/// - none +/// \~english @par Conditions of processing failure +/// - none +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// You can not use this function to +/// create a multiple of queues with one moduleID. +// \~english @see none +//////////////////////////////////////////////////////////////////////////////// + +EV_ID EV_moduleID_to_queueID(UINT16 m_id); // NOLINT (readability/nolint) + +//////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_create_flag_by_mID +/// \~english @par Brief create flag(moduleID specified) +/// \~english @param [in] m_id +/// moduleID +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid flag_id +/// \~english @retval EV_ERR_Thread_Over The MAX of event thread. +/// \~english @retval EV_ERR_Exist Duplication Error +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// There is no prerequisite +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error (specifying incorrect flag_id) +/// --incorrect flag_id:The ID is not created by function of EV_moduleID_to_flagID (). +/// - EV_ERR_Invalid_ID +/// - Startup thread upper limit (16) error +/// - EV_ERR_Thread_Over +/// - flag_id registered in launch thread +/// - Flag corresponding to flag_id already exists +/// - EV_ERR_Exist +/// - Securing free space of thread information management table (malloc) Failure +/// - Flag pool is NULL +/// - Flag generation corresponding to flag_id failed +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// You can not use this function to +/// create a multiple of flags with one moduleID.return error:EV_ERR_Exist. +/// This function is only used for generating one event by one module ID. +// \~english @see EV_create_flag +//////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_create_flag_by_mID(UINT16 m_id); // NOLINT (readability/nolint) + +//////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_create_flag64_by_mID +/// \~english @par Brief create 64bit flag(moduleID specified) +/// \~english @param [in] m_id +/// moduleID +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid flag_id +/// \~english @retval EV_ERR_Thread_Over The MAX of event thread. +/// \~english @retval EV_ERR_Exist Duplication Error +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// There is no prerequisite +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error (specifying incorrect flag_id) +/// --incorrect flag_id:The ID is not created by function of EV_moduleID_to_flag64ID (). +/// - EV_ERR_Invalid_ID +/// - Startup thread upper limit (16) error +/// - EV_ERR_Thread_Over +/// - flag_id registered in launch thread +/// - Flag corresponding to flag_id already exists +/// - EV_ERR_Exist +/// - Securing free space of thread information management table (malloc) Failure +/// - Flag pool is NULL +/// - Flag generation corresponding to flag_id failed +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// You can not use this function to +/// create a multiple of flags with one moduleID. return error:EV_ERR_Exist. +/// This function is only used for generating one event by one module ID. +// \~english @see EV_create_flag64 +//////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_create_flag64_by_mID(UINT16 m_id); // NOLINT (readability/nolint) + +//////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_create_queue_by_mID +/// \~english @par Brief create queue(moduleID specified) +/// \~english @param [in] m_id +/// moduleID +/// \~english @param [in] length +/// length of message queue +/// \~english @param [in] max_bytes +/// one max bytes for message +/// \~english @param [in] type +/// treat type of receiving events even though the queue is full +/// \~english @par +/// ev_message_queue_type struct +/// @code +/// enum ev_message_queue_type { +/// EV_MESSAGE_QUEUE_TYPE_BUSY, +/// EV_MESSAGE_QUEUE_TYPE_FIFO, +/// EV_MESSAGE_QUEUE_TYPE_REPLACE, +/// }; +/// @endcode +/// \~english @retval EV_OK: normal termination +/// \~english @retval EV_ERR_Invalid_ID: set en invalid flag ID +/// \~english @retval EV_ERR_Thread_Over The MAX of event thread. +/// \~english @retval EV_ERR_Exist: a same flag ID is existing +/// \~english @retval EV_ERR_Fatal: Fatal error +/// \~english @par Prerequisite +/// There is no prerequisite +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error (specifying incorrect queue_id) +/// --incorrect queue_id:The queue_id of essage which has not been created. +/// - EV_ERR_Invalid_ID +/// - Startup thread upper limit (16) error +/// - EV_ERR_Thread_Over +/// - queue_id registered in launch thread +/// - Message queue corresponding to queue_id already exists +/// - EV_ERR_Exist +/// - Securing free space of thread information management table (malloc) Failure +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - Message queue pool is NULL +/// - Message queue generation corresponding to queue_id failed +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// You can not use this function to +/// create a multiple of queues with one moduleID. +// \~english @see EV_create_queue +//////////////////////////////////////////////////////////////////////////////// + +EV_ERR +EV_create_queue_by_mID(UINT16 m_id, // NOLINT (readability/nolint) + UINT8 length, // NOLINT (readability/nolint) + UINT16 max_bytes, // NOLINT (readability/nolint) + EV_Message_Queue_Type type); // NOLINT (readability/nolint) + +//////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_destroy_flag_by_mID +/// \~english @par Brief delete flag(moduleID specified) +/// \~english @param [in] m_id +/// moduleID +/// \~english @par length [in]length of message queue +/// \~english @par max_bytes [in]one max bytes for message +/// \~english @par type [in]treat type of receiving events even though the queue is full +/// \~english @retval EV_OK: normal termination +/// \~english @retval EV_ERR_Invalid_ID: set en invalid flag ID +/// \~english @retval EV_ERR_Fatal: Fatal error +/// \~english @par Prerequisite +/// - none +/// \~english @par Change of internal state +/// - none +/// \~english @par Conditions of processing failure +/// - Input parameter error (specifying incorrect flag_id) +/// --incorrect flag_id:The flag_id of event/message which has not been created. +/// - Flag corresponding to queue_id doesn't exist +/// - EV_ERR_Invalid_ID +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// \~english You can not use this function to +/// \~english create a multiple of flags with one moduleID. return error:EV_ERR_Exist. +/// This function is only used for generating one event by one module ID. +// \~english @see EV_destroy_flag +//////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_destroy_flag_by_mID(UINT16 m_id); // NOLINT (readability/nolint) + +//////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_destroy_queue_by_mID +/// \~english @par Brief delete queue(moduleID specified) +/// \~english @param [in] m_id +/// moduleID +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid queue_id +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// - none +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error (specifying incorrect queue_id) +/// --incorrect queue_id:The queue_id of essage which has not been created. +/// - Message queue corresponding to flag_id doesn't exist +/// - EV_ERR_Invalid_ID +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// You can not use this function to +/// create a multiple of queues with one moduleID +// \~english @see EV_destroy_queue +//////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_destroy_queue_by_mID(UINT16 m_id); // NOLINT (readability/nolint) + +//////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_set_flag_by_mID +/// \~english @par Brief send flag(moduleID specified) +/// \~english @param [in] m_id +/// moduleID +/// \~english @param [in] bits +/// value of flag +/// \~english @retval EV_OK: normal termination +/// \~english @retval EV_ERR_Invalid_ID: set en invalid flag ID +/// \~english @retval EV_ERR_Fatal: Fatal error +/// \~english @par Prerequisite +/// - none +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error (specifying incorrect flag_id) +/// --incorrect flag_id:The flag_id of event which has not been created. +/// - Flag corresponding to flag_id doesn't exist +/// - EV_ERR_Invalid_ID +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Sets bit pattern specified by argument to flag of ID specified by argument. +/// When setting a plurality of bit patterns in the same flag, +/// "only OR operation result of all bit patterns" is held in flag. +// \~english @see EV_set_flag +//////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_set_flag_by_mID(UINT16 m_id, UINT32 bits); // NOLINT (readability/nolint) + +//////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_set_flag64_by_mID +/// \~english @par Brief send 64bit flag(moduleID specified) +/// \~english @param [in] m_id +/// moduleID +/// \~english @param [in] bits +/// value of flag +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid flag_id +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// - none +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error (specifying incorrect flag_id) +/// --incorrect flag_id:The flag_id of event which has not been created. +/// - Flag corresponding to flag_id doesn't exist +/// - EV_ERR_Invalid_ID +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Sets bit pattern specified by argument to flag of ID specified by argument. +/// When setting a plurality of bit patterns in the same flag, "only +/// OR operation result of all bit patterns" is held in flag. +// \~english @see EV_set_flag64 +//////////////////////////////////////////////////////////////////////////////// + +EV_ERR EV_set_flag64_by_mID(UINT16 m_id, UINT64 bits); // NOLINT (readability/nolint) + +//////////////////////////////////////////////////////////////////////////////// +/// \ingroup EV_send_message_by_mID +/// \~english @par Brief send message(moduleID specified) +/// \~english @param [in] m_id +/// moduleID +/// \~english @param [in] bytes +/// number of send bytes +/// \~english @param [in] message +/// pointer to sender contents +/// \~english @param [in] senderInfo +/// sender information +/// \~english @retval EV_OK Successful completion +/// \~english @retval EV_ERR_Invalid_ID Invalid queue_id +/// \~english @retval EV_ERR_Busy Queue overflow +/// \~english @retval EV_ERR_Fatal Abnormal error +/// \~english @par Prerequisite +/// Execute EV_create_queue(),EV_create_queue_auto_id() and message queue has already been created. +/// \~english @par Change of internal state +/// There is no change of the internal Status +/// \~english @par Conditions of processing failure +/// - Input parameter error (specifying incorrect queue_id) +/// --incorrect queue_id:The queue_id of essage which has not been created. +/// - Message queue corresponding to queue_id doesn't exist +/// - EV_ERR_Invalid_ID +/// - Queue overflow in kernel space +/// - EV_ERR_Busy +/// - Access failed from kernel space to user space reference area +/// - Failed to copy data from user space to kernel space +/// - Invalid queue types +/// - EV_ERR_Fatal +/// \~english @par Classification +/// Public +/// \~english @par Type +/// Sync Only +/// \~english @par Detail +/// Sends message specified by argument to message moduleID specified by argument. +/// An error occurs when message queue of the specified ID doesn't exist +/// or message size exceeds the specified size. +/// When message queue is FULL, the processing differs depending on the type +/// of message queue specified at the time of creation message queue. +/// \~english @see evk_open, evk_close, evk_ioctl, evk_store_message +//////////////////////////////////////////////////////////////////////////////// + +EV_ERR +EV_send_message_by_mID(UINT16 m_id, // NOLINT (readability/nolint) + UINT16 bytes, // NOLINT (readability/nolint) + const void *message, // NOLINT (readability/nolint) + UINT32 senderInfo); // NOLINT (readability/nolint) + +/** @}*/ // end of event_library +/** @}*/ // end of other_service +/** @}*/ // end of BaseSystem +/** + * + * @brief Method to specify module IDs as flag IDs and queue IDs + * + * The function with module ID as an argument directly can be used in the case of that created only + * one flag and queue in the module, other than using macros EV_Flag_ID_Base() or EV_Queue_ID_Base(). + * @see EV_create_flag_by_mID + * @see EV_create_queue_by_mID + * @see EV_destroy_flag_by_mID + * @see EV_destroy_queue_by_mID + * @see EV_set_flag_by_mID + * @see EV_send_message_by_mID + * + * So the following API can be used to convert IDs created using above method to flag IDs or queue ID + * when pass them to other modules. + * @see EV_moduleID_to_flagID(UINT16 m_id) + * @see EV_moduleID_to_queueID(UINT16 m_id) + * + * @see EV_ID_spec + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* !__KERNEL__ */ + +#endif // OTHERSERVICE_EV_LIB_H_ diff --git a/event_library/library/include/other_service/event_library.h b/event_library/library/include/other_service/event_library.h new file mode 100644 index 00000000..35b165c7 --- /dev/null +++ b/event_library/library/include/other_service/event_library.h @@ -0,0 +1,39 @@ +/* + * @copyright Copyright (c) 2017-2019 TOYOTA MOTOR CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file + * @brief \~english include all event_library head files + */ +/** @addtogroup BaseSystem + * @{ + */ +/** @addtogroup other_service + * @ingroup BaseSystem + * @{ + */ +/** @addtogroup event_library + * @ingroup other_service + * @{ + */ +#ifndef OTHERSERVICE_EVENTLIBRARY_H_ // NOLINT(build/header_guard) +#define OTHERSERVICE_EVENTLIBRARY_H_ // NOLINT(build/header_guard) + +#include <other_service/ev_lib.h> + +#endif // OTHERSERVICE_EVENTLIBRARY_H_ +/** @}*/ +/** @}*/ +/** @}*/ diff --git a/event_library/library/libev.ver b/event_library/library/libev.ver new file mode 100644 index 00000000..b9ac7fe9 --- /dev/null +++ b/event_library/library/libev.ver @@ -0,0 +1,41 @@ +/* + * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +###################### +# ev version script # +###################### +{ + global: + ### .text section ### + EV_*; + ev_lock_func; + ev_lock_line; + ev_lock_pid; + ev_process_global_mutex; + g_destory_message_invalid_id_wrapper_flag; + g_destory_message_fatal_wrapper_flag; + g_receive_message_no_exist_fatal_wrapper_flag; + g_receive_message_fatal_wrapper_flag; + g_send_message_invalid_id_wrapper_flag; + g_send_message_fatal_wrapper_flag; + g_create_event_fatal_wrapper_flag; + g_create_event_set_poll_fatal_wrapper_flag; + ### .data section ### + ### .bss section ### + local: + *; +}; + diff --git a/event_library/library/src/ev_lib.c b/event_library/library/src/ev_lib.c new file mode 100644 index 00000000..cd2f69f0 --- /dev/null +++ b/event_library/library/src/ev_lib.c @@ -0,0 +1,1551 @@ +/* + * @copyright Copyright (c) 2016-2019 TOYOTA MOTOR CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file ev_lib.c + * @brief Events Library -- Implementing API Functions + */ +#include <stdio.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> +#include <string.h> +#include <pthread.h> +#include <sys/prctl.h> +#include <other_service/ev_lib.h> +#include <agldd/evk_lib.h> +#include <agldd/ev_common.h> +#include <assert.h> +#define EV_perror perror +#define EV_assert assert + +/* + * Not use dbg_output in the EV so that the DTV apps and semiconductor vendor use this function. + */ +#define ev_log(format, arg...) \ +{ \ + { \ + char procname[33]; \ + prctl(PR_GET_NAME, procname); \ + int pid = getpid(); \ + printf(format, procname, pid, ##arg); \ + } \ +} + +#define EV_DEBUG_INFO(format, arg...) \ +{ \ + if (getenv("EV_DEBUG") != NULL) { \ + ev_log("[EV: info](%s:%d) " format, ##arg); \ + } \ +} + +#define EV_DEBUG_WARNING(format, arg...) \ +{ \ + ev_log("[EV: warning](%s:%d) " format, ##arg); \ +} + +#define EV_DEBUG_ERR(format, arg...) \ +{ \ + ev_log("[EV: ERR](%s:%d) " format, ##arg); \ +} + +/** @brief Structures for managing ID and FD in use by processes + */ +typedef struct { + EV_ID id; /**< flag/queue ID */ + INT32 fd; /**< file descriptor */ +} +EV_Info; + +/*----------------------------------------*/ +/** @brief EV management information table per thread */ +/*----------------------------------------*/ +typedef struct { + /** Thread calling the EV library */ + pthread_t thread; + /** Registration information by ID */ + EV_Info ev_info[EV_MAX_IDS_IN_THREAD]; + /** Number of registered IDs */ + UINT8 num; +} +EV_thread_info_type; + +/** Thread information acquisition mode */ +#define EV_THREAD_INFO_CREATE 0 +#define EV_THREAD_INFO_PEEK 1 +#define EV_SEARCH_ALL_THREAD -1 + +/* Related process exclusion control in the process */ +const char *g_ev_lock_func; +int g_ev_lock_line; +int g_ev_lock_pid; +pthread_mutex_t g_ev_process_global_mutex = PTHREAD_MUTEX_INITIALIZER; + +#define EV_PROCESS_MUTEX_LOCK \ + pthread_mutex_lock(&g_ev_process_global_mutex); \ + g_ev_lock_func = __FUNCTION__; \ + g_ev_lock_line = __LINE__; \ + g_ev_lock_pid = getpid(); +#define EV_PROCESS_MUTEX_UNLOCK \ + pthread_mutex_unlock(&g_ev_process_global_mutex); + +/** @mainpage + * This document describes the following specifications: + * - Event Library (EV) API specifications + * - Event ID specifications + * + * In principle, the API specifications of the event library for kernel space (EVK) is + * the same as the event library for user space (EV) except for the function name prefixed ""EVK"". + * If there are differences between the EV and EVK, it is described as "difference in kernel version". + */ +/** @defgroup Event Library (EV) API specifications */ +/** @defgroup EV_ID_spec Event ID specifications */ +/** @defgroup EV_m_id Function specifying module ID instead of event ID */ +/** @defgroup EV_in internal specifications of the event library for user space (EV) */ +/** @defgroup EVK_in Internal specifications of the event library for kernel space (EVK) */ +/** @addtogroup EV_in + * @{ */ + +/** EV thread information management table */ +EV_thread_info_type *EV_thread_info[EV_MAX_THREADS_IN_PROCESS]; + +/*---------------------------------------------------------------------- + * Return the registered position of the thread ID + * Allocate and initialize space for unregistered threads + * @brief Sending message (specified module-ID) + * @param index [OUT] Thread index + * @param flag [IN] Operating Mode + ----------------------------------------------------------------------*/ +EV_ERR +EV_thread_id_check(int *index, int flag) { + int i, empty; + + /* Current threadID */ + pthread_t EV_self_thread_id; + + /* Get thread ID */ + EV_self_thread_id = pthread_self(); + + /* Control-process lock */ + EV_PROCESS_MUTEX_LOCK; + + /* Whether or not the thread has already been registered. */ + for(i = 0, empty = -1; i < EV_MAX_THREADS_IN_PROCESS; i++) { + /* Free space */ + if(EV_thread_info[i] == NULL) { + /* Set free space index */ + empty = (empty == -1) ? i: empty; + continue; + } + + if(EV_thread_info[i]->thread == EV_self_thread_id) { + *index = i; + + /* Cancel in-process mutual exclusion */ + EV_PROCESS_MUTEX_UNLOCK; + return EV_OK; + } + } + + if(flag == EV_THREAD_INFO_PEEK) { + EV_DEBUG_ERR("thread id is not found.\n"); + + /* Cancel in-process mutual exclusion */ + EV_PROCESS_MUTEX_UNLOCK; + return EV_ERR_Invalid_Thread; + } + + /* If there are no unregistered threads and there is no space */ + if(empty == -1) { + EV_DEBUG_ERR("thread id is full.\n"); + + /* Cancel in-process mutual exclusion */ + EV_PROCESS_MUTEX_UNLOCK; + return EV_ERR_Thread_Over; + } + + /* Set to free space */ + EV_thread_info[empty] = malloc(sizeof(*(EV_thread_info[empty]))); + EV_thread_info_type *th = EV_thread_info[empty]; + + /* malloc failed */ + if(th == NULL) { // LCOV_EXCL_BR_LINE 5: fail safe for glibc function malloc + /* Cancel in-process mutual exclusion */ + // LCOV_EXCL_START 5: fail safe for glibc function malloc + + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + + EV_PROCESS_MUTEX_UNLOCK; + return EV_ERR_Fatal; + } + // LCOV_EXCL_STOP + + /* Initialization */ + memset(th, '\0', sizeof(*th)); + th->thread = EV_self_thread_id; + /* th->num = 0; */ + + /* Cancel in-process mutual exclusion */ + EV_PROCESS_MUTEX_UNLOCK; + + /* Set registration position */ + *index = empty; + + return EV_OK; +} + +// free thread information when create event/message fail and no release thread buffer. +// If no release thread buffer will cause be error: +// Creation event's Thread count num less than MAX count(16) when one thread create event/message +// fail and no longer to create event/message. +static void +free_thread_buffer(int th_index) { + /* in-process mutual exclusion */ + EV_PROCESS_MUTEX_LOCK; + if ((th_index >= 0) + &&(th_index < EV_MAX_THREADS_IN_PROCESS) + && (NULL != EV_thread_info[th_index]) + && (0 == EV_thread_info[th_index]->num)) { + free(EV_thread_info[th_index]); + EV_thread_info[th_index] = NULL; + EV_DEBUG_ERR("Free thread buffer by th_index:%d.\n", th_index); + } + /* in-process mutual exclusion */ + EV_PROCESS_MUTEX_UNLOCK; +} + +/* EV_info update function */ +static void +add_ev_info(int th_index, EV_ID id, int fd) { + /* Check storage position of ID information */ + /* beginning of in-process mutual exclusion */ + EV_PROCESS_MUTEX_LOCK; + + int id_index = EV_thread_info[th_index]->num; + EV_assert(id_index < EV_MAX_IDS_IN_THREAD); + + /* Set information */ + EV_thread_info[th_index]->ev_info[id_index].id = id; + EV_thread_info[th_index]->ev_info[id_index].fd = fd; + EV_thread_info[th_index]->num++; + + /* end of in-process mutual exclusion */ + EV_PROCESS_MUTEX_UNLOCK; +} + +/* EV_info search function */ +static int +find_ev_info(int th_index, EV_ID id) { + int i, j, start, end; + int ret = -1; + + /* Search all threads */ + if(th_index == EV_SEARCH_ALL_THREAD) { + start = 0; + end = EV_MAX_THREADS_IN_PROCESS; + } else { + start = th_index; + end = th_index + 1; + } + + /* in-process mutual exclusion */ + EV_PROCESS_MUTEX_LOCK; + + for(j = start; j < end; j++) { + if(EV_thread_info[j] == NULL) { + continue; + } + + for(i = 0; i < EV_thread_info[j]->num; i++) { + if(id == EV_thread_info[j]->ev_info[i].id) { + ret = EV_thread_info[j]->ev_info[i].fd; + break; + } + } + } + + /* Cancel in-process mutual exclusion */ + EV_PROCESS_MUTEX_UNLOCK; + + return ret; +} + +static int +delete_ev_info(EV_ID id) { + int fd = -1; + int i, j; + int found_th_index = -1; + int found_idx = -1; + EV_thread_info_type *th = NULL; + + /* beginning of in-thread mutual exclusion */ + EV_PROCESS_MUTEX_LOCK; + + for(i = 0 ; i < EV_MAX_THREADS_IN_PROCESS && found_idx == -1 ; i++) { + th = EV_thread_info[i]; + if (th == NULL) { + continue; + } + for(j = 0 ; j < th->num ; j++) { + if (th->ev_info[j].id == id) { + fd = th->ev_info[j].fd; + found_th_index = i; + found_idx = j; + break; + } + } + } + + if(found_idx == -1) { + EV_PROCESS_MUTEX_UNLOCK; + return -1; + } + + if (found_idx < th->num - 1) { /* pgr0060 */ + memmove(&(th->ev_info[found_idx]), &(th->ev_info[found_idx+1]), + sizeof(th->ev_info[0]) * (size_t)(th->num - 1 - found_idx)); + } + th->num--; + + /* If everything is deleted */ + if(th->num == 0 && EV_thread_info[found_th_index] != NULL) { + free(EV_thread_info[found_th_index]); + EV_thread_info[found_th_index] = NULL; + } + EV_PROCESS_MUTEX_UNLOCK; + return fd; +} + +/** @} */ +/** @addtogroup EV + * @{ */ + +static EV_ERR +EV_create_flag_in(int th_index, EV_ID flag_id, int is64bit) { + int fd; + + /* Open device driver */ + fd = open(EVK_DEV_NAME, O_RDWR|O_CLOEXEC); + EV_assert(fd >= 0); + + int ret = ioctl(fd, is64bit ? EVK_IOC_CREATE_FLAG64: + EVK_IOC_CREATE_FLAG, flag_id); + int myerrno = errno; + + if(ret < 0) { + if(myerrno == EEXIST) { // LCOV_EXCL_BR_LINE 5: fail safe for glibc function ioctl + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + + close(fd); // LCOV_EXCL_LINE 5: fail safe for glibc function ioctl + EV_DEBUG_ERR("flag_id %x already exists.\n", flag_id); // LCOV_EXCL_LINE 5: fail safe for glibc function ioctl + return EV_ERR_Exist; // LCOV_EXCL_LINE 5: fail safe for glibc function ioctl + } else { + close(fd); + errno = myerrno; + return EV_ERR_Fatal; + } + } + + ret = ioctl(fd, EVK_IOC_SET_POLL, flag_id); + if(ret < 0) { + close(fd); + EV_DEBUG_ERR("set_poll: internal error\n"); + return EV_ERR_Fatal; + } + + add_ev_info(th_index, flag_id, fd); + return EV_OK; +} + +/** @brief Create flag + * + * Create a flag with the given ID. + * Return error if a flag with the same flag ID already exists + * + * @param flag_id [IN]flag ID + * @see EV_ID + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: Specified an invalid flag ID + * @retval EV_ERR_Exist: A flag with the same ID already exists + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_create_flag (EV_ID flag_id) { + EV_ERR err; + int th_index; + + /* Flag ID check */ + if(!EV_ID_IS_FLAG(flag_id) || EV_ID_IS_AUTO_ID(flag_id)) { + EV_DEBUG_ERR("create_flag: Invalid flag_id %x.\n", flag_id); + return EV_ERR_Invalid_ID; + } + + /* Thread information check */ + err = EV_thread_id_check(&th_index, EV_THREAD_INFO_CREATE); + if(err != EV_OK) { + return err; + } + + EV_DEBUG_INFO("EV_create_flag (th_index=%d)\n", th_index); + + /* case of already created */ + int fd = find_ev_info(th_index, flag_id); + if(fd >= 0) { + EV_DEBUG_ERR("create_flag: You already created flag_id %x.\n", flag_id); + return EV_ERR_Exist; + } + + err = EV_create_flag_in(th_index, flag_id, 0); + if (EV_OK != err) { + free_thread_buffer(th_index); + } + + return err; +} + +/** @brief Create 64-bit flag + * + * Create a 64-bit flag with the given ID. + * Return error if a flag with the same flag ID already exists + * + * @param flag_id [IN]64-bit flag ID + * @see EV_ID + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: Specified an invalid 64-bit flag ID + * @retval EV_ERR_Exist: A 64-bit flag with same ID already exists + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_create_flag64(EV_ID flag_id) { + EV_ERR err; + int th_index; + + if(!EV_ID_IS_FLAG64(flag_id) || EV_ID_IS_AUTO_ID(flag_id)) { + EV_DEBUG_ERR("create_flag: Invalid flag_id %x.\n", flag_id); + return EV_ERR_Invalid_ID; + } + + /* Thread information check */ + err = EV_thread_id_check(&th_index, EV_THREAD_INFO_CREATE); + if(err != EV_OK) { + return err; + } + + int fd = find_ev_info(th_index, flag_id); + if(fd >= 0) { + EV_DEBUG_ERR("create_flag: You already created flag_id %x.\n", flag_id); + return EV_ERR_Exist; + } + + err = EV_create_flag_in(th_index, flag_id, 1); + if (EV_OK != err) { + free_thread_buffer(th_index); + } + + return err; +} + +/** @brief Create flag (auto-assign ID) + * + * Automatically assign a flag ID and creates a flag. + * Same as EV_create_flag(), except that ID is automatically assigned. + * + * @param flag_id [OUT]Area for storing the assigned flag ID + * + * @see EV_create_flag + */ +EV_ERR +EV_create_flag_auto_id(EV_ID *flag_id) { + EV_assert(flag_id != NULL); + + EV_ERR err; + int fd, th_index; + fd = open(EVK_DEV_NAME, O_RDWR|O_CLOEXEC); + EV_assert(fd >= 0); + + int ret = ioctl(fd, EVK_IOC_ALLOC_FLAG_ID, flag_id); + close(fd); + EV_assert(ret == 0); + + /* Thread information check */ + err = EV_thread_id_check(&th_index, EV_THREAD_INFO_CREATE); + if(err != EV_OK) { + *flag_id = EV_NO_ID; + return err; + } + + err = EV_create_flag_in(th_index, *flag_id, 0); + if (err != EV_OK) { + free_thread_buffer(th_index); + + *flag_id = EV_NO_ID; + return EV_ERR_Fatal; + } + return EV_OK; +} + +/** @brief Create 64-bit flag(auto-assign ID) + * + * Automatically assign a 64-bit flag ID and creates a 64-bit flag. + * Same as EV_create_flag64(), except that ID is automatically assigned. + * + * @param flag_id [OUT]Area for storing the assigned 64-bit flag ID + * + * @see EV_create_flag64 + */ +EV_ERR +EV_create_flag64_auto_id(EV_ID *flag_id) { + EV_assert(flag_id != NULL); + + EV_ERR err; + int fd, th_index; + fd = open(EVK_DEV_NAME, O_RDWR|O_CLOEXEC); + EV_assert(fd >= 0); + + int ret = ioctl(fd, EVK_IOC_ALLOC_FLAG64_ID, flag_id); + close(fd); + EV_assert(ret == 0); + + /* Thread information check */ + err = EV_thread_id_check(&th_index, EV_THREAD_INFO_CREATE); + if(err != EV_OK) { + *flag_id = EV_NO_ID; + return err; + } + + err = EV_create_flag_in(th_index, *flag_id, 1); + if (err != EV_OK) { + free_thread_buffer(th_index); + + *flag_id = EV_NO_ID; + return EV_ERR_Fatal; + } + return EV_OK; +} + +static EV_ERR +EV_create_queue_in(int th_index, EV_ID queue_id, UINT8 length, + UINT16 max_bytes, EV_Message_Queue_Type type) { + int fd; + fd = open(EVK_DEV_NAME, O_RDWR|O_CLOEXEC); + EV_assert(fd >= 0); + + EVK_Message_Queue_Request req; + req.queueID = queue_id; + req.length = length; + req.max_bytes = max_bytes; + req.type = type; + + int ret = ioctl(fd, EVK_IOC_CREATE_MESSAGE_QUEUE, &req); + int myerrno = errno; + if (ret < 0) { + if (myerrno == EEXIST) { // LCOV_EXCL_BR_LINE 5: fail safe for glibc function ioctl + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + + close(fd); // LCOV_EXCL_LINE 5: fail safe for glibc function ioctl + EV_DEBUG_ERR("queue %x already exists.\n", queue_id); // LCOV_EXCL_LINE 5: fail safe for glibc function ioctl + return EV_ERR_Exist; // LCOV_EXCL_LINE 5: fail safe for glibc function ioctl + } else { + close(fd); + errno = myerrno; + //EV_perror("create queue"); + return EV_ERR_Fatal; + } + } + + ret = ioctl(fd, EVK_IOC_SET_POLL, queue_id); + if (ret < 0) { + close(fd); + EV_DEBUG_ERR("set_poll: internal error\n"); + return EV_ERR_Fatal; + } + + add_ev_info(th_index, queue_id, fd); + return EV_OK; +} + +/** @brief message event queue creation + * + * Create a queue of message event with the specified ID. + * Return error if a queue with the same ID already exists. + * + * A memory area corresponding to the specified maximum number of bytes x queue length is allocated dynamically. + * + * @param queue_id [IN] Message queue ID + * @param length [IN] Message queue length + * @param max_bytes [IN] - Maximum number of bytes per message + * @param type [IN] Type of action to take when more events are received when the queue is full + * @see EV_ID + * @see ev_message_queue_type + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: Specified an invalid flag ID + * @retval EV_ERR_Exist: A flag with the same ID already exists + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_create_queue(EV_ID queue_id, UINT8 length, UINT16 max_bytes, + EV_Message_Queue_Type type) { + EV_ERR err; + int th_index; + + if(!EV_ID_IS_QUEUE(queue_id) || EV_ID_IS_AUTO_ID(queue_id)) { + EV_DEBUG_ERR("create_queue: Invalid queue_id %x was specified.\n", + queue_id); + return EV_ERR_Invalid_ID; + } + + /* Thread information check */ + err = EV_thread_id_check(&th_index, EV_THREAD_INFO_CREATE); + if(err != EV_OK) { + return err; + } + + int fd = find_ev_info(th_index, queue_id); + if(fd >= 0) { + EV_DEBUG_ERR("create_queue: You already created queue_id %x.\n", + queue_id); + return EV_ERR_Exist; + } + + err = EV_create_queue_in(th_index, queue_id, length, max_bytes, type); + if (EV_OK != err) { + free_thread_buffer(th_index); + } + + return err; +} + +/** @brief message event queue creation(auto-assign ID) + * + * Automatically assigns a queue ID and creates a queue for message events. + * Same as EV_create_queue(), except that ID is automatically assigned. + * + * @param queue_id [OUT] Area for storing the assigned flag ID + * @param length [IN] Message queue length + * @param max_bytes [IN] - Maximum number of bytes per message + * @param type [IN] Type of action to take when more events are received when the queue is full + * + * @see EV_create_queue + */ +EV_ERR +EV_create_queue_auto_id(EV_ID *queue_id, UINT8 length, UINT16 max_bytes, + EV_Message_Queue_Type type) { + int th_index; + + EV_assert(queue_id != NULL); + EV_ERR err; + int fd; + fd = open(EVK_DEV_NAME, O_RDWR|O_CLOEXEC); + EV_assert(fd >= 0); + + int ret = ioctl(fd, EVK_IOC_ALLOC_QUEUE_ID, queue_id); + close(fd); + EV_assert(ret == 0); + + /* Thread information check */ + err = EV_thread_id_check(&th_index, EV_THREAD_INFO_CREATE); + if(err != EV_OK) { + *queue_id = EV_NO_ID; + return err; + } + + err = EV_create_queue_in(th_index, *queue_id, length, max_bytes, + type); + if (err != EV_OK) { + free_thread_buffer(th_index); + + *queue_id = EV_NO_ID; + return EV_ERR_Fatal; + } + return EV_OK; +} + +/** @brief Deleting flag event + * + * Delete the flag with the specified ID. + * Only flags created by this process can be deleted. + * + * - differences in kernel versions + * EVK_destroy_flag can be used to delete any existing message event queue. + * + * @note The program wakes up that waiting for this queue (poll or wait) + * due to deletion. + * + * @param flag_id [IN] ID of flag + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: The flag with the specified ID does not exist, + * Or it is not a flag created by invoking process + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_destroy_flag(EV_ID flag_id) { + int fd = delete_ev_info(flag_id); + if (fd < 0) { + EV_DEBUG_ERR("You haven't created flag/queue_id %x.\n", flag_id); + return EV_ERR_Invalid_ID; + } + + int ret = ioctl(fd, EVK_IOC_DESTROY_QUEUE, flag_id); + int myerrno = errno; + close(fd); + if (ret < 0) { + if (myerrno == ENOENT) { + EV_DEBUG_ERR("destroy: no such ID %x\n", flag_id); + return EV_ERR_Invalid_ID; + } else { + errno = myerrno; + EV_perror("destroy"); + return EV_ERR_Fatal; + } + } + return EV_OK; +} + +/** @brief Delete message event queue + * + * Delete the message event queue with the specified ID. + * Only message event queues created by this process can be deleted. + * + * - differences in kernel versions + * EVK_destroy_queue can be used to delete any existing message event queue. + * + * @note The program wakes up that waiting for this queue (poll or wait) + * due to deletion. + * + * @param flag_id [IN] Message event queue ID + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: The message queue with the specified ID does not exist, + * or there is no message event queue created by this process. + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_destroy_queue(EV_ID queue_id) { + return EV_destroy_flag(queue_id); +} + +static EV_ERR +EV_get_flag_in(EV_ID flag_id, EV_Flag *flag, int peek_only, int wait) { + EV_assert(flag != NULL); + flag->flagID = EV_NO_ID; + flag->bits = 0; + + if (!EV_ID_IS_FLAG(flag_id)) { + EV_DEBUG_ERR("get_flag: %x is not a flag_id.\n", flag_id); + return EV_ERR_Invalid_ID; + } + + int fd = find_ev_info(EV_SEARCH_ALL_THREAD, flag_id); + if(fd < 0) { + EV_DEBUG_ERR("You have not created flag_id %x.\n", flag_id); + return EV_ERR_Invalid_ID; + } + + EV_Event ev; + ev.type = EV_EVENT_Flag; + ev.u.flag.flagID = flag_id; + ev.u.flag.bits = 0; + int ret = ioctl( + fd, + (peek_only ? EVK_IOC_PEEK_EVENT : (wait ? EVK_IOC_WAIT_EVENT : EVK_IOC_GET_EVENT)), + &ev); + + int myerrno = errno; + if (ret < 0) { + if (myerrno == ENOENT) { + EV_DEBUG_ERR("get_flag: No such flag_id %x.\n", flag_id); + return EV_ERR_Invalid_ID; + } + else if (myerrno == EINTR) { + EV_DEBUG_ERR("get_flag: Interrupted\n"); + return EV_ERR_Interrupted; + } else { + errno = myerrno; + EV_perror("get flag"); + return EV_ERR_Fatal; + } + } + + if (ev.type == EV_EVENT_Flag) { + flag->flagID = ev.u.flag.flagID; + flag->bits = ev.u.flag.bits; + } + return EV_OK; +} + +static EV_ERR +EV_get_flag64_in(EV_ID flag_id, EV_Flag64 *flag, int peek_only, int wait) { + EV_assert(flag != NULL); + flag->flagID = EV_NO_ID; + flag->bits = 0; + + if (!EV_ID_IS_FLAG64(flag_id)) { + EV_DEBUG_ERR("get_flag: %x is not a flag_id.\n", flag_id); + return EV_ERR_Invalid_ID; + } + + int fd = find_ev_info(EV_SEARCH_ALL_THREAD, flag_id); + if (fd < 0) { + EV_DEBUG_ERR("You have not created flag_id %x.\n", flag_id); + return EV_ERR_Invalid_ID; + } + + EV_Event ev; + ev.type = EV_EVENT_Flag64; + ev.u.flag64.flagID = flag_id; + ev.u.flag64.bits = 0; + int ret = ioctl( + fd, + (peek_only ? EVK_IOC_PEEK_EVENT : (wait ? EVK_IOC_WAIT_EVENT : EVK_IOC_GET_EVENT)), + &ev); + + int myerrno = errno; + if (ret < 0) { + if (myerrno == ENOENT) { + EV_DEBUG_ERR("get_flag: No such flag_id %x.\n", flag_id); + return EV_ERR_Invalid_ID; + } + else if (myerrno == EINTR) { + EV_DEBUG_ERR("get_flag: Interrupted\n"); + return EV_ERR_Interrupted; + } else { + errno = myerrno; + EV_perror("get flag"); + return EV_ERR_Fatal; + } + } + + if (ev.type == EV_EVENT_Flag64) { + flag->flagID = ev.u.flag64.flagID; + flag->bits = ev.u.flag64.bits; + } + return EV_OK; +} + +/** @brief Get flag event(non-block) + * + * Get the flag event with the specified ID, and clears the flag. + * Even if there is no event, it returns immediately. + * If there are no events, EV_NO_ID is stored in flag->flagID. + * A flag->bits of 0 can also be used to determine no events. + * Only flags created by this process can be gotten. + * + * @param flag_id [IN] Message event queue ID + * @param flag [OUT] Flag Structure + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: The flag with the specified ID does not exist, + * Or it is not a flag created by invoking process + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_get_flag(EV_ID flag_id, EV_Flag *flag) { + return EV_get_flag_in(flag_id, flag, 0, 0); +} + +/** @brief Get 64bit flag event(non-block) + * + * Get the 64-bit flag event with the specified ID, and clears the 64-bit flag. + * Even if there is no event, it returns immediately. + * If there are no events, EV_NO_ID is stored in flag->flagID. + * A flag->bits of 0 can also be used to determine no events. + * Only flags created by this process can be gotten. + * Be sure to specify the flag ID created by specifying 64-bits. + * + * @param flag_id [IN] Message event queue ID + * @param flag [OUT] 64-bit flag struct + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: The flag with the specified ID does not exist, + * Or it is not a flag created by invoking process + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_get_flag64(EV_ID flag_id, EV_Flag64 *flag) { + return EV_get_flag64_in(flag_id, flag, 0, 0); +} + +/** @brief Get flag event(block) + * + * Get the flag event with the specified ID, and clear the flag. + * If there is no event, block until an event is received. + * However, if the interrupt is interrupted by a signal interrupt, EV_ERR_Interrupted is returned. + * If the flag is deleted while waiting, the wait is suspended + * and EV_ERR_Invalid_ID is returned. + * When interrupted, EV_NO_ID is stored in flag->flagID. + * A flag->bits of 0 can also be judged to have been interrupted. + * + * @param flag_id [IN] Message event queue ID + * @param flag [OUT] Flag Structure + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: The flag with the specified ID does not exist, + * Or it is not a flag created by invoking process + * @retval EV_ERR_Interrupted: Interrupted by a signal interrupt + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_wait_flag(EV_ID flag_id, EV_Flag *flag) { + return EV_get_flag_in(flag_id, flag, 0, 1); +} + +/** @brief Get 64bit flag event(block) + * + * Get the 64-bit flag event with the specified ID, and clear the 64-bit flag. + * If there is no event, block until an event is received. + * However, if the interrupt is interrupted by a signal interrupt, EV_ERR_Interrupted is returned. + * If the flag is deleted while waiting, the wait is suspended + * and EV_ERR_Invalid_ID is returned. + * When interrupted, EV_NO_ID is stored in flag->flagID. + * A flag->bits of 0 can also be judged to have been interrupted. + * Be sure to specify the flag ID created by specifying 64 bits. + * + * @param flag_id [IN] Message event queue ID + * @param flag [OUT] 64-bit flag structure + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: The flag with the specified ID does not exist, + * Or it is not a flag created by invoking process + * @retval EV_ERR_Interrupted: Interrupted by a signal interrupt + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_wait_flag64(EV_ID flag_id, EV_Flag64 *flag) { + return EV_get_flag64_in(flag_id, flag, 0, 1); +} + +/** @brief Get flag event(non-destructive) + * + * Get the flag event with the specified ID non-destructively. + * Even if there is no event, it returns immediately. + * If there are no events, EV_NO_ID is stored in flag->flagID. + * A flag->bits of 0 can also be used to determine no events. + * + * @param flag_id [IN] Message event queue ID + * @param flag [OUT] Flag Structure + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: The flag with the specified ID does not exist, + * Or it is not a flag created by invoking process + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_peek_flag(EV_ID flag_id, EV_Flag *flag) { + return EV_get_flag_in(flag_id, flag, 1, 0); +} + +/** @brief Get 64bit flag event(non-destructive) + * + * Gets the 64-bit flag event with the specified ID non-destructively. + * Even if there is no event, it returns immediately. + * If there are no events, EV_NO_ID is stored in flag->flagID. + * A flag->bits of 0 can also be used to determine no events. + * + * @param flag_id [IN] Message event queue ID + * @param flag [OUT] 64-bit flag structure + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: The flag with the specified ID does not exist, + * Or it is not a flag created by invoking process + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_peek_flag64(EV_ID flag_id, EV_Flag64 *flag) { + return EV_get_flag64_in(flag_id, flag, 1, 0); +} + +static EV_ERR +EV_get_message_in(EV_ID queue_id, EV_Message *message, UINT32 senderInfo, + UINT32 length, const void *compare_bytes, + int peek_only, int wait) { + EV_assert(message != NULL); + message->queueID = EV_NO_ID; + message->senderInfo = 0; + message->length = 0; + + if (!EV_ID_IS_QUEUE(queue_id)) { + EV_DEBUG_ERR("get_message: Invalid queue_id %x\n", queue_id); + return EV_ERR_Invalid_ID; + } + + int fd = find_ev_info(EV_SEARCH_ALL_THREAD, queue_id); + if(fd < 0) { + EV_DEBUG_ERR("You have not created queue_id %x.\n", queue_id); + return EV_ERR_Invalid_ID; + } + + EV_Event ev; + ev.type = EV_EVENT_Message; + ev.u.message.queueID = queue_id; + ev.u.message.senderInfo = senderInfo; + if(length > 0 && compare_bytes != NULL) { + ev.u.message.length = length; + memcpy(ev.u.message.message, compare_bytes, length); + } else { + ev.u.message.length = 0; + } + + int ret = ioctl( + fd, + (peek_only ? EVK_IOC_PEEK_EVENT : (wait ? EVK_IOC_WAIT_EVENT : EVK_IOC_GET_EVENT)), + &ev); + + int myerrno = errno; + if (ret < 0) { + if (myerrno == ENOENT) { + EV_DEBUG_ERR("No such queue_id %x\n", queue_id); + return EV_ERR_Invalid_ID; + } + else if (myerrno == EINTR) { + EV_DEBUG_INFO("Interrupted.\n"); + return EV_ERR_Interrupted; + } else { + errno = myerrno; + EV_perror("get message"); + return EV_ERR_Fatal; + } + } + + if(ev.type == EV_EVENT_Message) { + message->queueID = ev.u.message.queueID; + message->senderInfo = ev.u.message.senderInfo; + message->length = ev.u.message.length; + memcpy(message->message, ev.u.message.message, + ev.u.message.length); + } + + return EV_OK; +} + +/** @brief Get message events(non-block) + * + * Get one message event from the queue with the specified ID. + * Even if there is no event, it returns immediately. + * If there are no events, EV_NO_ID is stored in message-> queue_id. + * The acquired message is deleted from the queue. + * + * @param queue_id [IN] Message event queue ID + * @param message [OUT] Message Event Structure + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: Queue with specified ID does not exist + * Or not a message event queue created by invoking process + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_get_message(EV_ID queue_id, EV_Message *message) { + return EV_get_message_in(queue_id, message, 0, 0, NULL, 0, 0); +} + +/** @brief Get message event(block) + * + * Get one message event from the queue with the specified ID. + * If there is no event, block until an event is received. + * However, if the interrupt is interrupted by a signal interrupt, EV_ERR_Interrupted is returned. + * If the queue is deleted while waiting, the waiting is suspended, + * EV_ERR_Invalid_ID is returned. + * When interrupted, EV_NO_ID is stored in message-> queue_id. + * + * @param queue_id [IN] Message event queue ID + * @param message [OUT] Message Event Structure + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: Queue with specified ID does not exist + * Or not a message event queue created by invoking process + * @retval EV_ERR_Interrupted: Interrupted by a signal interrupt + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_wait_message(EV_ID queue_id, EV_Message *message) { + return EV_get_message_in(queue_id, message, 0, 0, NULL, 0, 1); +} + +/** @brief Get message event(non-destructive) + * + * Get one message event queue of the specified ID non-destructively. + * Even if there is no event, it returns immediately. + * If there are no events, EV_NO_ID is stored in message-> queue_id. + * Same as EV_get_message(), except that the retrieved message remains in the queue. + * + * @param queue_id [IN] Message event queue ID + * @param message [OUT] Message Event Structure + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: Queue with specified ID does not exist + * Or not a message event queue created by invoking process + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_peek_message(EV_ID queue_id, EV_Message *message) { + return EV_get_message_in(queue_id, message, 0, 0, NULL, 1, 0); +} + +static EV_ERR +EV_get_next_event_in(EV_Event *ev, int peek_only) { + int i, th_index; + EV_ERR err; + EVK_Next_Event_Query query; + + EV_assert(ev != NULL); + ev->type = EV_EVENT_None; + + bzero(&query, sizeof(query)); + + err = EV_thread_id_check(&th_index, EV_THREAD_INFO_PEEK); + if(err != EV_OK) { + return err; + } + + EV_PROCESS_MUTEX_LOCK; + query.num = EV_thread_info[th_index]->num; + for(i = 0 ; i < query.num ; i++) { + query.ids[i] = EV_thread_info[th_index]->ev_info[i].id; + } + EV_PROCESS_MUTEX_UNLOCK; + + if (query.num == 0) { + return EV_OK; + } + + int fd; + fd = open(EVK_DEV_NAME, O_RDWR|O_CLOEXEC); + EV_assert(fd >= 0); + + int ret = ioctl( + fd, + (peek_only ? EVK_IOC_PEEK_NEXT_EVENT: EVK_IOC_GET_NEXT_EVENT), + &query); + + int myerrno = errno; + close(fd); + + if (ret < 0) { + errno = myerrno; + EV_perror("get_next_event"); + return EV_ERR_Fatal; + } + memcpy(ev, &(query.ev), sizeof(*ev)); + return EV_OK; +} + +/** @brief Get the first event that arrived(non-block) + * + * Get the first arrival of a flag created by invoking process or an event + * that occurred in the message queue. + * If there are no events, EV_EVENT_None is stored in the ev->type and returned immediately. + * + * @param ev [OUT] Event Structure + * Whether the acquired event type is flag or message is determined + * by ev->type is EV_EVENT_Flag or EV_EVENT_Message. + * + * @retval EV_OK: Normal completion + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_get_next_event(EV_Event *ev) { + return EV_get_next_event_in(ev, 0); +} + +/** @brief Get the first event that arrived(non-destructive) + * + * Get the first arrival of a flag created by invoking process or an event + * that occurred in the message queue non-destructively. + * The next call to EV_get_next_event() or EV_peek_next_event(), + * return the same event as long as no other program gets it. + * If there are no events, EV_EVENT_None is stored in the ev->type and returned immediately. + * + * @param ev [OUT] Event Structure + * Whether the acquired event flag or message is a message is determined + * by whether ev->type is EV_EVENT_Flag or EV_EVENT_Message. + * + * @retval EV_OK: Normal completion + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_peek_next_event(EV_Event *ev) { + return EV_get_next_event_in(ev, 1); +} + +/** @brief Get message event(search by source info) + * + * If there is an event whose source information matches + * in the message event queue of the specified ID,it is gotten and deleted from the queue. + * If there are no such messages, + * EV_NO_ID is stored in message->queue_id, and the system call returns immediately. + * + * @param queue_id [IN] Message event queue ID + * @param senderInfo [IN] Source Info + * @param message [OUT] Message Event Structure + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: Queue with specified ID does not exist + * Or not a message event queue created by invoking process + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_find_message_by_sender(EV_ID queue_id, UINT32 senderInfo, + EV_Message *message) { + EV_assert(message != NULL); + EV_assert(senderInfo != 0); + return EV_get_message_in(queue_id, message, senderInfo, 0, NULL, 0, 0); +} + +/** @brief Get message event(search by content) + * + * If there is an event with byte sequence matching the specified bytes from the beginning + * in the message event queue of the specified ID,it is gotten and deleted from the queue. + * If there are no such messages, + * EV_NO_ID is stored in message->queue_id, and the system call returns immediately. + * + * @param queue_id [IN] Message event queue ID + * @param bytes [IN] Bytes to compare + * @param compare_bytes [IN] Byte sequence to compare content against + * @param message [OUT] Message Event Structure + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: Queue with specified ID does not exist + * Or not a message event queue created by invoking process + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_find_message_by_content(EV_ID queue_id, + UINT16 bytes, const void *compare_bytes, + EV_Message *message) { + EV_assert(message != NULL); + EV_assert(bytes <= EV_MAX_MESSAGE_LENGTH); + EV_assert(compare_bytes != NULL); + + return EV_get_message_in(queue_id, message, 0, bytes, + compare_bytes, 0, 0); +} + +/** @brief Set flag event + * + * Set the flag with the specified ID. + * + * @param queue_id [IN] Flag ID + * @param bits [IN] Flag bit-pattern + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: The flag with the specified ID does not exist. + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_set_flag(EV_ID flag_id, UINT32 bits) { + if (!EV_ID_IS_FLAG(flag_id)) { + EV_DEBUG_ERR("set_flag: %x is not a valid flag_id.\n", flag_id); + return EV_ERR_Invalid_ID; + } + + int fd = open(EVK_DEV_NAME, O_RDWR|O_CLOEXEC); + EV_assert(fd >= 0); + + EV_Flag flag; + flag.flagID = flag_id; + flag.bits = bits; + + int ret = ioctl(fd, EVK_IOC_STORE_FLAG, &flag); + int myerrno = errno; + close(fd); + + if (ret < 0) { + if (myerrno == ENOENT) { + EV_DEBUG_WARNING("set_flag: No such flag_id %x.\n", flag_id); + return EV_ERR_Invalid_ID; + } + errno = myerrno; + EV_perror("set flag"); + return EV_ERR_Fatal; + } + return EV_OK; +} + +/** @brief Set 64bit flag event + * + * Set the flag with the specified ID. + * + * @param queue_id [IN] Flag ID + * @param bits [IN] Bit pattern of 64-bit flag + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: The flag with the specified ID does not exist. + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_set_flag64(EV_ID flag_id, UINT64 bits) { + if (!EV_ID_IS_FLAG64(flag_id)) { + EV_DEBUG_ERR("set_flag: %x is not a valid flag_id.\n", flag_id); + return EV_ERR_Invalid_ID; + } + + int fd = open(EVK_DEV_NAME, O_RDWR|O_CLOEXEC); + EV_assert(fd >= 0); + + EV_Flag64 flag; + flag.flagID = flag_id; + flag.bits = bits; + + int ret = ioctl(fd, EVK_IOC_STORE_FLAG64, &flag); + int myerrno = errno; + close(fd); + + if (ret < 0) { + if (myerrno == ENOENT) { + EV_DEBUG_ERR("set_flag: No such flag_id %x.\n", flag_id); + return EV_ERR_Invalid_ID; + } + + errno = myerrno; + EV_perror("set flag"); + return EV_ERR_Fatal; + } + + return EV_OK; +} + +/** @brief Send Messaging Event + * + * Send a message event to the specified queue ID. + * + * @param queue_id [IN] Queue ID + * @param bytes [IN] Bytes to send + * @param buf [IN] Pointer to the byte sequence to send + * @param senderInfo [IN] Source info + * Specify this option to identify applications, etc. + * When not used, specify 0. + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: Message event queue with specified ID does not exist + * @retval EV_ERR_Busy: Queue overflow + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_send_message(EV_ID queue_id, UINT16 bytes, const void *buf, UINT32 senderInfo) { + EV_assert(buf != NULL); + EV_assert(bytes <= EV_MAX_MESSAGE_LENGTH); + if (!EV_ID_IS_QUEUE(queue_id)) { + EV_DEBUG_ERR("send_message: %x is not a valid queue_id.\n", queue_id); + return EV_ERR_Invalid_ID; + } + + + /* + * Open fd at the first time of send_message in process, + * and continue to use the fd with it open after that. + * Reason: + * - Prevent frequent use of open/close system calls. + * - If the process is nonresident, the fd is close after the process is terminated. + * - Even for resident processes, there is no problem because processes + * that use event library normally continue to use event library + * from the beginning to the end. + */ + static int fd = -1; + EV_PROCESS_MUTEX_LOCK; + if (fd < 0) { + fd = open(EVK_DEV_NAME, O_RDWR|O_CLOEXEC); + if (fd < 0) { // LCOV_EXCL_BR_LINE 5: fail safe for glibc function open + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + + EV_PROCESS_MUTEX_UNLOCK; // LCOV_EXCL_LINE 5: fail safe for glibc function open + return EV_ERR_Fatal; // LCOV_EXCL_LINE 5: fail safe for glibc function open + } + fcntl(fd, F_SETFD, FD_CLOEXEC|(fcntl(fd, F_GETFD, 0))); + } + + EV_Message msg; + msg.queueID = queue_id; + msg.senderInfo = senderInfo; + msg.length = bytes; + memcpy(msg.message, buf, bytes); + + int ret = ioctl(fd, EVK_IOC_STORE_MESSAGE, &msg); + int myerrno = errno; + EV_PROCESS_MUTEX_UNLOCK; + + if (ret < 0) { + if (myerrno == ENOENT) { + EV_DEBUG_WARNING("send_message: No such queue_id %x.\n", queue_id); + return EV_ERR_Invalid_ID; + } else if (myerrno == EBUSY) { + EV_DEBUG_WARNING("send_message: queue_id %x returned BUSY.\n", queue_id); + return EV_ERR_Busy; + } + + errno = myerrno; + EV_perror("send message"); + return EV_ERR_Fatal; + } + + return EV_OK; +} + +/** @brief Get fd for poll flag event + * + * Get file descriptor (FD) that used to wait for a flag + * with the specified ID in a poll/select. + * Only flags created by invoked process can be specified. + * + * This FD can only be used to specify a poll/select. + * Subsequent operations are not guaranteed if any other operations are performed. + * When use poll, only POLLIN can be specified in events. + * When use select, you can only check if it is readable. + * + * If the same flag_id is called more than once, + * The same FD is returned each time (unless there is a destroy/create during that time). + * + * - differences in kernel versions + * - This API is not provided in the EVK. + * + * @note If the flag is deleted during poll/select using the FD gotten by the API, + * the poll/select is exited. + * POLLERR is set as event for poll. + * + * @param flag_id [IN] Flag ID + * @param fd [OUT] Pointer to the area to store the file descriptor + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: An invalid flag ID was specified. + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_get_flag_fd(EV_ID flag_id, int *fd) { + EV_assert(fd != NULL); + *fd = -1; + if ((!EV_ID_IS_FLAG(flag_id))&& (!EV_ID_IS_FLAG64(flag_id))) { + EV_DEBUG_ERR("get_flag_fd: %x is not a valid flag_id.\n", flag_id); + return EV_ERR_Invalid_ID; + } + + *fd = find_ev_info(EV_SEARCH_ALL_THREAD, flag_id); + if (*fd < 0) { + EV_DEBUG_ERR("You have not created flag_id %x.\n", flag_id); + return EV_ERR_Invalid_ID; + } + + return EV_OK; +} + +/** @brief Get fd for message event queue poll + * + * Get file descriptor (FD) that used to wait for a queue + * with the specified ID in a poll/select. + * Only message event queues created by invoked process can be specified. + * + * This FD can only be used to specify a poll/select. + * Subsequent operations are not guaranteed if any other operations are performed. + * When use poll, only POLLIN can be specified in events. + * When use select, you can only check if it is readable. + * + * If the same queue_id is called more than once, + * The same FD is returned each time (unless there is a destroy/create during that time). + * + * - differences in kernel versions + * - This API is not provided in the EVK. + * + * @note If the queue is deleted during poll/select using the FD gotten by the API, + * the poll/select is exited. + * POLLERR is set as event for poll. + * + * @param queue_id [IN] Message event queue ID + * @param fd [OUT] Pointer to the area to store the file descriptor + * + * @retval EV_OK: Normal completion + * @retval EV_ERR_Invalid_ID: An invalid flag ID was specified. + * @retval Otherwise: FATAL error + */ +EV_ERR +EV_get_queue_fd(EV_ID queue_id, int *fd) { + EV_assert(fd != NULL); + *fd = -1; + if (!EV_ID_IS_QUEUE(queue_id)) { + EV_DEBUG_ERR("get_queue_fd: %x is not a valid queue_id.\n", + queue_id); + return EV_ERR_Invalid_ID; + } + + *fd = find_ev_info(EV_SEARCH_ALL_THREAD, queue_id); + if (*fd < 0) { + EV_DEBUG_ERR("You have not created queue_id %x.\n", queue_id); + return EV_ERR_Invalid_ID; + } + return EV_OK; +} + +/* \~english Functions that specify the module ID (16 bits) instead of the flag ID and queue ID */ +EV_ID EV_moduleID_to_flagID(UINT16 mID) +{ + return EV_Flag_ID_Base(mID); +} + +EV_ID EV_moduleID_to_flag64ID(UINT16 mID) +{ + return EV_Flag64_ID_Base(mID); +} + +EV_ID EV_moduleID_to_queueID(UINT16 mID) +{ + return EV_Queue_ID_Base(mID); +} + +EV_ERR EV_create_flag_by_mID(UINT16 mID) +{ + return EV_create_flag(EV_moduleID_to_flagID(mID)); +} + +EV_ERR EV_create_flag64_by_mID(UINT16 mID) +{ + return EV_create_flag64(EV_moduleID_to_flag64ID(mID)); +} + +EV_ERR EV_create_queue_by_mID(UINT16 mID, UINT8 length,UINT16 max_bytes, + EV_Message_Queue_Type type) +{ + return EV_create_queue(EV_moduleID_to_queueID(mID), length, max_bytes, type); +} + +EV_ERR EV_destroy_flag_by_mID(UINT16 mID) +{ + return EV_destroy_flag(EV_moduleID_to_flagID(mID)); +} + +EV_ERR EV_destroy_queue_by_mID(UINT16 mID) +{ + return EV_destroy_queue(EV_moduleID_to_queueID(mID)); +} + +EV_ERR EV_set_flag_by_mID(UINT16 mID, UINT32 bits) +{ + return EV_set_flag(EV_moduleID_to_flagID(mID), bits); +} + +EV_ERR EV_set_flag64_by_mID(UINT16 mID, UINT64 bits) +{ + return EV_set_flag64(EV_moduleID_to_flag64ID(mID), bits); +} + +EV_ERR EV_send_message_by_mID(UINT16 mID, UINT16 bytes, const void *message, + UINT32 senderInfo) +{ + return EV_send_message(EV_moduleID_to_queueID(mID), + bytes, message, senderInfo); +} +/** @} */ |