Initial commit

This commit is contained in:
PProvost
2020-05-11 08:55:07 -06:00
commit 852421fda0
264 changed files with 54459 additions and 0 deletions

40
.gitattributes vendored Executable file
View File

@@ -0,0 +1,40 @@
.git* export-ignore
.hooks* export-ignore
# Custom attribute to mark sources as using our C code style.
[attr]our-c-style whitespace=tab-in-indent eol=lf format.clang-format-6.0
# Custom attribute to mark sources as generated.
# Do not perform whitespace checks. Do not format.
[attr]generated whitespace=-tab-in-indent,-indent-with-non-tab -format.clang-format-6.0
bootstrap eol=lf
configure eol=lf
*.[1-9] eol=lf
*.bash eol=lf
*.sh eol=lf
*.sh.in eol=lf
*.bat eol=crlf
*.bat.in eol=crlf
*.sln eol=crlf
*.vcproj eol=crlf
*.pfx -text
*.png -text
*.png.in -text
*.c our-c-style
*.cc our-c-style
*.cpp our-c-style
*.cu our-c-style
*.cxx our-c-style
*.h our-c-style
*.hh our-c-style
*.hpp our-c-style
*.hxx our-c-style
*.notcu our-c-style
*.cmake whitespace=tab-in-indent
*.rst whitespace=tab-in-indent conflict-marker-size=79
*.txt whitespace=tab-in-indent

14
.gitignore vendored Normal file
View File

@@ -0,0 +1,14 @@
.vscode/
_deps/
build/
CMakeFiles/
CMakeScripts/
CMakeLists.txt.user
CMakeCache.txt
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake

44
CMakeLists.txt Normal file
View File

@@ -0,0 +1,44 @@
cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
# Set up the project
project(threadx
VERSION 6.0.0
LANGUAGES C ASM
)
if(NOT DEFINED THREADX_ARCH)
message(FATAL_ERROR "Error: THREADX_ARCH not defined")
endif()
if(NOT DEFINED THREADX_TOOLCHAIN)
message(FATAL_ERROR "Error: THREADX_TOOLCHAIN not defined")
endif()
# Define our target library and an alias for consumers
add_library(${PROJECT_NAME})
add_library("azrtos::${PROJECT_NAME}" ALIAS ${PROJECT_NAME})
# A place for generated/copied include files (no need to change)
set(CUSTOM_INC_DIR ${CMAKE_CURRENT_BINARY_DIR}/custom_inc)
# Pick up the port specific variables and apply them
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/ports/${THREADX_ARCH}/${THREADX_TOOLCHAIN})
# Pick up the common stuff
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/common)
# If the user provided an override, copy it to the custom directory
if (NOT TX_USER_FILE)
message(STATUS "Using default tx_user.h file")
set(TX_USER_FILE ${CMAKE_CURRENT_LIST_DIR}/common/inc/tx_user_sample.h)
else()
message(STATUS "Using custom tx_user.h file from ${UX_USER_FILE}")
endif()
configure_file(${TX_USER_FILE} ${CUSTOM_INC_DIR}/tx_user.h COPYONLY)
target_include_directories(${PROJECT_NAME}
PUBLIC
${CUSTOM_INC_DIR}
)
target_compile_definitions(${PROJECT_NAME} PUBLIC "TX_INCLUDE_USER_DEFINE_FILE" )

246
LICENSE.txt Normal file
View File

@@ -0,0 +1,246 @@
MICROSOFT SOFTWARE LICENSE TERMS
MICROSOFT AZURE RTOS
Shape
These license terms are an agreement between you and Microsoft Corporation (or
one of its affiliates). They apply to the software named above and any Microsoft
services or software updates (except to the extent such services or updates are
accompanied by new or additional terms, in which case those different terms
apply prospectively and do not alter your or Microsofts rights relating to
pre-updated software or services). IF YOU COMPLY WITH THESE LICENSE TERMS, YOU
HAVE THE RIGHTS BELOW. BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS.
INSTALLATION AND USE RIGHTS.
General. You may install and use the software and the included Microsoft
applications solely for internal development, testing and evaluation purposes.
Any distribution or production use requires a separate license as set forth in
Section 2.
Contributions. Microsoft welcomes contributions to this software. In the event
that you make a contribution to this software you will be required to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and
actually do, grant Microsoft the rights to use your contribution. For details,
visit https://cla.microsoft.com.
Included Microsoft Applications. The software includes other Microsoft
applications which are governed by the licenses embedded in or made available
with those applications.
Third Party Components. The software may include third party components with
separate legal notices or governed by other agreements, as may be described
within the software or in the ThirdPartyNotices file(s) accompanying the
software.
Competitive Benchmarking. If you are a direct competitor, and you access or use
the software for purposes of competitive benchmarking, analysis, or intelligence
gathering, you waive as against Microsoft, its subsidiaries, and its affiliated
companies (including prospectively) any competitive use, access, and
benchmarking test restrictions in the terms governing your software to the
extent your terms of use are, or purport to be, more restrictive than
Microsofts terms. If you do not waive any such purported restrictions in the
terms governing your software, you are not allowed to access or use this
software, and will not do so.
DISTRIBUTION AND PRODUCTION USE. If you have obtained and/or are developing on
microprocessor(s) and/or microcontroller(s) (“hardware”) listed in the file
named “LICENSED-HARDWARE.txt” included in the repository and/or distributed with
the software you have the following rights in and to the software solely when
used in combination with the hardware. In the event hardware is not listed in
the LICENSED-HARDWARE.txt file, you do not have the rights in this Section 2.
Distribution and Production Use Rights.
You may use the software in production (e.g. program the modified or unmodified
software to devices you own or control) and distribute (i.e. make available to
third parties) the modified or unmodified binary image produced from this code.
You may permit your device distributors or developers to copy and distribute the
binary image as programmed or to be programmed to your devices.
You may redistribute the unmodified or modified source to your device
distributors or developers. Modifications must be clearly marked. Any
redistribution in source code form must contain this license and any other
licenses that accompany the software.
Requirements. For any code you distribute, you must:
when distributed in binary form, except as embedded in a device, include with
such distribution the terms of this agreement;
when distributed in source code form to distributors or developers of your
devices, include with such distribution the terms of this agreement; and
indemnify, defend and hold harmless Microsoft from any claims, including
attorneys fees, related to the distribution or use of your devices, except to
the extent that any claim is based solely on the unmodified software.
Restrictions. You may not:
use or modify the software to create a competing real time operating system
software;
remove any copyright notices or licenses contained in the software;
use Microsofts trademarks or trade dress in your application in any way that
suggests your device or application comes from or is endorsed by Microsoft;
transfer individual components, specific libraries, classes, functions or code
fragments of the software separately for purposes unrelated to the software; or
use or distribute the software in any way that would subject the software or
Microsofts intellectual property or technology to any other license terms.
SCOPE OF LICENSE. The software is licensed, not sold. Microsoft reserves all
other rights. Unless applicable law gives you more rights despite this
limitation, you will not (and have no right to):
remove, minimize, block, or modify any notices of Microsoft or its suppliers in
the software;
use the software in any way that is against the law or to create or propagate
malware; or
share, publish, distribute, or lease the software (except as permitted in
Section 2 above), or provide the software as a stand-alone offering for others
to use.
DATA. This software may interact with other Microsoft products that collect data
that is transmitted to Microsoft. To learn more about how Microsoft processes
personal data we collect, please see the Microsoft Privacy Statement at
https://go.microsoft.com/fwlink/?LinkId=248681.
EXPORT RESTRICTIONS. You must comply with all domestic and international export
laws and regulations that apply to the software, which include restrictions on
destinations, end users, and end use. For further information on export
restrictions, visit https://aka.ms/exporting.
SUPPORT SERVICES. Microsoft is not obligated under this agreement to provide any
support services for the software. Any support provided is “as is”, “with all
faults”, and without warranty of any kind.
UPDATES. Microsoft may periodically update the software. You may obtain updates
only from Microsoft or Microsoft-authorized sources. Updates may not include or
support all existing software features, services, or peripheral devices.
TERMINATION. Without prejudice to any other rights, Microsoft may terminate this
agreement if you fail to comply with any of its terms or conditions. In such
event, you must destroy all copies of the software and all of its component
parts.
ENTIRE AGREEMENT. This agreement, and any other terms Microsoft may provide for
supplements, updates, or third-party applications, is the entire agreement for
the software. To the extent you have entered into a separate agreement with
Microsoft relating specifically to the software, the terms in such agreement
shall control.
APPLICABLE LAW AND PLACE TO RESOLVE DISPUTES. If you acquired the software in
the United States or Canada, the laws of the state or province where you live
(or, if a business, where your principal place of business is located) govern
the interpretation of this agreement, claims for its breach, and all other
claims (including consumer protection, unfair competition, and tort claims),
regardless of conflict of laws principles. If you acquired the software in any
other country, its laws apply. If U.S. federal jurisdiction exists, you and
Microsoft consent to exclusive jurisdiction and venue in the federal court in
King County, Washington for all disputes heard in court. If not, you and
Microsoft consent to exclusive jurisdiction and venue in the Superior Court of
King County, Washington for all disputes heard in court.
CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal
rights. You may have other rights, including consumer rights, under the laws of
your state or country. Separate and apart from your relationship with Microsoft,
you may also have rights with respect to the party from which you acquired the
software. This agreement does not change those other rights if the laws of your
state or country do not permit it to do so. For example, if you acquired the
software in one of the below regions, or mandatory country law applies, then the
following provisions apply to you:
Australia. You have statutory guarantees under the Australian Consumer Law and
nothing in this agreement is intended to affect those rights.
Germany and Austria.
i.Warranty. The properly licensed software will perform substantially as
described in any Microsoft materials that accompany the software. However,
Microsoft gives no contractual guarantee in relation to the licensed software.
ii.Limitation of Liability. In case of intentional conduct, gross negligence,
claims based on the Product Liability Act, as well as, in case of death or
personal or physical injury, Microsoft is liable according to the statutory law.
Subject to the foregoing clause ii., Microsoft will only be liable for slight
negligence if Microsoft is in breach of such material contractual obligations,
the fulfillment of which facilitate the due performance of this agreement, the
breach of which would endanger the purpose of this agreement and the compliance
with which a party may constantly trust in (so-called "cardinal obligations").
In other cases of slight negligence, Microsoft will not be liable for slight
negligence.
DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED “AS IS.” YOU BEAR THE RISK OF
USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES, OR CONDITIONS. TO
THE EXTENT PERMITTED UNDER APPLICABLE LAWS, MICROSOFT EXCLUDES ALL IMPLIED
WARRANTIES, INCLUDING MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
NON-INFRINGEMENT.
LIMITATION ON AND EXCLUSION OF DAMAGES. IF YOU HAVE ANY BASIS FOR RECOVERING
DAMAGES DESPITE THE PRECEDING DISCLAIMER OF WARRANTY, YOU CAN RECOVER FROM
MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT
RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL,
INDIRECT, OR INCIDENTAL DAMAGES.
This limitation applies to (a) anything related to the software, services,
content (including code) on third party Internet sites, or third party
applications; and (b) claims for breach of contract, warranty, guarantee, or
condition; strict liability, negligence, or other tort; or any other claim; in
each case to the extent permitted by applicable law.
It also applies even if Microsoft knew or should have known about the
possibility of the damages. The above limitation or exclusion may not apply to
you because your state, province, or country may not allow the exclusion or
limitation of incidental, consequential, or other damages.
Please note: As this software is distributed in Canada, some of the clauses in
this agreement are provided below in French.
Remarque: Ce logiciel étant distribué au Canada, certaines des clauses dans ce
contrat sont fournies ci-dessous en français.
EXONÉRATION DE GARANTIE. Le logiciel visé par une licence est offert « tel quel
». Toute utilisation de ce logiciel est à votre seule risque et péril. Microsoft
naccorde aucune autre garantie expresse. Vous pouvez bénéficier de droits
additionnels en vertu du droit local sur la protection des consommateurs, que ce
contrat ne peut modifier. La ou elles sont permises par le droit locale, les
garanties implicites de qualité marchande, dadéquation à un usage particulier
et dabsence de contrefaçon sont exclues.
LIMITATION DES DOMMAGES-INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES
DOMMAGES. Vous pouvez obtenir de Microsoft et de ses fournisseurs une
indemnisation en cas de dommages directs uniquement à hauteur de 5,00 $ US. Vous
ne pouvez prétendre à aucune indemnisation pour les autres dommages, y compris
les dommages spéciaux, indirects ou accessoires et pertes de bénéfices.
Cette limitation concerne:
•tout ce qui est relié au logiciel, aux services ou au contenu (y compris le
code) figurant sur des sites Internet tiers ou dans des programmes tiers; et
•les réclamations au titre de violation de contrat ou de garantie, ou au titre
de responsabilité stricte, de négligence ou dune autre faute dans la limite
autorisée par la loi en vigueur.
Elle sapplique également, même si Microsoft connaissait ou devrait connaître
léventualité dun tel dommage. Si votre pays nautorise pas lexclusion ou la
limitation de responsabilité pour les dommages indirects, accessoires ou de
quelque nature que ce soit, il se peut que la limitation ou lexclusion
ci-dessus ne sappliquera pas à votre égard.
EFFET JURIDIQUE. Le présent contrat décrit certains droits juridiques. Vous
pourriez avoir dautres droits prévus par les lois de votre pays. Le présent
contrat ne modifie pas les droits que vous confèrent les lois de votre pays si
celles-ci ne le permettent pas.

16
LICENSED-HARDWARE.txt Normal file
View File

@@ -0,0 +1,16 @@
LICENSED HARDWARE LIST
Last Updated: 2020-05-08
Microsoft has entered into OEM Agreements with manufacturers of the following
microprocessors and microcontrollers (the “hardware”) to enable those
manufacturers to include and distribute Azure RTOS in certain hardware. If you
have obtained and/or are developing on microprocessor(s) and/or
microcontroller(s) (“hardware”) listed below you inherit the “Distribution and
Production Use” rights in Section 2 of the Microsoft Software License Terms for
Microsoft Azure RTOS. If hardware is not listed below, you do not have those
rights.
--------------------------------------------------------------------------------
More coming soon. Please check back frequently for updates.

1
README.md Normal file
View File

@@ -0,0 +1 @@
# ThreadX

2
TODO Normal file
View File

@@ -0,0 +1,2 @@
TODO:

208
common/CMakeLists.txt Normal file
View File

@@ -0,0 +1,208 @@
function(target_sources_if_not_overridden filename)
list(FIND TX_SRC_OVERRIDES ${filename} OVERRIDE_FOUND)
if( OVERRIDE_FOUND EQUAL -1 )
message(STATUS "** Using original ${filename} from common/src **")
target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/${filename})
endif()
endfunction()
# These files can be overridden by setting them in the variable list named TX_SRC_OVERRIDES
target_sources_if_not_overridden("tx_thread_delete.c")
target_sources_if_not_overridden("tx_thread_reset.c")
target_sources(${PROJECT_NAME}
PRIVATE
# {{BEGIN_TARGET_SOURCES}}
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_allocate.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_pool_cleanup.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_pool_create.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_pool_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_pool_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_pool_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_pool_performance_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_pool_performance_system_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_pool_prioritize.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_block_release.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_allocate.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_pool_cleanup.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_pool_create.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_pool_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_pool_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_pool_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_pool_performance_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_pool_performance_system_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_pool_prioritize.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_pool_search.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_byte_release.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_cleanup.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_create.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_performance_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_performance_system_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_set.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_event_flags_set_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_initialize_high_level.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_initialize_kernel_enter.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_initialize_kernel_setup.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_misra.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_cleanup.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_create.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_performance_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_performance_system_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_prioritize.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_priority_change.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_mutex_put.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_cleanup.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_create.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_flush.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_front_send.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_performance_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_performance_system_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_prioritize.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_send.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_queue_send_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_ceiling_put.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_cleanup.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_create.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_performance_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_performance_system_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_prioritize.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_put.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_semaphore_put_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_create.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_entry_exit_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_identify.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_performance_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_performance_system_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_preemption_change.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_priority_change.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_relinquish.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_resume.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_shell_entry.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_sleep.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_stack_analyze.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_stack_error_handler.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_stack_error_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_suspend.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_system_preempt_check.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_system_resume.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_system_suspend.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_terminate.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_time_slice.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_time_slice_change.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_timeout.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_wait_abort.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_time_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_time_set.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_activate.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_change.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_create.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_deactivate.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_expiration_process.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_performance_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_performance_system_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_system_activate.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_system_deactivate.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_thread_entry.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_buffer_full_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_disable.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_enable.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_event_filter.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_event_unfilter.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_initialize.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_interrupt_control.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_isr_enter_insert.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_isr_exit_insert.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_object_register.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_object_unregister.c
${CMAKE_CURRENT_LIST_DIR}/src/tx_trace_user_event_insert.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_block_allocate.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_block_pool_create.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_block_pool_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_block_pool_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_block_pool_prioritize.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_block_release.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_byte_allocate.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_byte_pool_create.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_byte_pool_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_byte_pool_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_byte_pool_prioritize.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_byte_release.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_event_flags_create.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_event_flags_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_event_flags_get.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_event_flags_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_event_flags_set.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_event_flags_set_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_mutex_create.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_mutex_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_mutex_get.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_mutex_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_mutex_prioritize.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_mutex_put.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_queue_create.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_queue_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_queue_flush.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_queue_front_send.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_queue_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_queue_prioritize.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_queue_receive.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_queue_send.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_queue_send_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_semaphore_ceiling_put.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_semaphore_create.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_semaphore_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_semaphore_get.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_semaphore_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_semaphore_prioritize.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_semaphore_put.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_semaphore_put_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_create.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_entry_exit_notify.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_info_get.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_preemption_change.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_priority_change.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_relinquish.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_reset.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_resume.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_suspend.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_terminate.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_time_slice_change.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_wait_abort.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_timer_activate.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_timer_change.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_timer_create.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_timer_deactivate.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_timer_delete.c
${CMAKE_CURRENT_LIST_DIR}/src/txe_timer_info_get.c
# {{END_TARGET_SOURCES}}
)
# Add the Common/inc directory to the project include list
target_include_directories(${PROJECT_NAME}
PUBLIC
${CMAKE_CURRENT_LIST_DIR}/inc
)

2208
common/inc/tx_api.h Normal file

File diff suppressed because it is too large Load Diff

146
common/inc/tx_block_pool.h Normal file
View File

@@ -0,0 +1,146 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Block Memory */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* tx_block_pool.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the ThreadX block memory management component, */
/* including all data types and external references. It is assumed */
/* that tx_api.h and tx_port.h have already been included. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef TX_BLOCK_POOL_H
#define TX_BLOCK_POOL_H
/* Define block memory control specific data definitions. */
#define TX_BLOCK_POOL_ID ((ULONG) 0x424C4F43)
/* Determine if in-line component initialization is supported by the
caller. */
#ifdef TX_INVOKE_INLINE_INITIALIZATION
/* Yes, in-line initialization is supported, remap the block memory pool
initialization function. */
#ifndef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
#define _tx_block_pool_initialize() \
_tx_block_pool_created_ptr = TX_NULL; \
_tx_block_pool_created_count = TX_EMPTY
#else
#define _tx_block_pool_initialize() \
_tx_block_pool_created_ptr = TX_NULL; \
_tx_block_pool_created_count = TX_EMPTY; \
_tx_block_pool_performance_allocate_count = ((ULONG) 0); \
_tx_block_pool_performance_release_count = ((ULONG) 0); \
_tx_block_pool_performance_suspension_count = ((ULONG) 0); \
_tx_block_pool_performance_timeout_count = ((ULONG) 0)
#endif
#define TX_BLOCK_POOL_INIT
#else
/* No in-line initialization is supported, use standard function call. */
VOID _tx_block_pool_initialize(VOID);
#endif
/* Define internal block memory pool management function prototypes. */
VOID _tx_block_pool_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence);
/* Block pool management component data declarations follow. */
/* Determine if the initialization function of this component is including
this file. If so, make the data definitions really happen. Otherwise,
make them extern so other functions in the component can access them. */
#ifdef TX_BLOCK_POOL_INIT
#define BLOCK_POOL_DECLARE
#else
#define BLOCK_POOL_DECLARE extern
#endif
/* Define the head pointer of the created block pool list. */
BLOCK_POOL_DECLARE TX_BLOCK_POOL * _tx_block_pool_created_ptr;
/* Define the variable that holds the number of created block pools. */
BLOCK_POOL_DECLARE ULONG _tx_block_pool_created_count;
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
/* Define the total number of block allocates. */
BLOCK_POOL_DECLARE ULONG _tx_block_pool_performance_allocate_count;
/* Define the total number of block releases. */
BLOCK_POOL_DECLARE ULONG _tx_block_pool_performance_release_count;
/* Define the total number of block pool suspensions. */
BLOCK_POOL_DECLARE ULONG _tx_block_pool_performance_suspension_count;
/* Define the total number of block pool timeouts. */
BLOCK_POOL_DECLARE ULONG _tx_block_pool_performance_timeout_count;
#endif
/* Define default post block pool delete macro to whitespace, if it hasn't been defined previously (typically in tx_port.h). */
#ifndef TX_BLOCK_POOL_DELETE_PORT_COMPLETION
#define TX_BLOCK_POOL_DELETE_PORT_COMPLETION(p)
#endif
#endif

177
common/inc/tx_byte_pool.h Normal file
View File

@@ -0,0 +1,177 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Byte Memory */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* tx_byte_pool.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the ThreadX byte memory management component, */
/* including all data types and external references. It is assumed */
/* that tx_api.h and tx_port.h have already been included. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef TX_BYTE_POOL_H
#define TX_BYTE_POOL_H
/* Define byte memory control specific data definitions. */
#define TX_BYTE_POOL_ID ((ULONG) 0x42595445)
#ifndef TX_BYTE_BLOCK_FREE
#define TX_BYTE_BLOCK_FREE ((ULONG) 0xFFFFEEEEUL)
#endif
#ifndef TX_BYTE_BLOCK_MIN
#define TX_BYTE_BLOCK_MIN ((ULONG) 20)
#endif
#ifndef TX_BYTE_POOL_MIN
#define TX_BYTE_POOL_MIN ((ULONG) 100)
#endif
/* Determine if in-line component initialization is supported by the
caller. */
#ifdef TX_INVOKE_INLINE_INITIALIZATION
/* Yes, in-line initialization is supported, remap the byte memory pool
initialization function. */
#ifndef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
#define _tx_byte_pool_initialize() \
_tx_byte_pool_created_ptr = TX_NULL; \
_tx_byte_pool_created_count = TX_EMPTY
#else
#define _tx_byte_pool_initialize() \
_tx_byte_pool_created_ptr = TX_NULL; \
_tx_byte_pool_created_count = TX_EMPTY; \
_tx_byte_pool_performance_allocate_count = ((ULONG) 0); \
_tx_byte_pool_performance_release_count = ((ULONG) 0); \
_tx_byte_pool_performance_merge_count = ((ULONG) 0); \
_tx_byte_pool_performance_split_count = ((ULONG) 0); \
_tx_byte_pool_performance_search_count = ((ULONG) 0); \
_tx_byte_pool_performance_suspension_count = ((ULONG) 0); \
_tx_byte_pool_performance_timeout_count = ((ULONG) 0)
#endif
#define TX_BYTE_POOL_INIT
#else
/* No in-line initialization is supported, use standard function call. */
VOID _tx_byte_pool_initialize(VOID);
#endif
/* Define internal byte memory pool management function prototypes. */
UCHAR *_tx_byte_pool_search(TX_BYTE_POOL *pool_ptr, ULONG memory_size);
VOID _tx_byte_pool_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence);
/* Byte pool management component data declarations follow. */
/* Determine if the initialization function of this component is including
this file. If so, make the data definitions really happen. Otherwise,
make them extern so other functions in the component can access them. */
#ifdef TX_BYTE_POOL_INIT
#define BYTE_POOL_DECLARE
#else
#define BYTE_POOL_DECLARE extern
#endif
/* Define the head pointer of the created byte pool list. */
BYTE_POOL_DECLARE TX_BYTE_POOL * _tx_byte_pool_created_ptr;
/* Define the variable that holds the number of created byte pools. */
BYTE_POOL_DECLARE ULONG _tx_byte_pool_created_count;
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
/* Define the total number of allocates. */
BYTE_POOL_DECLARE ULONG _tx_byte_pool_performance_allocate_count;
/* Define the total number of releases. */
BYTE_POOL_DECLARE ULONG _tx_byte_pool_performance_release_count;
/* Define the total number of adjacent memory fragment merges. */
BYTE_POOL_DECLARE ULONG _tx_byte_pool_performance_merge_count;
/* Define the total number of memory fragment splits. */
BYTE_POOL_DECLARE ULONG _tx_byte_pool_performance_split_count;
/* Define the total number of memory fragments searched during allocation. */
BYTE_POOL_DECLARE ULONG _tx_byte_pool_performance_search_count;
/* Define the total number of byte pool suspensions. */
BYTE_POOL_DECLARE ULONG _tx_byte_pool_performance_suspension_count;
/* Define the total number of byte pool timeouts. */
BYTE_POOL_DECLARE ULONG _tx_byte_pool_performance_timeout_count;
#endif
/* Define default post byte pool delete macro to whitespace, if it hasn't been defined previously (typically in tx_port.h). */
#ifndef TX_BYTE_POOL_DELETE_PORT_COMPLETION
#define TX_BYTE_POOL_DELETE_PORT_COMPLETION(p)
#endif
#endif

147
common/inc/tx_event_flags.h Normal file
View File

@@ -0,0 +1,147 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Event Flags */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* tx_event_flags.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the ThreadX event flags management component, */
/* including all data types and external references. It is assumed */
/* that tx_api.h and tx_port.h have already been included. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef TX_EVENT_FLAGS_H
#define TX_EVENT_FLAGS_H
/* Define event flags control specific data definitions. */
#define TX_EVENT_FLAGS_ID ((ULONG) 0x4456444E)
#define TX_EVENT_FLAGS_AND_MASK ((UINT) 0x2)
#define TX_EVENT_FLAGS_CLEAR_MASK ((UINT) 0x1)
/* Determine if in-line component initialization is supported by the
caller. */
#ifdef TX_INVOKE_INLINE_INITIALIZATION
/* Yes, in-line initialization is supported, remap the event flag initialization
function. */
#ifndef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
#define _tx_event_flags_initialize() \
_tx_event_flags_created_ptr = TX_NULL; \
_tx_event_flags_created_count = TX_EMPTY
#else
#define _tx_event_flags_initialize() \
_tx_event_flags_created_ptr = TX_NULL; \
_tx_event_flags_created_count = TX_EMPTY; \
_tx_event_flags_performance_set_count = ((ULONG) 0); \
_tx_event_flags_performance_get_count = ((ULONG) 0); \
_tx_event_flags_performance_suspension_count = ((ULONG) 0); \
_tx_event_flags_performance_timeout_count = ((ULONG) 0)
#endif
#define TX_EVENT_FLAGS_INIT
#else
/* No in-line initialization is supported, use standard function call. */
VOID _tx_event_flags_initialize(VOID);
#endif
/* Define internal event flags management function prototypes. */
VOID _tx_event_flags_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence);
/* Event flags management component data declarations follow. */
/* Determine if the initialization function of this component is including
this file. If so, make the data definitions really happen. Otherwise,
make them extern so other functions in the component can access them. */
#ifdef TX_EVENT_FLAGS_INIT
#define EVENT_FLAGS_DECLARE
#else
#define EVENT_FLAGS_DECLARE extern
#endif
/* Define the head pointer of the created event flags list. */
EVENT_FLAGS_DECLARE TX_EVENT_FLAGS_GROUP * _tx_event_flags_created_ptr;
/* Define the variable that holds the number of created event flag groups. */
EVENT_FLAGS_DECLARE ULONG _tx_event_flags_created_count;
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
/* Define the total number of event flag sets. */
EVENT_FLAGS_DECLARE ULONG _tx_event_flags_performance_set_count;
/* Define the total number of event flag gets. */
EVENT_FLAGS_DECLARE ULONG _tx_event_flags_performance_get_count;
/* Define the total number of event flag suspensions. */
EVENT_FLAGS_DECLARE ULONG _tx_event_flags_performance_suspension_count;
/* Define the total number of event flag timeouts. */
EVENT_FLAGS_DECLARE ULONG _tx_event_flags_performance_timeout_count;
#endif
/* Define default post event flag group delete macro to whitespace, if it hasn't been defined previously (typically in tx_port.h). */
#ifndef TX_EVENT_FLAGS_GROUP_DELETE_PORT_COMPLETION
#define TX_EVENT_FLAGS_GROUP_DELETE_PORT_COMPLETION(g)
#endif
#endif

111
common/inc/tx_initialize.h Normal file
View File

@@ -0,0 +1,111 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Initialize */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* tx_initialize.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the ThreadX initialization component, including */
/* data types and external references. It is assumed that tx_api.h */
/* and tx_port.h have already been included. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef TX_INITIALIZE_H
#define TX_INITIALIZE_H
/* Define constants that indicate initialization is in progress. */
#define TX_INITIALIZE_IN_PROGRESS ((ULONG) 0xF0F0F0F0UL)
#define TX_INITIALIZE_ALMOST_DONE ((ULONG) 0xF0F0F0F1UL)
#define TX_INITIALIZE_IS_FINISHED ((ULONG) 0x00000000UL)
/* Define internal initialization function prototypes. */
VOID _tx_initialize_high_level(VOID);
VOID _tx_initialize_kernel_setup(VOID);
VOID _tx_initialize_low_level(VOID);
/* Define the macro for adding additional port-specific global data. This macro is defined
as white space, unless defined by tx_port.h. */
#ifndef TX_PORT_SPECIFIC_DATA
#define TX_PORT_SPECIFIC_DATA
#endif
/* Define the macro for adding additional port-specific pre and post initialization processing.
These macros is defined as white space, unless defined by tx_port.h. */
#ifndef TX_PORT_SPECIFIC_PRE_INITIALIZATION
#define TX_PORT_SPECIFIC_PRE_INITIALIZATION
#endif
#ifndef TX_PORT_SPECIFIC_POST_INITIALIZATION
#define TX_PORT_SPECIFIC_POST_INITIALIZATION
#endif
#ifndef TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION
#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION
#endif
/* Initialization component data declarations follow. */
/* Determine if the initialization function of this component is including
this file. If so, make the data definitions really happen. Otherwise,
make them extern so other functions in the component can access them. */
#ifdef TX_INITIALIZE_INIT
#define INITIALIZE_DECLARE
#else
#define INITIALIZE_DECLARE extern
#endif
/* Define the unused memory pointer. The value of the first available
memory address is placed in this variable in the low-level
initialization function. The content of this variable is passed
to the application's system definition function. */
INITIALIZE_DECLARE VOID *_tx_initialize_unused_memory;
#endif

160
common/inc/tx_mutex.h Normal file
View File

@@ -0,0 +1,160 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Mutex */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* tx_mutex.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the ThreadX mutex management component, */
/* including all data types and external references. It is assumed */
/* that tx_api.h and tx_port.h have already been included. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef TX_MUTEX_H
#define TX_MUTEX_H
/* Define mutex control specific data definitions. */
#define TX_MUTEX_ID ((ULONG) 0x4D555445)
/* Determine if in-line component initialization is supported by the
caller. */
#ifdef TX_INVOKE_INLINE_INITIALIZATION
/* Yes, in-line initialization is supported, remap the mutex initialization
function. */
#ifndef TX_MUTEX_ENABLE_PERFORMANCE_INFO
#define _tx_mutex_initialize() \
_tx_mutex_created_ptr = TX_NULL; \
_tx_mutex_created_count = TX_EMPTY
#else
#define _tx_mutex_initialize() \
_tx_mutex_created_ptr = TX_NULL; \
_tx_mutex_created_count = TX_EMPTY; \
_tx_mutex_performance_put_count = ((ULONG) 0); \
_tx_mutex_performance_get_count = ((ULONG) 0); \
_tx_mutex_performance_suspension_count = ((ULONG) 0); \
_tx_mutex_performance_timeout_count = ((ULONG) 0); \
_tx_mutex_performance_priority_inversion_count = ((ULONG) 0); \
_tx_mutex_performance__priority_inheritance_count = ((ULONG) 0)
#endif
#define TX_MUTEX_INIT
#else
/* No in-line initialization is supported, use standard function call. */
VOID _tx_mutex_initialize(VOID);
#endif
/* Define internal mutex management function prototypes. */
VOID _tx_mutex_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence);
VOID _tx_mutex_thread_release(TX_THREAD *thread_ptr);
VOID _tx_mutex_priority_change(TX_THREAD *thread_ptr, UINT new_priority);
/* Mutex management component data declarations follow. */
/* Determine if the initialization function of this component is including
this file. If so, make the data definitions really happen. Otherwise,
make them extern so other functions in the component can access them. */
#ifdef TX_MUTEX_INIT
#define MUTEX_DECLARE
#else
#define MUTEX_DECLARE extern
#endif
/* Define the head pointer of the created mutex list. */
MUTEX_DECLARE TX_MUTEX * _tx_mutex_created_ptr;
/* Define the variable that holds the number of created mutexes. */
MUTEX_DECLARE ULONG _tx_mutex_created_count;
#ifdef TX_MUTEX_ENABLE_PERFORMANCE_INFO
/* Define the total number of mutex puts. */
MUTEX_DECLARE ULONG _tx_mutex_performance_put_count;
/* Define the total number of mutex gets. */
MUTEX_DECLARE ULONG _tx_mutex_performance_get_count;
/* Define the total number of mutex suspensions. */
MUTEX_DECLARE ULONG _tx_mutex_performance_suspension_count;
/* Define the total number of mutex timeouts. */
MUTEX_DECLARE ULONG _tx_mutex_performance_timeout_count;
/* Define the total number of priority inversions. */
MUTEX_DECLARE ULONG _tx_mutex_performance_priority_inversion_count;
/* Define the total number of priority inheritance conditions. */
MUTEX_DECLARE ULONG _tx_mutex_performance__priority_inheritance_count;
#endif
/* Define default post mutex delete macro to whitespace, if it hasn't been defined previously (typically in tx_port.h). */
#ifndef TX_MUTEX_DELETE_PORT_COMPLETION
#define TX_MUTEX_DELETE_PORT_COMPLETION(m)
#endif
#endif

173
common/inc/tx_queue.h Normal file
View File

@@ -0,0 +1,173 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Queue */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* tx_queue.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the ThreadX queue management component, */
/* including all data types and external references. It is assumed */
/* that tx_api.h and tx_port.h have already been included. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef TX_QUEUE_H
#define TX_QUEUE_H
/* Define queue control specific data definitions. */
#define TX_QUEUE_ID ((ULONG) 0x51554555)
/* Determine if in-line component initialization is supported by the
caller. */
#ifdef TX_INVOKE_INLINE_INITIALIZATION
/* Yes, in-line initialization is supported, remap the queue initialization
function. */
#ifndef TX_QUEUE_ENABLE_PERFORMANCE_INFO
#define _tx_queue_initialize() \
_tx_queue_created_ptr = TX_NULL; \
_tx_queue_created_count = TX_EMPTY
#else
#define _tx_queue_initialize() \
_tx_queue_created_ptr = TX_NULL; \
_tx_queue_created_count = TX_EMPTY; \
_tx_queue_performance_messages_sent_count = ((ULONG) 0); \
_tx_queue_performance__messages_received_count = ((ULONG) 0); \
_tx_queue_performance_empty_suspension_count = ((ULONG) 0); \
_tx_queue_performance_full_suspension_count = ((ULONG) 0); \
_tx_queue_performance_timeout_count = ((ULONG) 0)
#endif
#define TX_QUEUE_INIT
#else
/* No in-line initialization is supported, use standard function call. */
VOID _tx_queue_initialize(VOID);
#endif
/* Define the message copy macro. Note that the source and destination
pointers must be modified since they are used subsequently. */
#ifndef TX_QUEUE_MESSAGE_COPY
#define TX_QUEUE_MESSAGE_COPY(s, d, z) \
*(d)++ = *(s)++; \
if ((z) > ((UINT) 1)) \
{ \
while (--(z)) \
{ \
*(d)++ = *(s)++; \
} \
}
#endif
/* Define internal queue management function prototypes. */
VOID _tx_queue_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence);
/* Queue management component data declarations follow. */
/* Determine if the initialization function of this component is including
this file. If so, make the data definitions really happen. Otherwise,
make them extern so other functions in the component can access them. */
#ifdef TX_QUEUE_INIT
#define QUEUE_DECLARE
#else
#define QUEUE_DECLARE extern
#endif
/* Define the head pointer of the created queue list. */
QUEUE_DECLARE TX_QUEUE * _tx_queue_created_ptr;
/* Define the variable that holds the number of created queues. */
QUEUE_DECLARE ULONG _tx_queue_created_count;
#ifdef TX_QUEUE_ENABLE_PERFORMANCE_INFO
/* Define the total number of messages sent. */
QUEUE_DECLARE ULONG _tx_queue_performance_messages_sent_count;
/* Define the total number of messages received. */
QUEUE_DECLARE ULONG _tx_queue_performance__messages_received_count;
/* Define the total number of queue empty suspensions. */
QUEUE_DECLARE ULONG _tx_queue_performance_empty_suspension_count;
/* Define the total number of queue full suspensions. */
QUEUE_DECLARE ULONG _tx_queue_performance_full_suspension_count;
/* Define the total number of queue full errors. */
QUEUE_DECLARE ULONG _tx_queue_performance_full_error_count;
/* Define the total number of queue timeouts. */
QUEUE_DECLARE ULONG _tx_queue_performance_timeout_count;
#endif
/* Define default post queue delete macro to whitespace, if it hasn't been defined previously (typically in tx_port.h). */
#ifndef TX_QUEUE_DELETE_PORT_COMPLETION
#define TX_QUEUE_DELETE_PORT_COMPLETION(q)
#endif
#endif

144
common/inc/tx_semaphore.h Normal file
View File

@@ -0,0 +1,144 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Semaphore */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* tx_semaphore.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the ThreadX semaphore management component, */
/* including all data types and external references. It is assumed */
/* that tx_api.h and tx_port.h have already been included. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef TX_SEMAPHORE_H
#define TX_SEMAPHORE_H
/* Define semaphore control specific data definitions. */
#define TX_SEMAPHORE_ID ((ULONG) 0x53454D41)
/* Determine if in-line component initialization is supported by the
caller. */
#ifdef TX_INVOKE_INLINE_INITIALIZATION
/* Yes, in-line initialization is supported, remap the
semaphore initialization function. */
#ifndef TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO
#define _tx_semaphore_initialize() \
_tx_semaphore_created_ptr = TX_NULL; \
_tx_semaphore_created_count = TX_EMPTY
#else
#define _tx_semaphore_initialize() \
_tx_semaphore_created_ptr = TX_NULL; \
_tx_semaphore_created_count = TX_EMPTY; \
_tx_semaphore_performance_put_count = ((ULONG) 0); \
_tx_semaphore_performance_get_count = ((ULONG) 0); \
_tx_semaphore_performance_suspension_count = ((ULONG) 0); \
_tx_semaphore_performance_timeout_count = ((ULONG) 0)
#endif
#define TX_SEMAPHORE_INIT
#else
/* No in-line initialization is supported, use standard
function call. */
VOID _tx_semaphore_initialize(VOID);
#endif
/* Define internal semaphore management function prototypes. */
VOID _tx_semaphore_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence);
/* Semaphore management component data declarations follow. */
/* Determine if the initialization function of this component is including
this file. If so, make the data definitions really happen. Otherwise,
make them extern so other functions in the component can access them. */
#ifdef TX_SEMAPHORE_INIT
#define SEMAPHORE_DECLARE
#else
#define SEMAPHORE_DECLARE extern
#endif
/* Define the head pointer of the created semaphore list. */
SEMAPHORE_DECLARE TX_SEMAPHORE * _tx_semaphore_created_ptr;
/* Define the variable that holds the number of created semaphores. */
SEMAPHORE_DECLARE ULONG _tx_semaphore_created_count;
#ifdef TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO
/* Define the total number of semaphore puts. */
SEMAPHORE_DECLARE ULONG _tx_semaphore_performance_put_count;
/* Define the total number of semaphore gets. */
SEMAPHORE_DECLARE ULONG _tx_semaphore_performance_get_count;
/* Define the total number of semaphore suspensions. */
SEMAPHORE_DECLARE ULONG _tx_semaphore_performance_suspension_count;
/* Define the total number of semaphore timeouts. */
SEMAPHORE_DECLARE ULONG _tx_semaphore_performance_timeout_count;
#endif
/* Define default post semaphore delete macro to whitespace, if it hasn't been defined previously (typically in tx_port.h). */
#ifndef TX_SEMAPHORE_DELETE_PORT_COMPLETION
#define TX_SEMAPHORE_DELETE_PORT_COMPLETION(s)
#endif
#endif

524
common/inc/tx_thread.h Normal file

File diff suppressed because it is too large Load Diff

213
common/inc/tx_timer.h Normal file
View File

@@ -0,0 +1,213 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Timer */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* COMPONENT DEFINITION RELEASE */
/* */
/* tx_timer.h PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file defines the ThreadX timer management component, including */
/* data types and external references. It is assumed that tx_api.h */
/* and tx_port.h have already been included. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef TX_TIMER_H
#define TX_TIMER_H
/* Define timer management specific data definitions. */
#define TX_TIMER_ID ((ULONG) 0x4154494D)
#define TX_TIMER_ENTRIES ((ULONG) 32)
/* Define internal timer management function prototypes. */
VOID _tx_timer_expiration_process(VOID);
VOID _tx_timer_initialize(VOID);
VOID _tx_timer_system_activate(TX_TIMER_INTERNAL *timer_ptr);
VOID _tx_timer_system_deactivate(TX_TIMER_INTERNAL *timer_ptr);
VOID _tx_timer_thread_entry(ULONG timer_thread_input);
/* Timer management component data declarations follow. */
/* Determine if the initialization function of this component is including
this file. If so, make the data definitions really happen. Otherwise,
make them extern so other functions in the component can access them. */
#ifdef TX_TIMER_INIT
#define TIMER_DECLARE
#else
#define TIMER_DECLARE extern
#endif
/* Define the system clock value that is continually incremented by the
periodic timer interrupt processing. */
TIMER_DECLARE volatile ULONG _tx_timer_system_clock;
/* Define the current time slice value. If non-zero, a time-slice is active.
Otherwise, the time_slice is not active. */
TIMER_DECLARE ULONG _tx_timer_time_slice;
/* Define the time-slice expiration flag. This is used to indicate that a time-slice
has happened. */
TIMER_DECLARE UINT _tx_timer_expired_time_slice;
/* Define the thread and application timer entry list. This list provides a direct access
method for insertion of times less than TX_TIMER_ENTRIES. */
TIMER_DECLARE TX_TIMER_INTERNAL *_tx_timer_list[TX_TIMER_ENTRIES];
/* Define the boundary pointers to the list. These are setup to easily manage
wrapping the list. */
TIMER_DECLARE TX_TIMER_INTERNAL **_tx_timer_list_start;
TIMER_DECLARE TX_TIMER_INTERNAL **_tx_timer_list_end;
/* Define the current timer pointer in the list. This pointer is moved sequentially
through the timer list by the timer interrupt handler. */
TIMER_DECLARE TX_TIMER_INTERNAL **_tx_timer_current_ptr;
/* Define the timer expiration flag. This is used to indicate that a timer
has expired. */
TIMER_DECLARE UINT _tx_timer_expired;
/* Define the created timer list head pointer. */
TIMER_DECLARE TX_TIMER *_tx_timer_created_ptr;
/* Define the created timer count. */
TIMER_DECLARE ULONG _tx_timer_created_count;
/* Define the pointer to the timer that has expired and is being processed. */
TIMER_DECLARE TX_TIMER_INTERNAL *_tx_timer_expired_timer_ptr;
#ifndef TX_TIMER_PROCESS_IN_ISR
/* Define the timer thread's control block. */
TIMER_DECLARE TX_THREAD _tx_timer_thread;
/* Define the variable that holds the timer thread's starting stack address. */
TIMER_DECLARE VOID *_tx_timer_stack_start;
/* Define the variable that holds the timer thread's stack size. */
TIMER_DECLARE ULONG _tx_timer_stack_size;
/* Define the variable that holds the timer thread's priority. */
TIMER_DECLARE UINT _tx_timer_priority;
/* Define the system timer thread's stack. The default size is defined
in tx_port.h. */
TIMER_DECLARE ULONG _tx_timer_thread_stack_area[(((UINT) TX_TIMER_THREAD_STACK_SIZE)+((sizeof(ULONG)) - ((UINT) 1)))/sizeof(ULONG)];
#else
/* Define the busy flag that will prevent nested timer ISR processing. */
TIMER_DECLARE UINT _tx_timer_processing_active;
#endif
#ifdef TX_TIMER_ENABLE_PERFORMANCE_INFO
/* Define the total number of timer activations. */
TIMER_DECLARE ULONG _tx_timer_performance_activate_count;
/* Define the total number of timer reactivations. */
TIMER_DECLARE ULONG _tx_timer_performance_reactivate_count;
/* Define the total number of timer deactivations. */
TIMER_DECLARE ULONG _tx_timer_performance_deactivate_count;
/* Define the total number of timer expirations. */
TIMER_DECLARE ULONG _tx_timer_performance_expiration_count;
/* Define the total number of timer expiration adjustments. These are required
if the expiration time is greater than the size of the timer list. In such
cases, the timer is placed at the end of the list and then reactivated
as many times as necessary to finally achieve the resulting timeout. */
TIMER_DECLARE ULONG _tx_timer_performance__expiration_adjust_count;
#endif
/* Define default post timer delete macro to whitespace, if it hasn't been defined previously (typically in tx_port.h). */
#ifndef TX_TIMER_DELETE_PORT_COMPLETION
#define TX_TIMER_DELETE_PORT_COMPLETION(t)
#endif
#endif

559
common/inc/tx_trace.h Normal file

File diff suppressed because it is too large Load Diff

257
common/inc/tx_user_sample.h Normal file
View File

@@ -0,0 +1,257 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** User Specific */
/** */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/* */
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_user.h PORTABLE C */
/* 6.0 */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This file contains user defines for configuring ThreadX in specific */
/* ways. This file will have an effect only if the application and */
/* ThreadX library are built with TX_INCLUDE_USER_DEFINE_FILE defined. */
/* Note that all the defines in this file may also be made on the */
/* command line when building ThreadX library and application objects. */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
#ifndef TX_USER_H
#define TX_USER_H
/* Define various build options for the ThreadX port. The application should either make changes
here by commenting or un-commenting the conditional compilation defined OR supply the defines
though the compiler's equivalent of the -D option.
For maximum speed, the following should be defined:
TX_MAX_PRIORITIES 32
TX_DISABLE_PREEMPTION_THRESHOLD
TX_DISABLE_REDUNDANT_CLEARING
TX_DISABLE_NOTIFY_CALLBACKS
TX_NOT_INTERRUPTABLE
TX_TIMER_PROCESS_IN_ISR
TX_REACTIVATE_INLINE
TX_DISABLE_STACK_FILLING
TX_INLINE_THREAD_RESUME_SUSPEND
For minimum size, the following should be defined:
TX_MAX_PRIORITIES 32
TX_DISABLE_PREEMPTION_THRESHOLD
TX_DISABLE_REDUNDANT_CLEARING
TX_DISABLE_NOTIFY_CALLBACKS
TX_NOT_INTERRUPTABLE
TX_TIMER_PROCESS_IN_ISR
Of course, many of these defines reduce functionality and/or change the behavior of the
system in ways that may not be worth the trade-off. For example, the TX_TIMER_PROCESS_IN_ISR
results in faster and smaller code, however, it increases the amount of processing in the ISR.
In addition, some services that are available in timers are not available from ISRs and will
therefore return an error if this option is used. This may or may not be desirable for a
given application. */
/* Override various options with default values already assigned in tx_port.h. Please also refer
to tx_port.h for descriptions on each of these options. */
/*
#define TX_MAX_PRIORITIES 32
#define TX_MINIMUM_STACK ????
#define TX_THREAD_USER_EXTENSION ????
#define TX_TIMER_THREAD_STACK_SIZE ????
#define TX_TIMER_THREAD_PRIORITY ????
*/
/* Determine if timer expirations (application timers, timeouts, and tx_thread_sleep calls
should be processed within the a system timer thread or directly in the timer ISR.
By default, the timer thread is used. When the following is defined, the timer expiration
processing is done directly from the timer ISR, thereby eliminating the timer thread control
block, stack, and context switching to activate it. */
/*
#define TX_TIMER_PROCESS_IN_ISR
*/
/* Determine if in-line timer reactivation should be used within the timer expiration processing.
By default, this is disabled and a function call is used. When the following is defined,
reactivating is performed in-line resulting in faster timer processing but slightly larger
code size. */
/*
#define TX_REACTIVATE_INLINE
*/
/* Determine is stack filling is enabled. By default, ThreadX stack filling is enabled,
which places an 0xEF pattern in each byte of each thread's stack. This is used by
debuggers with ThreadX-awareness and by the ThreadX run-time stack checking feature. */
/*
#define TX_DISABLE_STACK_FILLING
*/
/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
define is negated, thereby forcing the stack fill which is necessary for the stack checking
logic. */
/*
#define TX_ENABLE_STACK_CHECKING
*/
/* Determine if preemption-threshold should be disabled. By default, preemption-threshold is
enabled. If the application does not use preemption-threshold, it may be disabled to reduce
code size and improve performance. */
/*
#define TX_DISABLE_PREEMPTION_THRESHOLD
*/
/* Determine if global ThreadX variables should be cleared. If the compiler startup code clears
the .bss section prior to ThreadX running, the define can be used to eliminate unnecessary
clearing of ThreadX global variables. */
/*
#define TX_DISABLE_REDUNDANT_CLEARING
*/
/* Determine if no timer processing is required. This option will help eliminate the timer
processing when not needed. The user will also have to comment out the call to
tx_timer_interrupt, which is typically made from assembly language in
tx_initialize_low_level. Note: if TX_NO_TIMER is used, the define TX_TIMER_PROCESS_IN_ISR
must also be used. */
/*
#define TX_NO_TIMER
#ifndef TX_TIMER_PROCESS_IN_ISR
#define TX_TIMER_PROCESS_IN_ISR
#endif
*/
/* Determine if the notify callback option should be disabled. By default, notify callbacks are
enabled. If the application does not use notify callbacks, they may be disabled to reduce
code size and improve performance. */
/*
#define TX_DISABLE_NOTIFY_CALLBACKS
*/
/* Determine if the tx_thread_resume and tx_thread_suspend services should have their internal
code in-line. This results in a larger image, but improves the performance of the thread
resume and suspend services. */
/*
#define TX_INLINE_THREAD_RESUME_SUSPEND
*/
/* Determine if the internal ThreadX code is non-interruptable. This results in smaller code
size and less processing overhead, but increases the interrupt lockout time. */
/*
#define TX_NOT_INTERRUPTABLE
*/
/* Determine if the trace event logging code should be enabled. This causes slight increases in
code size and overhead, but provides the ability to generate system trace information which
is available for viewing in TraceX. */
/*
#define TX_ENABLE_EVENT_TRACE
*/
/* Determine if block pool performance gathering is required by the application. When the following is
defined, ThreadX gathers various block pool performance information. */
/*
#define TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
*/
/* Determine if byte pool performance gathering is required by the application. When the following is
defined, ThreadX gathers various byte pool performance information. */
/*
#define TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
*/
/* Determine if event flags performance gathering is required by the application. When the following is
defined, ThreadX gathers various event flags performance information. */
/*
#define TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
*/
/* Determine if mutex performance gathering is required by the application. When the following is
defined, ThreadX gathers various mutex performance information. */
/*
#define TX_MUTEX_ENABLE_PERFORMANCE_INFO
*/
/* Determine if queue performance gathering is required by the application. When the following is
defined, ThreadX gathers various queue performance information. */
/*
#define TX_QUEUE_ENABLE_PERFORMANCE_INFO
*/
/* Determine if semaphore performance gathering is required by the application. When the following is
defined, ThreadX gathers various semaphore performance information. */
/*
#define TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO
*/
/* Determine if thread performance gathering is required by the application. When the following is
defined, ThreadX gathers various thread performance information. */
/*
#define TX_THREAD_ENABLE_PERFORMANCE_INFO
*/
/* Determine if timer performance gathering is required by the application. When the following is
defined, ThreadX gathers various timer performance information. */
/*
#define TX_TIMER_ENABLE_PERFORMANCE_INFO
*/
#endif

View File

@@ -0,0 +1,372 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Block Pool */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#ifdef TX_ENABLE_EVENT_TRACE
#include "tx_trace.h"
#endif
#include "tx_thread.h"
#include "tx_block_pool.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_block_allocate PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function allocates a block from the specified memory block */
/* pool. */
/* */
/* INPUT */
/* */
/* pool_ptr Pointer to pool control block */
/* block_ptr Pointer to place allocated block */
/* pointer */
/* wait_option Suspension option */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _tx_thread_system_suspend Suspend thread */
/* _tx_thread_system_ni_suspend Non-interruptable suspend thread */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_block_allocate(TX_BLOCK_POOL *pool_ptr, VOID **block_ptr, ULONG wait_option)
{
TX_INTERRUPT_SAVE_AREA
UINT status;
TX_THREAD *thread_ptr;
UCHAR *work_ptr;
UCHAR *temp_ptr;
UCHAR **next_block_ptr;
UCHAR **return_ptr;
UINT suspended_count;
TX_THREAD *next_thread;
TX_THREAD *previous_thread;
#ifdef TX_ENABLE_EVENT_TRACE
TX_TRACE_BUFFER_ENTRY *entry_ptr;
ULONG time_stamp = ((ULONG) 0);
#endif
#ifdef TX_ENABLE_EVENT_LOGGING
UCHAR *log_entry_ptr;
ULONG upper_tbu;
ULONG lower_tbu;
#endif
/* Disable interrupts to get a block from the pool. */
TX_DISABLE
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
/* Increment the total allocations counter. */
_tx_block_pool_performance_allocate_count++;
/* Increment the number of allocations on this pool. */
pool_ptr -> tx_block_pool_performance_allocate_count++;
#endif
#ifdef TX_ENABLE_EVENT_TRACE
/* If trace is enabled, save the current event pointer. */
entry_ptr = _tx_trace_buffer_current_ptr;
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BLOCK_ALLOCATE, pool_ptr, 0, wait_option, pool_ptr -> tx_block_pool_available, TX_TRACE_BLOCK_POOL_EVENTS)
/* Save the time stamp for later comparison to verify that
the event hasn't been overwritten by the time the allocate
call succeeds. */
if (entry_ptr != TX_NULL)
{
time_stamp = entry_ptr -> tx_trace_buffer_entry_time_stamp;
}
#endif
#ifdef TX_ENABLE_EVENT_LOGGING
log_entry_ptr = *(UCHAR **) _tx_el_current_event;
/* Log this kernel call. */
TX_EL_BLOCK_ALLOCATE_INSERT
/* Store -1 in the third event slot. */
*((ULONG *) (log_entry_ptr + TX_EL_EVENT_INFO_3_OFFSET)) = (ULONG) -1;
/* Save the time stamp for later comparison to verify that
the event hasn't been overwritten by the time the allocate
call succeeds. */
lower_tbu = *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET));
upper_tbu = *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET));
#endif
/* Determine if there is an available block. */
if (pool_ptr -> tx_block_pool_available != ((UINT) 0))
{
/* Yes, a block is available. Decrement the available count. */
pool_ptr -> tx_block_pool_available--;
/* Pickup the current block pointer. */
work_ptr = pool_ptr -> tx_block_pool_available_list;
/* Return the first available block to the caller. */
temp_ptr = TX_UCHAR_POINTER_ADD(work_ptr, (sizeof(UCHAR *)));
return_ptr = TX_INDIRECT_VOID_TO_UCHAR_POINTER_CONVERT(block_ptr);
*return_ptr = temp_ptr;
/* Modify the available list to point at the next block in the pool. */
next_block_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(work_ptr);
pool_ptr -> tx_block_pool_available_list = *next_block_ptr;
/* Save the pool's address in the block for when it is released! */
temp_ptr = TX_BLOCK_POOL_TO_UCHAR_POINTER_CONVERT(pool_ptr);
*next_block_ptr = temp_ptr;
#ifdef TX_ENABLE_EVENT_TRACE
/* Check that the event time stamp is unchanged. A different
timestamp means that a later event wrote over the byte
allocate event. In that case, do nothing here. */
if (entry_ptr != TX_NULL)
{
/* Is the time stamp the same? */
if (time_stamp == entry_ptr -> tx_trace_buffer_entry_time_stamp)
{
/* Timestamp is the same, update the entry with the address. */
#ifdef TX_MISRA_ENABLE
entry_ptr -> tx_trace_buffer_entry_info_2 = TX_POINTER_TO_ULONG_CONVERT(*block_ptr);
#else
entry_ptr -> tx_trace_buffer_entry_information_field_2 = TX_POINTER_TO_ULONG_CONVERT(*block_ptr);
#endif
}
}
#endif
#ifdef TX_ENABLE_EVENT_LOGGING
/* Store the address of the allocated block. */
*((ULONG *) (log_entry_ptr + TX_EL_EVENT_INFO_3_OFFSET)) = (ULONG) *block_ptr;
#endif
/* Set status to success. */
status = TX_SUCCESS;
/* Restore interrupts. */
TX_RESTORE
}
else
{
/* Default the return pointer to NULL. */
return_ptr = TX_INDIRECT_VOID_TO_UCHAR_POINTER_CONVERT(block_ptr);
*return_ptr = TX_NULL;
/* Determine if the request specifies suspension. */
if (wait_option != TX_NO_WAIT)
{
/* Determine if the preempt disable flag is non-zero. */
if (_tx_thread_preempt_disable != ((UINT) 0))
{
/* Suspension is not allowed if the preempt disable flag is non-zero at this point, return error completion. */
status = TX_NO_MEMORY;
/* Restore interrupts. */
TX_RESTORE
}
else
{
/* Prepare for suspension of this thread. */
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
/* Increment the total suspensions counter. */
_tx_block_pool_performance_suspension_count++;
/* Increment the number of suspensions on this pool. */
pool_ptr -> tx_block_pool_performance_suspension_count++;
#endif
/* Pickup thread pointer. */
TX_THREAD_GET_CURRENT(thread_ptr)
/* Setup cleanup routine pointer. */
thread_ptr -> tx_thread_suspend_cleanup = &(_tx_block_pool_cleanup);
/* Setup cleanup information, i.e. this pool control
block. */
thread_ptr -> tx_thread_suspend_control_block = (VOID *) pool_ptr;
/* Save the return block pointer address as well. */
thread_ptr -> tx_thread_additional_suspend_info = (VOID *) block_ptr;
#ifndef TX_NOT_INTERRUPTABLE
/* Increment the suspension sequence number, which is used to identify
this suspension event. */
thread_ptr -> tx_thread_suspension_sequence++;
#endif
/* Pickup the number of suspended threads. */
suspended_count = (pool_ptr -> tx_block_pool_suspended_count);
/* Increment the number of suspended threads. */
(pool_ptr -> tx_block_pool_suspended_count)++;
/* Setup suspension list. */
if (suspended_count == TX_NO_SUSPENSIONS)
{
/* No other threads are suspended. Setup the head pointer and
just setup this threads pointers to itself. */
pool_ptr -> tx_block_pool_suspension_list = thread_ptr;
thread_ptr -> tx_thread_suspended_next = thread_ptr;
thread_ptr -> tx_thread_suspended_previous = thread_ptr;
}
else
{
/* This list is not NULL, add current thread to the end. */
next_thread = pool_ptr -> tx_block_pool_suspension_list;
thread_ptr -> tx_thread_suspended_next = next_thread;
previous_thread = next_thread -> tx_thread_suspended_previous;
thread_ptr -> tx_thread_suspended_previous = previous_thread;
previous_thread -> tx_thread_suspended_next = thread_ptr;
next_thread -> tx_thread_suspended_previous = thread_ptr;
}
/* Set the state to suspended. */
thread_ptr -> tx_thread_state = TX_BLOCK_MEMORY;
#ifdef TX_NOT_INTERRUPTABLE
/* Call actual non-interruptable thread suspension routine. */
_tx_thread_system_ni_suspend(thread_ptr, wait_option);
/* Restore interrupts. */
TX_RESTORE
#else
/* Set the suspending flag. */
thread_ptr -> tx_thread_suspending = TX_TRUE;
/* Setup the timeout period. */
thread_ptr -> tx_thread_timer.tx_timer_internal_remaining_ticks = wait_option;
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Restore interrupts. */
TX_RESTORE
/* Call actual thread suspension routine. */
_tx_thread_system_suspend(thread_ptr);
#endif
#ifdef TX_ENABLE_EVENT_TRACE
/* Check that the event time stamp is unchanged. A different
timestamp means that a later event wrote over the byte
allocate event. In that case, do nothing here. */
if (entry_ptr != TX_NULL)
{
/* Is the time-stamp the same? */
if (time_stamp == entry_ptr -> tx_trace_buffer_entry_time_stamp)
{
/* Timestamp is the same, update the entry with the address. */
#ifdef TX_MISRA_ENABLE
entry_ptr -> tx_trace_buffer_entry_info_2 = TX_POINTER_TO_ULONG_CONVERT(*block_ptr);
#else
entry_ptr -> tx_trace_buffer_entry_information_field_2 = TX_POINTER_TO_ULONG_CONVERT(*block_ptr);
#endif
}
}
#endif
#ifdef TX_ENABLE_EVENT_LOGGING
/* Check that the event time stamp is unchanged and the call is about
to return success. A different timestamp means that a later event
wrote over the block allocate event. A return value other than
TX_SUCCESS indicates that no block was available. In those cases,
do nothing here. */
if (lower_tbu == *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) &&
upper_tbu == *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)) &&
((thread_ptr -> tx_thread_suspend_status) == TX_SUCCESS))
{
/* Store the address of the allocated block. */
*((ULONG *) (log_entry_ptr + TX_EL_EVENT_INFO_3_OFFSET)) = (ULONG) *block_ptr;
}
#endif
/* Return the completion status. */
status = thread_ptr -> tx_thread_suspend_status;
}
}
else
{
/* Immediate return, return error completion. */
status = TX_NO_MEMORY;
/* Restore interrupts. */
TX_RESTORE
}
}
/* Return completion status. */
return(status);
}

View File

@@ -0,0 +1,213 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Block Pool */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_thread.h"
#include "tx_block_pool.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_block_pool_cleanup PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes block allocate timeout and thread terminate */
/* actions that require the block pool data structures to be cleaned */
/* up. */
/* */
/* INPUT */
/* */
/* thread_ptr Pointer to suspended thread's */
/* control block */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_system_resume Resume thread service */
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
/* */
/* CALLED BY */
/* */
/* _tx_thread_timeout Thread timeout processing */
/* _tx_thread_terminate Thread terminate processing */
/* _tx_thread_wait_abort Thread wait abort processing */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _tx_block_pool_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence)
{
#ifndef TX_NOT_INTERRUPTABLE
TX_INTERRUPT_SAVE_AREA
#endif
TX_BLOCK_POOL *pool_ptr;
UINT suspended_count;
TX_THREAD *next_thread;
TX_THREAD *previous_thread;
#ifndef TX_NOT_INTERRUPTABLE
/* Disable interrupts to remove the suspended thread from the block pool. */
TX_DISABLE
/* Determine if the cleanup is still required. */
if (thread_ptr -> tx_thread_suspend_cleanup == &(_tx_block_pool_cleanup))
{
/* Check for valid suspension sequence. */
if (suspension_sequence == thread_ptr -> tx_thread_suspension_sequence)
{
/* Setup pointer to block pool control block. */
pool_ptr = TX_VOID_TO_BLOCK_POOL_POINTER_CONVERT(thread_ptr -> tx_thread_suspend_control_block);
/* Check for a NULL byte pool pointer. */
if (pool_ptr != TX_NULL)
{
/* Check for valid pool ID. */
if (pool_ptr -> tx_block_pool_id == TX_BLOCK_POOL_ID)
{
/* Determine if there are any thread suspensions. */
if (pool_ptr -> tx_block_pool_suspended_count != TX_NO_SUSPENSIONS)
{
#else
/* Setup pointer to block pool control block. */
pool_ptr = TX_VOID_TO_BLOCK_POOL_POINTER_CONVERT(thread_ptr -> tx_thread_suspend_control_block);
#endif
/* Yes, we still have thread suspension! */
/* Clear the suspension cleanup flag. */
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
/* Decrement the suspended count. */
pool_ptr -> tx_block_pool_suspended_count--;
/* Pickup the suspended count. */
suspended_count = pool_ptr -> tx_block_pool_suspended_count;
/* Remove the suspended thread from the list. */
/* See if this is the only suspended thread on the list. */
if (suspended_count == TX_NO_SUSPENSIONS)
{
/* Yes, the only suspended thread. */
/* Update the head pointer. */
pool_ptr -> tx_block_pool_suspension_list = TX_NULL;
}
else
{
/* At least one more thread is on the same suspension list. */
/* Update the links of the adjacent threads. */
next_thread = thread_ptr -> tx_thread_suspended_next;
previous_thread = thread_ptr -> tx_thread_suspended_previous;
next_thread -> tx_thread_suspended_previous = previous_thread;
previous_thread -> tx_thread_suspended_next = next_thread;
/* Determine if we need to update the head pointer. */
if (pool_ptr -> tx_block_pool_suspension_list == thread_ptr)
{
/* Update the list head pointer. */
pool_ptr -> tx_block_pool_suspension_list = next_thread;
}
}
/* Now we need to determine if this cleanup is from a terminate, timeout,
or from a wait abort. */
if (thread_ptr -> tx_thread_state == TX_BLOCK_MEMORY)
{
/* Timeout condition and the thread still suspended on the block pool.
Setup return error status and resume the thread. */
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
/* Increment the total timeouts counter. */
_tx_block_pool_performance_timeout_count++;
/* Increment the number of timeouts on this block pool. */
pool_ptr -> tx_block_pool_performance_timeout_count++;
#endif
/* Setup return status. */
thread_ptr -> tx_thread_suspend_status = TX_NO_MEMORY;
#ifdef TX_NOT_INTERRUPTABLE
/* Resume the thread! */
_tx_thread_system_ni_resume(thread_ptr);
#else
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Restore interrupts. */
TX_RESTORE
/* Resume the thread! */
_tx_thread_system_resume(thread_ptr);
/* Disable interrupts. */
TX_DISABLE
#endif
}
#ifndef TX_NOT_INTERRUPTABLE
}
}
}
}
}
/* Restore interrupts. */
TX_RESTORE
#endif
}

View File

@@ -0,0 +1,213 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Block Pool */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_trace.h"
#include "tx_block_pool.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_block_pool_create PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function creates a pool of fixed-size memory blocks in the */
/* specified memory area. */
/* */
/* INPUT */
/* */
/* pool_ptr Pointer to pool control block */
/* name_ptr Pointer to block pool name */
/* block_size Number of bytes in each block */
/* pool_start Address of beginning of pool area */
/* pool_size Number of bytes in the block pool */
/* */
/* OUTPUT */
/* */
/* TX_SUCCESS Successful completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_block_pool_create(TX_BLOCK_POOL *pool_ptr, CHAR *name_ptr, ULONG block_size,
VOID *pool_start, ULONG pool_size)
{
TX_INTERRUPT_SAVE_AREA
UINT blocks;
UINT status;
ULONG total_blocks;
UCHAR *block_ptr;
UCHAR **block_link_ptr;
UCHAR *next_block_ptr;
TX_BLOCK_POOL *next_pool;
TX_BLOCK_POOL *previous_pool;
/* Initialize block pool control block to all zeros. */
TX_MEMSET(pool_ptr, 0, (sizeof(TX_BLOCK_POOL)));
/* Round the block size up to something that is evenly divisible by
an ALIGN_TYPE (typically this is a 32-bit ULONG). This helps guarantee proper alignment. */
block_size = (((block_size + (sizeof(ALIGN_TYPE))) - ((ALIGN_TYPE) 1))/(sizeof(ALIGN_TYPE))) * (sizeof(ALIGN_TYPE));
/* Round the pool size down to something that is evenly divisible by
an ALIGN_TYPE (typically this is a 32-bit ULONG). */
pool_size = (pool_size/(sizeof(ALIGN_TYPE))) * (sizeof(ALIGN_TYPE));
/* Setup the basic block pool fields. */
pool_ptr -> tx_block_pool_name = name_ptr;
pool_ptr -> tx_block_pool_start = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
pool_ptr -> tx_block_pool_size = pool_size;
pool_ptr -> tx_block_pool_block_size = (UINT) block_size;
/* Calculate the total number of blocks. */
total_blocks = pool_size/(block_size + (sizeof(UCHAR *)));
/* Walk through the pool area, setting up the available block list. */
blocks = ((UINT) 0);
block_ptr = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
next_block_ptr = TX_UCHAR_POINTER_ADD(block_ptr, (block_size + (sizeof(UCHAR *))));
while(blocks < (UINT) total_blocks)
{
/* Yes, we have another block. Increment the block count. */
blocks++;
/* Setup the link to the next block. */
block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(block_ptr);
*block_link_ptr = next_block_ptr;
/* Advance to the next block. */
block_ptr = next_block_ptr;
/* Update the next block pointer. */
next_block_ptr = TX_UCHAR_POINTER_ADD(block_ptr, (block_size + (sizeof(UCHAR *))));
}
/* Save the remaining information in the pool control block. */
pool_ptr -> tx_block_pool_available = blocks;
pool_ptr -> tx_block_pool_total = blocks;
/* Quickly check to make sure at least one block is in the pool. */
if (blocks != ((UINT) 0))
{
/* Backup to the last block in the pool. */
block_ptr = TX_UCHAR_POINTER_SUB(block_ptr,(block_size + (sizeof(UCHAR *))));
/* Set the last block's forward pointer to NULL. */
block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(block_ptr);
*block_link_ptr = TX_NULL;
/* Setup the starting pool address. */
pool_ptr -> tx_block_pool_available_list = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
/* Disable interrupts to place the block pool on the created list. */
TX_DISABLE
/* Setup the block pool ID to make it valid. */
pool_ptr -> tx_block_pool_id = TX_BLOCK_POOL_ID;
/* Place the block pool on the list of created block pools. First,
check for an empty list. */
if (_tx_block_pool_created_count == TX_EMPTY)
{
/* The created block pool list is empty. Add block pool to empty list. */
_tx_block_pool_created_ptr = pool_ptr;
pool_ptr -> tx_block_pool_created_next = pool_ptr;
pool_ptr -> tx_block_pool_created_previous = pool_ptr;
}
else
{
/* This list is not NULL, add to the end of the list. */
next_pool = _tx_block_pool_created_ptr;
previous_pool = next_pool -> tx_block_pool_created_previous;
/* Place the new block pool in the list. */
next_pool -> tx_block_pool_created_previous = pool_ptr;
previous_pool -> tx_block_pool_created_next = pool_ptr;
/* Setup this block pool's created links. */
pool_ptr -> tx_block_pool_created_previous = previous_pool;
pool_ptr -> tx_block_pool_created_next = next_pool;
}
/* Increment the created count. */
_tx_block_pool_created_count++;
/* Optional block pool create extended processing. */
TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
/* If trace is enabled, register this object. */
TX_TRACE_OBJECT_REGISTER(TX_TRACE_OBJECT_TYPE_BLOCK_POOL, pool_ptr, name_ptr, pool_size, block_size)
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BLOCK_POOL_CREATE, pool_ptr, TX_POINTER_TO_ULONG_CONVERT(pool_start), blocks, block_size, TX_TRACE_BLOCK_POOL_EVENTS)
/* Log this kernel call. */
TX_EL_BLOCK_POOL_CREATE_INSERT
/* Restore interrupts. */
TX_RESTORE
/* Return successful status. */
status = TX_SUCCESS;
}
else
{
/* Not enough memory for one block, return appropriate error. */
status = TX_SIZE_ERROR;
}
/* Return completion status. */
return(status);
}

View File

@@ -0,0 +1,207 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Block Pool */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_trace.h"
#include "tx_thread.h"
#include "tx_block_pool.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_block_pool_delete PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function deletes the specified block pool. All threads */
/* suspended on the block pool are resumed with the TX_DELETED status */
/* code. */
/* */
/* INPUT */
/* */
/* pool_ptr Pointer to pool control block */
/* */
/* OUTPUT */
/* */
/* TX_SUCCESS Successful completion status */
/* */
/* CALLS */
/* */
/* _tx_thread_system_preempt_check Check for preemption */
/* _tx_thread_system_resume Resume thread service */
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_block_pool_delete(TX_BLOCK_POOL *pool_ptr)
{
TX_INTERRUPT_SAVE_AREA
TX_THREAD *thread_ptr;
TX_THREAD *next_thread;
UINT suspended_count;
TX_BLOCK_POOL *next_pool;
TX_BLOCK_POOL *previous_pool;
/* Disable interrupts to remove the block pool from the created list. */
TX_DISABLE
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BLOCK_POOL_DELETE, pool_ptr, TX_POINTER_TO_ULONG_CONVERT(&thread_ptr), 0, 0, TX_TRACE_BLOCK_POOL_EVENTS)
/* Log this kernel call. */
TX_EL_BLOCK_POOL_DELETE_INSERT
/* Optional block pool delete extended processing. */
TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
/* If trace is enabled, unregister this object. */
TX_TRACE_OBJECT_UNREGISTER(pool_ptr)
/* Clear the block pool ID to make it invalid. */
pool_ptr -> tx_block_pool_id = TX_CLEAR_ID;
/* Decrement the number of block pools. */
_tx_block_pool_created_count--;
/* See if the block pool is the only one on the list. */
if (_tx_block_pool_created_count == TX_EMPTY)
{
/* Only created block pool, just set the created list to NULL. */
_tx_block_pool_created_ptr = TX_NULL;
}
else
{
/* Link-up the neighbors. */
next_pool = pool_ptr -> tx_block_pool_created_next;
previous_pool = pool_ptr -> tx_block_pool_created_previous;
next_pool -> tx_block_pool_created_previous = previous_pool;
previous_pool -> tx_block_pool_created_next = next_pool;
/* See if we have to update the created list head pointer. */
if (_tx_block_pool_created_ptr == pool_ptr)
{
/* Yes, move the head pointer to the next link. */
_tx_block_pool_created_ptr = next_pool;
}
}
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Pickup the suspension information. */
thread_ptr = pool_ptr -> tx_block_pool_suspension_list;
pool_ptr -> tx_block_pool_suspension_list = TX_NULL;
suspended_count = pool_ptr -> tx_block_pool_suspended_count;
pool_ptr -> tx_block_pool_suspended_count = TX_NO_SUSPENSIONS;
/* Restore interrupts. */
TX_RESTORE
/* Walk through the block pool suspension list to resume any and all threads suspended
on this block pool. */
while (suspended_count != TX_NO_SUSPENSIONS)
{
/* Decrement the suspension count. */
suspended_count--;
/* Lockout interrupts. */
TX_DISABLE
/* Clear the cleanup pointer, this prevents the timeout from doing
anything. */
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
/* Set the return status in the thread to TX_DELETED. */
thread_ptr -> tx_thread_suspend_status = TX_DELETED;
/* Move the thread pointer ahead. */
next_thread = thread_ptr -> tx_thread_suspended_next;
#ifdef TX_NOT_INTERRUPTABLE
/* Resume the thread! */
_tx_thread_system_ni_resume(thread_ptr);
/* Restore interrupts. */
TX_RESTORE
#else
/* Temporarily disable preemption again. */
_tx_thread_preempt_disable++;
/* Restore interrupts. */
TX_RESTORE
/* Resume the thread. */
_tx_thread_system_resume(thread_ptr);
#endif
/* Move to next thread. */
thread_ptr = next_thread;
}
/* Execute Port-Specific completion processing. If needed, it is typically defined in tx_port.h. */
TX_BLOCK_POOL_DELETE_PORT_COMPLETION(pool_ptr)
/* Disable interrupts. */
TX_DISABLE
/* Release previous preempt disable. */
_tx_thread_preempt_disable--;
/* Restore interrupts. */
TX_RESTORE
/* Check for preemption. */
_tx_thread_system_preempt_check();
/* Return TX_SUCCESS. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,146 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Block Memory */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_trace.h"
#include "tx_block_pool.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_block_pool_info_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function retrieves information from the specified block pool. */
/* */
/* INPUT */
/* */
/* pool_ptr Pointer to block pool control blk */
/* name Destination for the pool name */
/* available_blocks Number of free blocks in pool */
/* total_blocks Total number of blocks in pool */
/* first_suspended Destination for pointer of first */
/* thread suspended on block pool */
/* suspended_count Destination for suspended count */
/* next_pool Destination for pointer to next */
/* block pool on the created list */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_block_pool_info_get(TX_BLOCK_POOL *pool_ptr, CHAR **name, ULONG *available_blocks,
ULONG *total_blocks, TX_THREAD **first_suspended,
ULONG *suspended_count, TX_BLOCK_POOL **next_pool)
{
TX_INTERRUPT_SAVE_AREA
/* Disable interrupts. */
TX_DISABLE
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BLOCK_POOL_INFO_GET, pool_ptr, 0, 0, 0, TX_TRACE_BLOCK_POOL_EVENTS)
/* Log this kernel call. */
TX_EL_BLOCK_POOL_INFO_GET_INSERT
/* Retrieve all the pertinent information and return it in the supplied
destinations. */
/* Retrieve the name of the block pool. */
if (name != TX_NULL)
{
*name = pool_ptr -> tx_block_pool_name;
}
/* Retrieve the number of available blocks in the block pool. */
if (available_blocks != TX_NULL)
{
*available_blocks = (ULONG) pool_ptr -> tx_block_pool_available;
}
/* Retrieve the total number of blocks in the block pool. */
if (total_blocks != TX_NULL)
{
*total_blocks = (ULONG) pool_ptr -> tx_block_pool_total;
}
/* Retrieve the first thread suspended on this block pool. */
if (first_suspended != TX_NULL)
{
*first_suspended = pool_ptr -> tx_block_pool_suspension_list;
}
/* Retrieve the number of threads suspended on this block pool. */
if (suspended_count != TX_NULL)
{
*suspended_count = (ULONG) pool_ptr -> tx_block_pool_suspended_count;
}
/* Retrieve the pointer to the next block pool created. */
if (next_pool != TX_NULL)
{
*next_pool = pool_ptr -> tx_block_pool_created_next;
}
/* Restore interrupts. */
TX_RESTORE
/* Return completion status. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,129 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Block Pool */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_block_pool.h"
#ifndef TX_INLINE_INITIALIZATION
/* Locate block pool component data in this file. */
/* Define the head pointer of the created block pool list. */
TX_BLOCK_POOL * _tx_block_pool_created_ptr;
/* Define the variable that holds the number of created block pools. */
ULONG _tx_block_pool_created_count;
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
/* Define the total number of block allocates. */
ULONG _tx_block_pool_performance_allocate_count;
/* Define the total number of block releases. */
ULONG _tx_block_pool_performance_release_count;
/* Define the total number of block pool suspensions. */
ULONG _tx_block_pool_performance_suspension_count;
/* Define the total number of block pool timeouts. */
ULONG _tx_block_pool_performance_timeout_count;
#endif
#endif
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_block pool_initialize PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function initializes the various control data structures for */
/* the block pool component. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_initialize_high_level High level initialization */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _tx_block_pool_initialize(VOID)
{
#ifndef TX_DISABLE_REDUNDANT_CLEARING
/* Initialize the head pointer of the created block pools list and the
number of block pools created. */
_tx_block_pool_created_ptr = TX_NULL;
_tx_block_pool_created_count = TX_EMPTY;
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
/* Initialize block pool performance counters. */
_tx_block_pool_performance_allocate_count = ((ULONG) 0);
_tx_block_pool_performance_release_count = ((ULONG) 0);
_tx_block_pool_performance_suspension_count = ((ULONG) 0);
_tx_block_pool_performance_timeout_count = ((ULONG) 0);
#endif
#endif
}

View File

@@ -0,0 +1,201 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Block Memory */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_block_pool.h"
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
#include "tx_trace.h"
#endif
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_block_pool_performance_info_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function retrieves performance information from the specified */
/* block pool. */
/* */
/* INPUT */
/* */
/* pool_ptr Pointer to block pool control blk */
/* allocates Destination for the number of */
/* allocations from this pool */
/* releases Destination for the number of */
/* blocks released back to pool */
/* suspensions Destination for number of */
/* suspensions on this pool */
/* timeouts Destination for number of timeouts*/
/* on this pool */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_block_pool_performance_info_get(TX_BLOCK_POOL *pool_ptr, ULONG *allocates, ULONG *releases,
ULONG *suspensions, ULONG *timeouts)
{
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
TX_INTERRUPT_SAVE_AREA
UINT status;
/* Determine if this is a legal request. */
if (pool_ptr == TX_NULL)
{
/* Block pool pointer is illegal, return error. */
status = TX_PTR_ERROR;
}
/* Determine if the pool ID is invalid. */
else if (pool_ptr -> tx_block_pool_id != TX_BLOCK_POOL_ID)
{
/* Block pool pointer is illegal, return error. */
status = TX_PTR_ERROR;
}
else
{
/* Disable interrupts. */
TX_DISABLE
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BLOCK_POOL_PERFORMANCE_INFO_GET, pool_ptr, 0, 0, 0, TX_TRACE_BLOCK_POOL_EVENTS)
/* Log this kernel call. */
TX_EL_BLOCK_POOL_PERFORMANCE_INFO_GET_INSERT
/* Retrieve all the pertinent information and return it in the supplied
destinations. */
/* Retrieve the number of allocations from this block pool. */
if (allocates != TX_NULL)
{
*allocates = pool_ptr -> tx_block_pool_performance_allocate_count;
}
/* Retrieve the number of blocks released to this block pool. */
if (releases != TX_NULL)
{
*releases = pool_ptr -> tx_block_pool_performance_release_count;
}
/* Retrieve the number of thread suspensions on this block pool. */
if (suspensions != TX_NULL)
{
*suspensions = pool_ptr -> tx_block_pool_performance_suspension_count;
}
/* Retrieve the number of thread timeouts on this block pool. */
if (timeouts != TX_NULL)
{
*timeouts = pool_ptr -> tx_block_pool_performance_timeout_count;
}
/* Restore interrupts. */
TX_RESTORE
/* Return successful completion. */
status = TX_SUCCESS;
}
#else
UINT status;
/* Access input arguments just for the sake of lint, MISRA, etc. */
if (pool_ptr != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (allocates != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (releases != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (suspensions != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (timeouts != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
#endif
/* Return completion status. */
return(status);
}

View File

@@ -0,0 +1,173 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Block Memory */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_block_pool.h"
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
#include "tx_trace.h"
#endif
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_block_pool_performance_system_info_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function retrieves block pool performance information. */
/* */
/* INPUT */
/* */
/* allocates Destination for the total number */
/* of block allocations */
/* releases Destination for the total number */
/* of blocks released */
/* suspensions Destination for the total number */
/* of suspensions */
/* timeouts Destination for total number of */
/* timeouts */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_block_pool_performance_system_info_get(ULONG *allocates, ULONG *releases, ULONG *suspensions, ULONG *timeouts)
{
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
TX_INTERRUPT_SAVE_AREA
/* Disable interrupts. */
TX_DISABLE
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BLOCK_POOL__PERFORMANCE_SYSTEM_INFO_GET, 0, 0, 0, 0, TX_TRACE_BLOCK_POOL_EVENTS)
/* Log this kernel call. */
TX_EL_BLOCK_POOL_PERFORMANCE_SYSTEM_INFO_GET_INSERT
/* Retrieve all the pertinent information and return it in the supplied
destinations. */
/* Retrieve the total number of block allocations. */
if (allocates != TX_NULL)
{
*allocates = _tx_block_pool_performance_allocate_count;
}
/* Retrieve the total number of blocks released. */
if (releases != TX_NULL)
{
*releases = _tx_block_pool_performance_release_count;
}
/* Retrieve the total number of block pool thread suspensions. */
if (suspensions != TX_NULL)
{
*suspensions = _tx_block_pool_performance_suspension_count;
}
/* Retrieve the total number of block pool thread timeouts. */
if (timeouts != TX_NULL)
{
*timeouts = _tx_block_pool_performance_timeout_count;
}
/* Restore interrupts. */
TX_RESTORE
/* Return completion status. */
return(TX_SUCCESS);
#else
UINT status;
/* Access input arguments just for the sake of lint, MISRA, etc. */
if (allocates != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (releases != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (suspensions != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (timeouts != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
/* Return completion status. */
return(status);
#endif
}

View File

@@ -0,0 +1,249 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Block Pool */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_trace.h"
#include "tx_thread.h"
#include "tx_block_pool.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_block_pool_prioritize PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function places the highest priority suspended thread at the */
/* front of the suspension list. All other threads remain in the same */
/* FIFO suspension order. */
/* */
/* INPUT */
/* */
/* pool_ptr Pointer to pool control block */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _tx_thread_system_preempt_check Check for preemption */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_block_pool_prioritize(TX_BLOCK_POOL *pool_ptr)
{
TX_INTERRUPT_SAVE_AREA
TX_THREAD *thread_ptr;
TX_THREAD *priority_thread_ptr;
TX_THREAD *head_ptr;
UINT suspended_count;
TX_THREAD *next_thread;
TX_THREAD *previous_thread;
UINT list_changed;
/* Disable interrupts. */
TX_DISABLE
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BLOCK_POOL_PRIORITIZE, pool_ptr, pool_ptr -> tx_block_pool_suspended_count, TX_POINTER_TO_ULONG_CONVERT(&suspended_count), 0, TX_TRACE_BLOCK_POOL_EVENTS)
/* Log this kernel call. */
TX_EL_BLOCK_POOL_PRIORITIZE_INSERT
/* Pickup the suspended count. */
suspended_count = pool_ptr -> tx_block_pool_suspended_count;
/* Determine if there are fewer than 2 suspended threads. */
if (suspended_count < ((UINT) 2))
{
/* Restore interrupts. */
TX_RESTORE
}
/* Determine if there how many threads are suspended on this block memory pool. */
else if (suspended_count == ((UINT) 2))
{
/* Pickup the head pointer and the next pointer. */
head_ptr = pool_ptr -> tx_block_pool_suspension_list;
next_thread = head_ptr -> tx_thread_suspended_next;
/* Determine if the next suspended thread has a higher priority. */
if ((next_thread -> tx_thread_priority) < (head_ptr -> tx_thread_priority))
{
/* Yes, move the list head to the next thread. */
pool_ptr -> tx_block_pool_suspension_list = next_thread;
}
/* Restore interrupts. */
TX_RESTORE
}
else
{
/* Remember the suspension count and head pointer. */
head_ptr = pool_ptr -> tx_block_pool_suspension_list;
/* Default the highest priority thread to the thread at the front of the list. */
priority_thread_ptr = head_ptr;
/* Setup search pointer. */
thread_ptr = priority_thread_ptr -> tx_thread_suspended_next;
/* Disable preemption. */
_tx_thread_preempt_disable++;
/* Set the list changed flag to false. */
list_changed = TX_FALSE;
/* Search through the list to find the highest priority thread. */
do
{
/* Is the current thread higher priority? */
if (thread_ptr -> tx_thread_priority < priority_thread_ptr -> tx_thread_priority)
{
/* Yes, remember that this thread is the highest priority. */
priority_thread_ptr = thread_ptr;
}
/* Restore interrupts temporarily. */
TX_RESTORE
/* Disable interrupts again. */
TX_DISABLE
/* Determine if any changes to the list have occurred while
interrupts were enabled. */
/* Is the list head the same? */
if (head_ptr != pool_ptr -> tx_block_pool_suspension_list)
{
/* The list head has changed, set the list changed flag. */
list_changed = TX_TRUE;
}
else
{
/* Is the suspended count the same? */
if (suspended_count != pool_ptr -> tx_block_pool_suspended_count)
{
/* The list head has changed, set the list changed flag. */
list_changed = TX_TRUE;
}
}
/* Determine if the list has changed. */
if (list_changed == TX_FALSE)
{
/* Move the thread pointer to the next thread. */
thread_ptr = thread_ptr -> tx_thread_suspended_next;
}
else
{
/* Remember the suspension count and head pointer. */
head_ptr = pool_ptr -> tx_block_pool_suspension_list;
suspended_count = pool_ptr -> tx_block_pool_suspended_count;
/* Default the highest priority thread to the thread at the front of the list. */
priority_thread_ptr = head_ptr;
/* Setup search pointer. */
thread_ptr = priority_thread_ptr -> tx_thread_suspended_next;
/* Reset the list changed flag. */
list_changed = TX_FALSE;
}
} while (thread_ptr != head_ptr);
/* Release preemption. */
_tx_thread_preempt_disable--;
/* Now determine if the highest priority thread is at the front
of the list. */
if (priority_thread_ptr != head_ptr)
{
/* No, we need to move the highest priority suspended thread to the
front of the list. */
/* First, remove the highest priority thread by updating the
adjacent suspended threads. */
next_thread = priority_thread_ptr -> tx_thread_suspended_next;
previous_thread = priority_thread_ptr -> tx_thread_suspended_previous;
next_thread -> tx_thread_suspended_previous = previous_thread;
previous_thread -> tx_thread_suspended_next = next_thread;
/* Now, link the highest priority thread at the front of the list. */
previous_thread = head_ptr -> tx_thread_suspended_previous;
priority_thread_ptr -> tx_thread_suspended_next = head_ptr;
priority_thread_ptr -> tx_thread_suspended_previous = previous_thread;
previous_thread -> tx_thread_suspended_next = priority_thread_ptr;
head_ptr -> tx_thread_suspended_previous = priority_thread_ptr;
/* Move the list head pointer to the highest priority suspended thread. */
pool_ptr -> tx_block_pool_suspension_list = priority_thread_ptr;
}
/* Restore interrupts. */
TX_RESTORE
/* Check for preemption. */
_tx_thread_system_preempt_check();
}
/* Return successful status. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,204 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Block Pool */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_trace.h"
#include "tx_thread.h"
#include "tx_block_pool.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_block_release PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function returns a previously allocated block to its */
/* associated memory block pool. */
/* */
/* INPUT */
/* */
/* block_ptr Pointer to memory block */
/* */
/* OUTPUT */
/* */
/* TX_SUCCESS Successful completion status */
/* */
/* CALLS */
/* */
/* _tx_thread_system_resume Resume thread service */
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_block_release(VOID *block_ptr)
{
TX_INTERRUPT_SAVE_AREA
TX_BLOCK_POOL *pool_ptr;
TX_THREAD *thread_ptr;
UCHAR *work_ptr;
UCHAR **return_block_ptr;
UCHAR **next_block_ptr;
UINT suspended_count;
TX_THREAD *next_thread;
TX_THREAD *previous_thread;
/* Disable interrupts to put this block back in the pool. */
TX_DISABLE
/* Pickup the pool pointer which is just previous to the starting
address of the block that the caller sees. */
work_ptr = TX_VOID_TO_UCHAR_POINTER_CONVERT(block_ptr);
work_ptr = TX_UCHAR_POINTER_SUB(work_ptr, (sizeof(UCHAR *)));
next_block_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(work_ptr);
pool_ptr = TX_UCHAR_TO_BLOCK_POOL_POINTER_CONVERT((*next_block_ptr));
#ifdef TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
/* Increment the total releases counter. */
_tx_block_pool_performance_release_count++;
/* Increment the number of releases on this pool. */
pool_ptr -> tx_block_pool_performance_release_count++;
#endif
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BLOCK_RELEASE, pool_ptr, TX_POINTER_TO_ULONG_CONVERT(block_ptr), pool_ptr -> tx_block_pool_suspended_count, TX_POINTER_TO_ULONG_CONVERT(&work_ptr), TX_TRACE_BLOCK_POOL_EVENTS)
/* Log this kernel call. */
TX_EL_BLOCK_RELEASE_INSERT
/* Determine if there are any threads suspended on the block pool. */
thread_ptr = pool_ptr -> tx_block_pool_suspension_list;
if (thread_ptr != TX_NULL)
{
/* Remove the suspended thread from the list. */
/* Decrement the number of threads suspended. */
(pool_ptr -> tx_block_pool_suspended_count)--;
/* Pickup the suspended count. */
suspended_count = (pool_ptr -> tx_block_pool_suspended_count);
/* See if this is the only suspended thread on the list. */
if (suspended_count == TX_NO_SUSPENSIONS)
{
/* Yes, the only suspended thread. */
/* Update the head pointer. */
pool_ptr -> tx_block_pool_suspension_list = TX_NULL;
}
else
{
/* At least one more thread is on the same expiration list. */
/* Update the list head pointer. */
next_thread = thread_ptr -> tx_thread_suspended_next;
pool_ptr -> tx_block_pool_suspension_list = next_thread;
/* Update the links of the adjacent threads. */
previous_thread = thread_ptr -> tx_thread_suspended_previous;
next_thread -> tx_thread_suspended_previous = previous_thread;
previous_thread -> tx_thread_suspended_next = next_thread;
}
/* Prepare for resumption of the first thread. */
/* Clear cleanup routine to avoid timeout. */
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
/* Return this block pointer to the suspended thread waiting for
a block. */
return_block_ptr = TX_VOID_TO_INDIRECT_UCHAR_POINTER_CONVERT(thread_ptr -> tx_thread_additional_suspend_info);
work_ptr = TX_VOID_TO_UCHAR_POINTER_CONVERT(block_ptr);
*return_block_ptr = work_ptr;
/* Put return status into the thread control block. */
thread_ptr -> tx_thread_suspend_status = TX_SUCCESS;
#ifdef TX_NOT_INTERRUPTABLE
/* Resume the thread! */
_tx_thread_system_ni_resume(thread_ptr);
/* Restore interrupts. */
TX_RESTORE
#else
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Restore interrupts. */
TX_RESTORE
/* Resume thread. */
_tx_thread_system_resume(thread_ptr);
#endif
}
else
{
/* No thread is suspended for a memory block. */
/* Put the block back in the available list. */
*next_block_ptr = pool_ptr -> tx_block_pool_available_list;
/* Adjust the head pointer. */
pool_ptr -> tx_block_pool_available_list = work_ptr;
/* Increment the count of available blocks. */
pool_ptr -> tx_block_pool_available++;
/* Restore interrupts. */
TX_RESTORE
}
/* Return successful completion status. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,409 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Byte Memory */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#ifdef TX_ENABLE_EVENT_TRACE
#include "tx_trace.h"
#endif
#include "tx_thread.h"
#include "tx_byte_pool.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_byte_allocate PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function allocates bytes from the specified memory byte */
/* pool. */
/* */
/* INPUT */
/* */
/* pool_ptr Pointer to pool control block */
/* memory_ptr Pointer to place allocated bytes */
/* pointer */
/* memory_size Number of bytes to allocate */
/* wait_option Suspension option */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _tx_thread_system_suspend Suspend thread service */
/* _tx_thread_system_ni_suspend Non-interruptable suspend thread */
/* _tx_byte_pool_search Search byte pool for memory */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_byte_allocate(TX_BYTE_POOL *pool_ptr, VOID **memory_ptr, ULONG memory_size, ULONG wait_option)
{
TX_INTERRUPT_SAVE_AREA
UINT status;
TX_THREAD *thread_ptr;
UCHAR *work_ptr;
UINT suspended_count;
TX_THREAD *next_thread;
TX_THREAD *previous_thread;
UINT finished;
#ifdef TX_ENABLE_EVENT_TRACE
TX_TRACE_BUFFER_ENTRY *entry_ptr;
ULONG time_stamp = ((ULONG) 0);
#endif
#ifdef TX_ENABLE_EVENT_LOGGING
UCHAR *log_entry_ptr;
ULONG upper_tbu;
ULONG lower_tbu;
#endif
/* Round the memory size up to the next size that is evenly divisible by
an ALIGN_TYPE (this is typically a 32-bit ULONG). This guarantees proper alignment. */
memory_size = (((memory_size + (sizeof(ALIGN_TYPE)))-((ALIGN_TYPE) 1))/(sizeof(ALIGN_TYPE))) * (sizeof(ALIGN_TYPE));
/* Disable interrupts. */
TX_DISABLE
/* Pickup thread pointer. */
TX_THREAD_GET_CURRENT(thread_ptr)
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
/* Increment the total allocations counter. */
_tx_byte_pool_performance_allocate_count++;
/* Increment the number of allocations on this pool. */
pool_ptr -> tx_byte_pool_performance_allocate_count++;
#endif
#ifdef TX_ENABLE_EVENT_TRACE
/* If trace is enabled, save the current event pointer. */
entry_ptr = _tx_trace_buffer_current_ptr;
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BYTE_ALLOCATE, pool_ptr, 0, memory_size, wait_option, TX_TRACE_BYTE_POOL_EVENTS)
/* Save the time stamp for later comparison to verify that
the event hasn't been overwritten by the time the allocate
call succeeds. */
if (entry_ptr != TX_NULL)
{
time_stamp = entry_ptr -> tx_trace_buffer_entry_time_stamp;
}
#endif
#ifdef TX_ENABLE_EVENT_LOGGING
log_entry_ptr = *(UCHAR **) _tx_el_current_event;
/* Log this kernel call. */
TX_EL_BYTE_ALLOCATE_INSERT
/* Store -1 in the fourth event slot. */
*((ULONG *) (log_entry_ptr + TX_EL_EVENT_INFO_4_OFFSET)) = (ULONG) -1;
/* Save the time stamp for later comparison to verify that
the event hasn't been overwritten by the time the allocate
call succeeds. */
lower_tbu = *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET));
upper_tbu = *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET));
#endif
/* Set the search finished flag to false. */
finished = TX_FALSE;
/* Loop to handle cases where the owner of the pool changed. */
do
{
/* Indicate that this thread is the current owner. */
pool_ptr -> tx_byte_pool_owner = thread_ptr;
/* Restore interrupts. */
TX_RESTORE
/* At this point, the executing thread owns the pool and can perform a search
for free memory. */
work_ptr = _tx_byte_pool_search(pool_ptr, memory_size);
/* Optional processing extension. */
TX_BYTE_ALLOCATE_EXTENSION
/* Lockout interrupts. */
TX_DISABLE
/* Determine if we are finished. */
if (work_ptr != TX_NULL)
{
/* Yes, we have found a block the search is finished. */
finished = TX_TRUE;
}
else
{
/* No block was found, does this thread still own the pool? */
if (pool_ptr -> tx_byte_pool_owner == thread_ptr)
{
/* Yes, then we have looked through the entire pool and haven't found the memory. */
finished = TX_TRUE;
}
}
} while (finished == TX_FALSE);
/* Copy the pointer into the return destination. */
*memory_ptr = (VOID *) work_ptr;
/* Determine if memory was found. */
if (work_ptr != TX_NULL)
{
#ifdef TX_ENABLE_EVENT_TRACE
/* Check that the event time stamp is unchanged. A different
timestamp means that a later event wrote over the byte
allocate event. In that case, do nothing here. */
if (entry_ptr != TX_NULL)
{
/* Is the timestamp the same? */
if (time_stamp == entry_ptr -> tx_trace_buffer_entry_time_stamp)
{
/* Timestamp is the same, update the entry with the address. */
#ifdef TX_MISRA_ENABLE
entry_ptr -> tx_trace_buffer_entry_info_2 = TX_POINTER_TO_ULONG_CONVERT(*memory_ptr);
#else
entry_ptr -> tx_trace_buffer_entry_information_field_2 = TX_POINTER_TO_ULONG_CONVERT(*memory_ptr);
#endif
}
}
#endif
#ifdef TX_ENABLE_EVENT_LOGGING
/* Check that the event time stamp is unchanged. A different
timestamp means that a later event wrote over the byte
allocate event. In that case, do nothing here. */
if (lower_tbu == *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) &&
upper_tbu == *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)))
{
/* Store the address of the allocated fragment. */
*((ULONG *) (log_entry_ptr + TX_EL_EVENT_INFO_4_OFFSET)) = (ULONG) *memory_ptr;
}
#endif
/* Restore interrupts. */
TX_RESTORE
/* Set the status to success. */
status = TX_SUCCESS;
}
else
{
/* No memory of sufficient size was found... */
/* Determine if the request specifies suspension. */
if (wait_option != TX_NO_WAIT)
{
/* Determine if the preempt disable flag is non-zero. */
if (_tx_thread_preempt_disable != ((UINT) 0))
{
/* Suspension is not allowed if the preempt disable flag is non-zero at this point - return error completion. */
status = TX_NO_MEMORY;
/* Restore interrupts. */
TX_RESTORE
}
else
{
/* Prepare for suspension of this thread. */
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
/* Increment the total suspensions counter. */
_tx_byte_pool_performance_suspension_count++;
/* Increment the number of suspensions on this pool. */
pool_ptr -> tx_byte_pool_performance_suspension_count++;
#endif
/* Setup cleanup routine pointer. */
thread_ptr -> tx_thread_suspend_cleanup = &(_tx_byte_pool_cleanup);
/* Setup cleanup information, i.e. this pool control
block. */
thread_ptr -> tx_thread_suspend_control_block = (VOID *) pool_ptr;
/* Save the return memory pointer address as well. */
thread_ptr -> tx_thread_additional_suspend_info = (VOID *) memory_ptr;
/* Save the byte size requested. */
thread_ptr -> tx_thread_suspend_info = memory_size;
#ifndef TX_NOT_INTERRUPTABLE
/* Increment the suspension sequence number, which is used to identify
this suspension event. */
thread_ptr -> tx_thread_suspension_sequence++;
#endif
/* Pickup the number of suspended threads. */
suspended_count = pool_ptr -> tx_byte_pool_suspended_count;
/* Increment the suspension count. */
(pool_ptr -> tx_byte_pool_suspended_count)++;
/* Setup suspension list. */
if (suspended_count == TX_NO_SUSPENSIONS)
{
/* No other threads are suspended. Setup the head pointer and
just setup this threads pointers to itself. */
pool_ptr -> tx_byte_pool_suspension_list = thread_ptr;
thread_ptr -> tx_thread_suspended_next = thread_ptr;
thread_ptr -> tx_thread_suspended_previous = thread_ptr;
}
else
{
/* This list is not NULL, add current thread to the end. */
next_thread = pool_ptr -> tx_byte_pool_suspension_list;
thread_ptr -> tx_thread_suspended_next = next_thread;
previous_thread = next_thread -> tx_thread_suspended_previous;
thread_ptr -> tx_thread_suspended_previous = previous_thread;
previous_thread -> tx_thread_suspended_next = thread_ptr;
next_thread -> tx_thread_suspended_previous = thread_ptr;
}
/* Set the state to suspended. */
thread_ptr -> tx_thread_state = TX_BYTE_MEMORY;
#ifdef TX_NOT_INTERRUPTABLE
/* Call actual non-interruptable thread suspension routine. */
_tx_thread_system_ni_suspend(thread_ptr, wait_option);
/* Restore interrupts. */
TX_RESTORE
#else
/* Set the suspending flag. */
thread_ptr -> tx_thread_suspending = TX_TRUE;
/* Setup the timeout period. */
thread_ptr -> tx_thread_timer.tx_timer_internal_remaining_ticks = wait_option;
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Restore interrupts. */
TX_RESTORE
/* Call actual thread suspension routine. */
_tx_thread_system_suspend(thread_ptr);
#endif
#ifdef TX_ENABLE_EVENT_TRACE
/* Check that the event time stamp is unchanged. A different
timestamp means that a later event wrote over the byte
allocate event. In that case, do nothing here. */
if (entry_ptr != TX_NULL)
{
/* Is the timestamp the same? */
if (time_stamp == entry_ptr -> tx_trace_buffer_entry_time_stamp)
{
/* Timestamp is the same, update the entry with the address. */
#ifdef TX_MISRA_ENABLE
entry_ptr -> tx_trace_buffer_entry_info_2 = TX_POINTER_TO_ULONG_CONVERT(*memory_ptr);
#else
entry_ptr -> tx_trace_buffer_entry_information_field_2 = TX_POINTER_TO_ULONG_CONVERT(*memory_ptr);
#endif
}
}
#endif
#ifdef TX_ENABLE_EVENT_LOGGING
/* Check that the event time stamp is unchanged. A different
timestamp means that a later event wrote over the byte
allocate event. In that case, do nothing here. */
if (lower_tbu == *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_LOWER_OFFSET)) &&
upper_tbu == *((ULONG *) (log_entry_ptr + TX_EL_EVENT_TIME_UPPER_OFFSET)))
{
/* Store the address of the allocated fragment. */
*((ULONG *) (log_entry_ptr + TX_EL_EVENT_INFO_4_OFFSET)) = (ULONG) *memory_ptr;
}
#endif
/* Return the completion status. */
status = thread_ptr -> tx_thread_suspend_status;
}
}
else
{
/* Restore interrupts. */
TX_RESTORE
/* Immediate return, return error completion. */
status = TX_NO_MEMORY;
}
}
/* Return completion status. */
return(status);
}

View File

@@ -0,0 +1,212 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Byte Memory */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_thread.h"
#include "tx_byte_pool.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_byte_pool_cleanup PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes byte allocate timeout and thread terminate */
/* actions that require the byte pool data structures to be cleaned */
/* up. */
/* */
/* INPUT */
/* */
/* thread_ptr Pointer to suspended thread's */
/* control block */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_system_resume Resume thread service */
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
/* */
/* CALLED BY */
/* */
/* _tx_thread_timeout Thread timeout processing */
/* _tx_thread_terminate Thread terminate processing */
/* _tx_thread_wait_abort Thread wait abort processing */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _tx_byte_pool_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence)
{
#ifndef TX_NOT_INTERRUPTABLE
TX_INTERRUPT_SAVE_AREA
#endif
TX_BYTE_POOL *pool_ptr;
UINT suspended_count;
TX_THREAD *next_thread;
TX_THREAD *previous_thread;
#ifndef TX_NOT_INTERRUPTABLE
/* Disable interrupts to remove the suspended thread from the byte pool. */
TX_DISABLE
/* Determine if the cleanup is still required. */
if (thread_ptr -> tx_thread_suspend_cleanup == &(_tx_byte_pool_cleanup))
{
/* Check for valid suspension sequence. */
if (suspension_sequence == thread_ptr -> tx_thread_suspension_sequence)
{
/* Setup pointer to byte pool control block. */
pool_ptr = TX_VOID_TO_BYTE_POOL_POINTER_CONVERT(thread_ptr -> tx_thread_suspend_control_block);
/* Check for a NULL byte pool pointer. */
if (pool_ptr != TX_NULL)
{
/* Check for valid pool ID. */
if (pool_ptr -> tx_byte_pool_id == TX_BYTE_POOL_ID)
{
/* Determine if there are any thread suspensions. */
if (pool_ptr -> tx_byte_pool_suspended_count != TX_NO_SUSPENSIONS)
{
#else
/* Setup pointer to byte pool control block. */
pool_ptr = TX_VOID_TO_BYTE_POOL_POINTER_CONVERT(thread_ptr -> tx_thread_suspend_control_block);
#endif
/* Thread suspended for memory... Clear the suspension cleanup flag. */
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
/* Decrement the suspension count. */
pool_ptr -> tx_byte_pool_suspended_count--;
/* Pickup the suspended count. */
suspended_count = pool_ptr -> tx_byte_pool_suspended_count;
/* Remove the suspended thread from the list. */
/* See if this is the only suspended thread on the list. */
if (suspended_count == TX_NO_SUSPENSIONS)
{
/* Yes, the only suspended thread. */
/* Update the head pointer. */
pool_ptr -> tx_byte_pool_suspension_list = TX_NULL;
}
else
{
/* At least one more thread is on the same suspension list. */
/* Update the links of the adjacent threads. */
next_thread = thread_ptr -> tx_thread_suspended_next;
previous_thread = thread_ptr -> tx_thread_suspended_previous;
next_thread -> tx_thread_suspended_previous = previous_thread;
previous_thread -> tx_thread_suspended_next = next_thread;
/* Determine if we need to update the head pointer. */
if (pool_ptr -> tx_byte_pool_suspension_list == thread_ptr)
{
/* Update the list head pointer. */
pool_ptr -> tx_byte_pool_suspension_list = next_thread;
}
}
/* Now we need to determine if this cleanup is from a terminate, timeout,
or from a wait abort. */
if (thread_ptr -> tx_thread_state == TX_BYTE_MEMORY)
{
/* Timeout condition and the thread still suspended on the byte pool.
Setup return error status and resume the thread. */
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
/* Increment the total timeouts counter. */
_tx_byte_pool_performance_timeout_count++;
/* Increment the number of timeouts on this byte pool. */
pool_ptr -> tx_byte_pool_performance_timeout_count++;
#endif
/* Setup return status. */
thread_ptr -> tx_thread_suspend_status = TX_NO_MEMORY;
#ifdef TX_NOT_INTERRUPTABLE
/* Resume the thread! */
_tx_thread_system_ni_resume(thread_ptr);
#else
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Restore interrupts. */
TX_RESTORE
/* Resume the thread! */
_tx_thread_system_resume(thread_ptr);
/* Disable interrupts. */
TX_DISABLE
#endif
}
#ifndef TX_NOT_INTERRUPTABLE
}
}
}
}
}
/* Restore interrupts. */
TX_RESTORE
#endif
}

View File

@@ -0,0 +1,197 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Byte Pool */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_trace.h"
#include "tx_byte_pool.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_byte_pool_create PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function creates a pool of memory bytes in the specified */
/* memory area. */
/* */
/* INPUT */
/* */
/* pool_ptr Pointer to pool control block */
/* name_ptr Pointer to byte pool name */
/* pool_start Address of beginning of pool area */
/* pool_size Number of bytes in the byte pool */
/* */
/* OUTPUT */
/* */
/* TX_SUCCESS Successful completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_byte_pool_create(TX_BYTE_POOL *pool_ptr, CHAR *name_ptr, VOID *pool_start, ULONG pool_size)
{
TX_INTERRUPT_SAVE_AREA
UCHAR *block_ptr;
UCHAR **block_indirect_ptr;
UCHAR *temp_ptr;
TX_BYTE_POOL *next_pool;
TX_BYTE_POOL *previous_pool;
ALIGN_TYPE *free_ptr;
/* Initialize the byte pool control block to all zeros. */
TX_MEMSET(pool_ptr, 0, (sizeof(TX_BYTE_POOL)));
/* Round the pool size down to something that is evenly divisible by
an ULONG. */
pool_size = (pool_size/(sizeof(ALIGN_TYPE))) * (sizeof(ALIGN_TYPE));
/* Setup the basic byte pool fields. */
pool_ptr -> tx_byte_pool_name = name_ptr;
/* Save the start and size of the pool. */
pool_ptr -> tx_byte_pool_start = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
pool_ptr -> tx_byte_pool_size = pool_size;
/* Setup memory list to the beginning as well as the search pointer. */
pool_ptr -> tx_byte_pool_list = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
pool_ptr -> tx_byte_pool_search = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
/* Initially, the pool will have two blocks. One large block at the
beginning that is available and a small allocated block at the end
of the pool that is there just for the algorithm. Be sure to count
the available block's header in the available bytes count. */
pool_ptr -> tx_byte_pool_available = pool_size - ((sizeof(VOID *)) + (sizeof(ALIGN_TYPE)));
pool_ptr -> tx_byte_pool_fragments = ((UINT) 2);
/* Each block contains a "next" pointer that points to the next block in the pool followed by a ALIGN_TYPE
field that contains either the constant TX_BYTE_BLOCK_FREE (if the block is free) or a pointer to the
owning pool (if the block is allocated). */
/* Calculate the end of the pool's memory area. */
block_ptr = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
block_ptr = TX_UCHAR_POINTER_ADD(block_ptr, pool_size);
/* Backup the end of the pool pointer and build the pre-allocated block. */
block_ptr = TX_UCHAR_POINTER_SUB(block_ptr, (sizeof(ALIGN_TYPE)));
/* Cast the pool pointer into a ULONG. */
temp_ptr = TX_BYTE_POOL_TO_UCHAR_POINTER_CONVERT(pool_ptr);
block_indirect_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(block_ptr);
*block_indirect_ptr = temp_ptr;
block_ptr = TX_UCHAR_POINTER_SUB(block_ptr, (sizeof(UCHAR *)));
block_indirect_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(block_ptr);
*block_indirect_ptr = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
/* Now setup the large available block in the pool. */
temp_ptr = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
block_indirect_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(temp_ptr);
*block_indirect_ptr = block_ptr;
block_ptr = TX_VOID_TO_UCHAR_POINTER_CONVERT(pool_start);
block_ptr = TX_UCHAR_POINTER_ADD(block_ptr, (sizeof(UCHAR *)));
free_ptr = TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(block_ptr);
*free_ptr = TX_BYTE_BLOCK_FREE;
/* Clear the owner id. */
pool_ptr -> tx_byte_pool_owner = TX_NULL;
/* Disable interrupts to place the byte pool on the created list. */
TX_DISABLE
/* Setup the byte pool ID to make it valid. */
pool_ptr -> tx_byte_pool_id = TX_BYTE_POOL_ID;
/* Place the byte pool on the list of created byte pools. First,
check for an empty list. */
if (_tx_byte_pool_created_count == TX_EMPTY)
{
/* The created byte pool list is empty. Add byte pool to empty list. */
_tx_byte_pool_created_ptr = pool_ptr;
pool_ptr -> tx_byte_pool_created_next = pool_ptr;
pool_ptr -> tx_byte_pool_created_previous = pool_ptr;
}
else
{
/* This list is not NULL, add to the end of the list. */
next_pool = _tx_byte_pool_created_ptr;
previous_pool = next_pool -> tx_byte_pool_created_previous;
/* Place the new byte pool in the list. */
next_pool -> tx_byte_pool_created_previous = pool_ptr;
previous_pool -> tx_byte_pool_created_next = pool_ptr;
/* Setup this byte pool's created links. */
pool_ptr -> tx_byte_pool_created_previous = previous_pool;
pool_ptr -> tx_byte_pool_created_next = next_pool;
}
/* Increment the number of created byte pools. */
_tx_byte_pool_created_count++;
/* Optional byte pool create extended processing. */
TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
/* If trace is enabled, register this object. */
TX_TRACE_OBJECT_REGISTER(TX_TRACE_OBJECT_TYPE_BYTE_POOL, pool_ptr, name_ptr, pool_size, 0)
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BYTE_POOL_CREATE, pool_ptr, TX_POINTER_TO_ULONG_CONVERT(pool_start), pool_size, TX_POINTER_TO_ULONG_CONVERT(&block_ptr), TX_TRACE_BYTE_POOL_EVENTS)
/* Log this kernel call. */
TX_EL_BYTE_POOL_CREATE_INSERT
/* Restore interrupts. */
TX_RESTORE
/* Return TX_SUCCESS. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,211 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Byte Pool */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_trace.h"
#include "tx_thread.h"
#include "tx_byte_pool.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_byte_pool_delete PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function deletes the specified byte pool. All threads */
/* suspended on the byte pool are resumed with the TX_DELETED status */
/* code. */
/* */
/* It is important to note that the byte pool being deleted, or the */
/* memory associated with it should not be in use when this function */
/* is called. */
/* */
/* INPUT */
/* */
/* pool_ptr Pointer to pool control block */
/* */
/* OUTPUT */
/* */
/* TX_SUCCESS Successful completion status */
/* */
/* CALLS */
/* */
/* _tx_thread_system_preempt_check Check for preemption */
/* _tx_thread_system_resume Resume thread service */
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_byte_pool_delete(TX_BYTE_POOL *pool_ptr)
{
TX_INTERRUPT_SAVE_AREA
TX_THREAD *thread_ptr;
TX_THREAD *next_thread;
UINT suspended_count;
TX_BYTE_POOL *next_pool;
TX_BYTE_POOL *previous_pool;
/* Disable interrupts to remove the byte pool from the created list. */
TX_DISABLE
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BYTE_POOL_DELETE, pool_ptr, TX_POINTER_TO_ULONG_CONVERT(&thread_ptr), 0, 0, TX_TRACE_BYTE_POOL_EVENTS)
/* Optional byte pool delete extended processing. */
TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
/* If trace is enabled, unregister this object. */
TX_TRACE_OBJECT_UNREGISTER(pool_ptr)
/* Log this kernel call. */
TX_EL_BYTE_POOL_DELETE_INSERT
/* Clear the byte pool ID to make it invalid. */
pool_ptr -> tx_byte_pool_id = TX_CLEAR_ID;
/* Decrement the number of byte pools created. */
_tx_byte_pool_created_count--;
/* See if the byte pool is the only one on the list. */
if (_tx_byte_pool_created_count == TX_EMPTY)
{
/* Only created byte pool, just set the created list to NULL. */
_tx_byte_pool_created_ptr = TX_NULL;
}
else
{
/* Link-up the neighbors. */
next_pool = pool_ptr -> tx_byte_pool_created_next;
previous_pool = pool_ptr -> tx_byte_pool_created_previous;
next_pool -> tx_byte_pool_created_previous = previous_pool;
previous_pool -> tx_byte_pool_created_next = next_pool;
/* See if we have to update the created list head pointer. */
if (_tx_byte_pool_created_ptr == pool_ptr)
{
/* Yes, move the head pointer to the next link. */
_tx_byte_pool_created_ptr = next_pool;
}
}
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Pickup the suspension information. */
thread_ptr = pool_ptr -> tx_byte_pool_suspension_list;
pool_ptr -> tx_byte_pool_suspension_list = TX_NULL;
suspended_count = pool_ptr -> tx_byte_pool_suspended_count;
pool_ptr -> tx_byte_pool_suspended_count = TX_NO_SUSPENSIONS;
/* Restore interrupts. */
TX_RESTORE
/* Walk through the byte pool list to resume any and all threads suspended
on this byte pool. */
while (suspended_count != TX_NO_SUSPENSIONS)
{
/* Decrement the suspension count. */
suspended_count--;
/* Lockout interrupts. */
TX_DISABLE
/* Clear the cleanup pointer, this prevents the timeout from doing
anything. */
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
/* Set the return status in the thread to TX_DELETED. */
thread_ptr -> tx_thread_suspend_status = TX_DELETED;
/* Move the thread pointer ahead. */
next_thread = thread_ptr -> tx_thread_suspended_next;
#ifdef TX_NOT_INTERRUPTABLE
/* Resume the thread! */
_tx_thread_system_ni_resume(thread_ptr);
/* Restore interrupts. */
TX_RESTORE
#else
/* Temporarily disable preemption again. */
_tx_thread_preempt_disable++;
/* Restore interrupts. */
TX_RESTORE
/* Resume the thread. */
_tx_thread_system_resume(thread_ptr);
#endif
/* Move to next thread. */
thread_ptr = next_thread;
}
/* Execute Port-Specific completion processing. If needed, it is typically defined in tx_port.h. */
TX_BYTE_POOL_DELETE_PORT_COMPLETION(pool_ptr)
/* Disable interrupts. */
TX_DISABLE
/* Release previous preempt disable. */
_tx_thread_preempt_disable--;
/* Restore interrupts. */
TX_RESTORE
/* Check for preemption. */
_tx_thread_system_preempt_check();
/* Return TX_SUCCESS. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,146 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Byte Memory */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_trace.h"
#include "tx_byte_pool.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_byte_pool_info_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function retrieves information from the specified byte pool. */
/* */
/* INPUT */
/* */
/* pool_ptr Pointer to byte pool control block*/
/* name Destination for the pool name */
/* available_bytes Number of free bytes in byte pool */
/* fragments Number of fragments in byte pool */
/* first_suspended Destination for pointer of first */
/* thread suspended on byte pool */
/* suspended_count Destination for suspended count */
/* next_pool Destination for pointer to next */
/* byte pool on the created list */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_byte_pool_info_get(TX_BYTE_POOL *pool_ptr, CHAR **name, ULONG *available_bytes,
ULONG *fragments, TX_THREAD **first_suspended,
ULONG *suspended_count, TX_BYTE_POOL **next_pool)
{
TX_INTERRUPT_SAVE_AREA
/* Disable interrupts. */
TX_DISABLE
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BYTE_POOL_INFO_GET, pool_ptr, 0, 0, 0, TX_TRACE_BYTE_POOL_EVENTS)
/* Log this kernel call. */
TX_EL_BYTE_POOL_INFO_GET_INSERT
/* Retrieve all the pertinent information and return it in the supplied
destinations. */
/* Retrieve the name of the byte pool. */
if (name != TX_NULL)
{
*name = pool_ptr -> tx_byte_pool_name;
}
/* Retrieve the number of available bytes in the byte pool. */
if (available_bytes != TX_NULL)
{
*available_bytes = pool_ptr -> tx_byte_pool_available;
}
/* Retrieve the total number of bytes in the byte pool. */
if (fragments != TX_NULL)
{
*fragments = (ULONG) pool_ptr -> tx_byte_pool_fragments;
}
/* Retrieve the first thread suspended on this byte pool. */
if (first_suspended != TX_NULL)
{
*first_suspended = pool_ptr -> tx_byte_pool_suspension_list;
}
/* Retrieve the number of threads suspended on this byte pool. */
if (suspended_count != TX_NULL)
{
*suspended_count = (ULONG) pool_ptr -> tx_byte_pool_suspended_count;
}
/* Retrieve the pointer to the next byte pool created. */
if (next_pool != TX_NULL)
{
*next_pool = pool_ptr -> tx_byte_pool_created_next;
}
/* Restore interrupts. */
TX_RESTORE
/* Return completion status. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,147 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Byte Pool */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_byte_pool.h"
#ifndef TX_INLINE_INITIALIZATION
/* Locate byte pool component data in this file. */
/* Define the head pointer of the created byte pool list. */
TX_BYTE_POOL * _tx_byte_pool_created_ptr;
/* Define the variable that holds the number of created byte pools. */
ULONG _tx_byte_pool_created_count;
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
/* Define the total number of allocates. */
ULONG _tx_byte_pool_performance_allocate_count;
/* Define the total number of releases. */
ULONG _tx_byte_pool_performance_release_count;
/* Define the total number of adjacent memory fragment merges. */
ULONG _tx_byte_pool_performance_merge_count;
/* Define the total number of memory fragment splits. */
ULONG _tx_byte_pool_performance_split_count;
/* Define the total number of memory fragments searched during allocation. */
ULONG _tx_byte_pool_performance_search_count;
/* Define the total number of byte pool suspensions. */
ULONG _tx_byte_pool_performance_suspension_count;
/* Define the total number of byte pool timeouts. */
ULONG _tx_byte_pool_performance_timeout_count;
#endif
#endif
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_byte_pool_initialize PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function initializes the various control data structures for */
/* the byte pool component. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_initialize_high_level High level initialization */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _tx_byte_pool_initialize(VOID)
{
#ifndef TX_DISABLE_REDUNDANT_CLEARING
/* Initialize the head pointer of the created byte pools list and the
number of byte pools created. */
_tx_byte_pool_created_ptr = TX_NULL;
_tx_byte_pool_created_count = TX_EMPTY;
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
/* Initialize byte pool performance counters. */
_tx_byte_pool_performance_allocate_count = ((ULONG) 0);
_tx_byte_pool_performance_release_count = ((ULONG) 0);
_tx_byte_pool_performance_merge_count = ((ULONG) 0);
_tx_byte_pool_performance_split_count = ((ULONG) 0);
_tx_byte_pool_performance_search_count = ((ULONG) 0);
_tx_byte_pool_performance_suspension_count = ((ULONG) 0);
_tx_byte_pool_performance_timeout_count = ((ULONG) 0);
#endif
#endif
}

View File

@@ -0,0 +1,253 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Byte Memory */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_byte_pool.h"
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
#include "tx_trace.h"
#endif
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_byte_pool_performance_info_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function retrieves performance information from the specified */
/* byte pool. */
/* */
/* INPUT */
/* */
/* pool_ptr Pointer to byte pool control block*/
/* allocates Destination for number of */
/* allocates on this pool */
/* releases Destination for number of */
/* releases on this pool */
/* fragments_searched Destination for number of */
/* fragments searched during */
/* allocation */
/* merges Destination for number of adjacent*/
/* free fragments merged */
/* splits Destination for number of */
/* fragments split during */
/* allocation */
/* suspensions Destination for number of */
/* suspensions on this pool */
/* timeouts Destination for number of timeouts*/
/* on this byte pool */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_byte_pool_performance_info_get(TX_BYTE_POOL *pool_ptr, ULONG *allocates, ULONG *releases,
ULONG *fragments_searched, ULONG *merges, ULONG *splits, ULONG *suspensions, ULONG *timeouts)
{
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
TX_INTERRUPT_SAVE_AREA
UINT status;
/* Determine if this is a legal request. */
if (pool_ptr == TX_NULL)
{
/* Byte pool pointer is illegal, return error. */
status = TX_PTR_ERROR;
}
/* Determine if the pool ID is invalid. */
else if (pool_ptr -> tx_byte_pool_id != TX_BYTE_POOL_ID)
{
/* Byte pool pointer is illegal, return error. */
status = TX_PTR_ERROR;
}
else
{
/* Disable interrupts. */
TX_DISABLE
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BYTE_POOL_PERFORMANCE_INFO_GET, pool_ptr, 0, 0, 0, TX_TRACE_BYTE_POOL_EVENTS)
/* Log this kernel call. */
TX_EL_BYTE_POOL_PERFORMANCE_INFO_GET_INSERT
/* Retrieve all the pertinent information and return it in the supplied
destinations. */
/* Retrieve the number of allocates on this byte pool. */
if (allocates != TX_NULL)
{
*allocates = pool_ptr -> tx_byte_pool_performance_allocate_count;
}
/* Retrieve the number of releases on this byte pool. */
if (releases != TX_NULL)
{
*releases = pool_ptr -> tx_byte_pool_performance_release_count;
}
/* Retrieve the number of fragments searched in this byte pool. */
if (fragments_searched != TX_NULL)
{
*fragments_searched = pool_ptr -> tx_byte_pool_performance_search_count;
}
/* Retrieve the number of fragments merged on this byte pool. */
if (merges != TX_NULL)
{
*merges = pool_ptr -> tx_byte_pool_performance_merge_count;
}
/* Retrieve the number of fragment splits on this byte pool. */
if (splits != TX_NULL)
{
*splits = pool_ptr -> tx_byte_pool_performance_split_count;
}
/* Retrieve the number of suspensions on this byte pool. */
if (suspensions != TX_NULL)
{
*suspensions = pool_ptr -> tx_byte_pool_performance_suspension_count;
}
/* Retrieve the number of timeouts on this byte pool. */
if (timeouts != TX_NULL)
{
*timeouts = pool_ptr -> tx_byte_pool_performance_timeout_count;
}
/* Restore interrupts. */
TX_RESTORE
/* Return completion status. */
status = TX_SUCCESS;
}
/* Return completion status. */
return(status);
#else
UINT status;
/* Access input arguments just for the sake of lint, MISRA, etc. */
if (pool_ptr != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (allocates != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (releases != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (fragments_searched != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (merges != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (splits != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (suspensions != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (timeouts != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
/* Return completion status. */
return(status);
#endif
}

View File

@@ -0,0 +1,221 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Byte Memory */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_byte_pool.h"
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
#include "tx_trace.h"
#endif
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_byte_pool_performance_system_info_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function retrieves byte pool performance information. */
/* */
/* INPUT */
/* */
/* allocates Destination for total number of */
/* allocates */
/* releases Destination for total number of */
/* releases */
/* fragments_searched Destination for total number of */
/* fragments searched during */
/* allocation */
/* merges Destination for total number of */
/* adjacent free fragments merged */
/* splits Destination for total number of */
/* fragments split during */
/* allocation */
/* suspensions Destination for total number of */
/* suspensions */
/* timeouts Destination for total number of */
/* timeouts */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_byte_pool_performance_system_info_get(ULONG *allocates, ULONG *releases,
ULONG *fragments_searched, ULONG *merges, ULONG *splits, ULONG *suspensions, ULONG *timeouts)
{
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
TX_INTERRUPT_SAVE_AREA
/* Disable interrupts. */
TX_DISABLE
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BYTE_POOL__PERFORMANCE_SYSTEM_INFO_GET, 0, 0, 0, 0, TX_TRACE_BYTE_POOL_EVENTS)
/* Log this kernel call. */
TX_EL_BYTE_POOL_PERFORMANCE_SYSTEM_INFO_GET_INSERT
/* Retrieve all the pertinent information and return it in the supplied
destinations. */
/* Retrieve the total number of byte pool allocates. */
if (allocates != TX_NULL)
{
*allocates = _tx_byte_pool_performance_allocate_count;
}
/* Retrieve the total number of byte pool releases. */
if (releases != TX_NULL)
{
*releases = _tx_byte_pool_performance_release_count;
}
/* Retrieve the total number of byte pool fragments searched. */
if (fragments_searched != TX_NULL)
{
*fragments_searched = _tx_byte_pool_performance_search_count;
}
/* Retrieve the total number of byte pool fragments merged. */
if (merges != TX_NULL)
{
*merges = _tx_byte_pool_performance_merge_count;
}
/* Retrieve the total number of byte pool fragment splits. */
if (splits != TX_NULL)
{
*splits = _tx_byte_pool_performance_split_count;
}
/* Retrieve the total number of byte pool suspensions. */
if (suspensions != TX_NULL)
{
*suspensions = _tx_byte_pool_performance_suspension_count;
}
/* Retrieve the total number of byte pool timeouts. */
if (timeouts != TX_NULL)
{
*timeouts = _tx_byte_pool_performance_timeout_count;
}
/* Restore interrupts. */
TX_RESTORE
/* Return completion status. */
return(TX_SUCCESS);
#else
UINT status;
/* Access input arguments just for the sake of lint, MISRA, etc. */
if (allocates != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (releases != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (fragments_searched != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (merges != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (splits != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (suspensions != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (timeouts != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
/* Return completion status. */
return(status);
#endif
}

View File

@@ -0,0 +1,249 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Byte Memory */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_trace.h"
#include "tx_thread.h"
#include "tx_byte_pool.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_byte_pool_prioritize PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function places the highest priority suspended thread at the */
/* front of the suspension list. All other threads remain in the same */
/* FIFO suspension order. */
/* */
/* INPUT */
/* */
/* pool_ptr Pointer to pool control block */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _tx_thread_system_preempt_check Check for preemption */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_byte_pool_prioritize(TX_BYTE_POOL *pool_ptr)
{
TX_INTERRUPT_SAVE_AREA
TX_THREAD *thread_ptr;
TX_THREAD *priority_thread_ptr;
TX_THREAD *head_ptr;
UINT suspended_count;
TX_THREAD *next_thread;
TX_THREAD *previous_thread;
UINT list_changed;
/* Disable interrupts. */
TX_DISABLE
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BYTE_POOL_PRIORITIZE, pool_ptr, pool_ptr -> tx_byte_pool_suspended_count, TX_POINTER_TO_ULONG_CONVERT(&suspended_count), 0, TX_TRACE_BYTE_POOL_EVENTS)
/* Log this kernel call. */
TX_EL_BYTE_POOL_PRIORITIZE_INSERT
/* Pickup the suspended count. */
suspended_count = pool_ptr -> tx_byte_pool_suspended_count;
/* Determine if there are fewer than 2 suspended threads. */
if (suspended_count < ((UINT) 2))
{
/* Restore interrupts. */
TX_RESTORE
}
/* Determine if there how many threads are suspended on this byte memory pool. */
else if (suspended_count == ((UINT) 2))
{
/* Pickup the head pointer and the next pointer. */
head_ptr = pool_ptr -> tx_byte_pool_suspension_list;
next_thread = head_ptr -> tx_thread_suspended_next;
/* Determine if the next suspended thread has a higher priority. */
if ((next_thread -> tx_thread_priority) < (head_ptr -> tx_thread_priority))
{
/* Yes, move the list head to the next thread. */
pool_ptr -> tx_byte_pool_suspension_list = next_thread;
}
/* Restore interrupts. */
TX_RESTORE
}
else
{
/* Remember the suspension count and head pointer. */
head_ptr = pool_ptr -> tx_byte_pool_suspension_list;
/* Default the highest priority thread to the thread at the front of the list. */
priority_thread_ptr = head_ptr;
/* Setup search pointer. */
thread_ptr = priority_thread_ptr -> tx_thread_suspended_next;
/* Disable preemption. */
_tx_thread_preempt_disable++;
/* Set the list changed flag to false. */
list_changed = TX_FALSE;
/* Search through the list to find the highest priority thread. */
do
{
/* Is the current thread higher priority? */
if (thread_ptr -> tx_thread_priority < priority_thread_ptr -> tx_thread_priority)
{
/* Yes, remember that this thread is the highest priority. */
priority_thread_ptr = thread_ptr;
}
/* Restore interrupts temporarily. */
TX_RESTORE
/* Disable interrupts again. */
TX_DISABLE
/* Determine if any changes to the list have occurred while
interrupts were enabled. */
/* Is the list head the same? */
if (head_ptr != pool_ptr -> tx_byte_pool_suspension_list)
{
/* The list head has changed, set the list changed flag. */
list_changed = TX_TRUE;
}
else
{
/* Is the suspended count the same? */
if (suspended_count != pool_ptr -> tx_byte_pool_suspended_count)
{
/* The list head has changed, set the list changed flag. */
list_changed = TX_TRUE;
}
}
/* Determine if the list has changed. */
if (list_changed == TX_FALSE)
{
/* Move the thread pointer to the next thread. */
thread_ptr = thread_ptr -> tx_thread_suspended_next;
}
else
{
/* Remember the suspension count and head pointer. */
head_ptr = pool_ptr -> tx_byte_pool_suspension_list;
suspended_count = pool_ptr -> tx_byte_pool_suspended_count;
/* Default the highest priority thread to the thread at the front of the list. */
priority_thread_ptr = head_ptr;
/* Setup search pointer. */
thread_ptr = priority_thread_ptr -> tx_thread_suspended_next;
/* Reset the list changed flag. */
list_changed = TX_FALSE;
}
} while (thread_ptr != head_ptr);
/* Release preemption. */
_tx_thread_preempt_disable--;
/* Now determine if the highest priority thread is at the front
of the list. */
if (priority_thread_ptr != head_ptr)
{
/* No, we need to move the highest priority suspended thread to the
front of the list. */
/* First, remove the highest priority thread by updating the
adjacent suspended threads. */
next_thread = priority_thread_ptr -> tx_thread_suspended_next;
previous_thread = priority_thread_ptr -> tx_thread_suspended_previous;
next_thread -> tx_thread_suspended_previous = previous_thread;
previous_thread -> tx_thread_suspended_next = next_thread;
/* Now, link the highest priority thread at the front of the list. */
previous_thread = head_ptr -> tx_thread_suspended_previous;
priority_thread_ptr -> tx_thread_suspended_next = head_ptr;
priority_thread_ptr -> tx_thread_suspended_previous = previous_thread;
previous_thread -> tx_thread_suspended_next = priority_thread_ptr;
head_ptr -> tx_thread_suspended_previous = priority_thread_ptr;
/* Move the list head pointer to the highest priority suspended thread. */
pool_ptr -> tx_byte_pool_suspension_list = priority_thread_ptr;
}
/* Restore interrupts. */
TX_RESTORE
/* Check for preemption. */
_tx_thread_system_preempt_check();
}
/* Return completion status. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,350 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Byte Pool */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_thread.h"
#include "tx_byte_pool.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_byte_pool_search PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function searches a byte pool for a memory block to satisfy */
/* the requested number of bytes. Merging of adjacent free blocks */
/* takes place during the search and a split of the block that */
/* satisfies the request may occur before this function returns. */
/* */
/* It is assumed that this function is called with interrupts enabled */
/* and with the tx_pool_owner field set to the thread performing the */
/* search. Also note that the search can occur during allocation and */
/* release of a memory block. */
/* */
/* INPUT */
/* */
/* pool_ptr Pointer to pool control block */
/* memory_size Number of bytes required */
/* */
/* OUTPUT */
/* */
/* UCHAR * Pointer to the allocated memory, */
/* if successful. Otherwise, a */
/* NULL is returned */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_byte_allocate Allocate bytes of memory */
/* _tx_byte_release Release bytes of memory */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UCHAR *_tx_byte_pool_search(TX_BYTE_POOL *pool_ptr, ULONG memory_size)
{
TX_INTERRUPT_SAVE_AREA
UCHAR *current_ptr;
UCHAR *next_ptr;
UCHAR **this_block_link_ptr;
UCHAR **next_block_link_ptr;
ULONG available_bytes;
UINT examine_blocks;
UINT first_free_block_found = TX_FALSE;
TX_THREAD *thread_ptr;
ALIGN_TYPE *free_ptr;
UCHAR *work_ptr;
/* Disable interrupts. */
TX_DISABLE
/* First, determine if there are enough bytes in the pool. */
if (memory_size >= pool_ptr -> tx_byte_pool_available)
{
/* Restore interrupts. */
TX_RESTORE
/* Not enough memory, return a NULL pointer. */
current_ptr = TX_NULL;
}
else
{
/* Pickup thread pointer. */
TX_THREAD_GET_CURRENT(thread_ptr)
/* Setup ownership of the byte pool. */
pool_ptr -> tx_byte_pool_owner = thread_ptr;
/* Walk through the memory pool in search for a large enough block. */
current_ptr = pool_ptr -> tx_byte_pool_search;
examine_blocks = pool_ptr -> tx_byte_pool_fragments + ((UINT) 1);
available_bytes = ((ULONG) 0);
do
{
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
/* Increment the total fragment search counter. */
_tx_byte_pool_performance_search_count++;
/* Increment the number of fragments searched on this pool. */
pool_ptr -> tx_byte_pool_performance_search_count++;
#endif
/* Check to see if this block is free. */
work_ptr = TX_UCHAR_POINTER_ADD(current_ptr, (sizeof(UCHAR *)));
free_ptr = TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(work_ptr);
if ((*free_ptr) == TX_BYTE_BLOCK_FREE)
{
/* Determine if this is the first free block. */
if (first_free_block_found == TX_FALSE)
{
/* This is the first free block. */
pool_ptr->tx_byte_pool_search = current_ptr;
/* Set the flag to indicate we have found the first free
block. */
first_free_block_found = TX_TRUE;
}
/* Block is free, see if it is large enough. */
/* Pickup the next block's pointer. */
this_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(current_ptr);
next_ptr = *this_block_link_ptr;
/* Calculate the number of bytes available in this block. */
available_bytes = TX_UCHAR_POINTER_DIF(next_ptr, current_ptr);
available_bytes = available_bytes - ((sizeof(UCHAR *)) + (sizeof(ALIGN_TYPE)));
/* If this is large enough, we are done because our first-fit algorithm
has been satisfied! */
if (available_bytes >= memory_size)
{
/* Get out of the search loop! */
break;
}
else
{
/* Clear the available bytes variable. */
available_bytes = ((ULONG) 0);
/* Not enough memory, check to see if the neighbor is
free and can be merged. */
work_ptr = TX_UCHAR_POINTER_ADD(next_ptr, (sizeof(UCHAR *)));
free_ptr = TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(work_ptr);
if ((*free_ptr) == TX_BYTE_BLOCK_FREE)
{
/* Yes, neighbor block can be merged! This is quickly accomplished
by updating the current block with the next blocks pointer. */
next_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(next_ptr);
*this_block_link_ptr = *next_block_link_ptr;
/* Reduce the fragment total. We don't need to increase the bytes
available because all free headers are also included in the available
count. */
pool_ptr -> tx_byte_pool_fragments--;
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
/* Increment the total merge counter. */
_tx_byte_pool_performance_merge_count++;
/* Increment the number of blocks merged on this pool. */
pool_ptr -> tx_byte_pool_performance_merge_count++;
#endif
/* See if the search pointer is affected. */
if (pool_ptr -> tx_byte_pool_search == next_ptr)
{
/* Yes, update the search pointer. */
pool_ptr -> tx_byte_pool_search = current_ptr;
}
}
else
{
/* Neighbor is not free so we can skip over it! */
next_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(next_ptr);
current_ptr = *next_block_link_ptr;
/* Decrement the examined block count to account for this one. */
if (examine_blocks != ((UINT) 0))
{
examine_blocks--;
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
/* Increment the total fragment search counter. */
_tx_byte_pool_performance_search_count++;
/* Increment the number of fragments searched on this pool. */
pool_ptr -> tx_byte_pool_performance_search_count++;
#endif
}
}
}
}
else
{
/* Block is not free, move to next block. */
this_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(current_ptr);
current_ptr = *this_block_link_ptr;
}
/* Another block has been searched... decrement counter. */
if (examine_blocks != ((UINT) 0))
{
examine_blocks--;
}
/* Restore interrupts temporarily. */
TX_RESTORE
/* Disable interrupts. */
TX_DISABLE
/* Determine if anything has changed in terms of pool ownership. */
if (pool_ptr -> tx_byte_pool_owner != thread_ptr)
{
/* Pool changed ownership in the brief period interrupts were
enabled. Reset the search. */
current_ptr = pool_ptr -> tx_byte_pool_search;
examine_blocks = pool_ptr -> tx_byte_pool_fragments + ((UINT) 1);
/* Setup our ownership again. */
pool_ptr -> tx_byte_pool_owner = thread_ptr;
}
} while(examine_blocks != ((UINT) 0));
/* Determine if a block was found. If so, determine if it needs to be
split. */
if (available_bytes != ((ULONG) 0))
{
/* Determine if we need to split this block. */
if ((available_bytes - memory_size) >= ((ULONG) TX_BYTE_BLOCK_MIN))
{
/* Split the block. */
next_ptr = TX_UCHAR_POINTER_ADD(current_ptr, (memory_size + ((sizeof(UCHAR *)) + (sizeof(ALIGN_TYPE)))));
/* Setup the new free block. */
next_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(next_ptr);
this_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(current_ptr);
*next_block_link_ptr = *this_block_link_ptr;
work_ptr = TX_UCHAR_POINTER_ADD(next_ptr, (sizeof(UCHAR *)));
free_ptr = TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(work_ptr);
*free_ptr = TX_BYTE_BLOCK_FREE;
/* Increase the total fragment counter. */
pool_ptr -> tx_byte_pool_fragments++;
/* Update the current pointer to point at the newly created block. */
*this_block_link_ptr = next_ptr;
/* Set available equal to memory size for subsequent calculation. */
available_bytes = memory_size;
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
/* Increment the total split counter. */
_tx_byte_pool_performance_split_count++;
/* Increment the number of blocks split on this pool. */
pool_ptr -> tx_byte_pool_performance_split_count++;
#endif
}
/* In any case, mark the current block as allocated. */
work_ptr = TX_UCHAR_POINTER_ADD(current_ptr, (sizeof(UCHAR *)));
this_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(work_ptr);
*this_block_link_ptr = TX_BYTE_POOL_TO_UCHAR_POINTER_CONVERT(pool_ptr);
/* Reduce the number of available bytes in the pool. */
pool_ptr -> tx_byte_pool_available = (pool_ptr -> tx_byte_pool_available - available_bytes) - ((sizeof(UCHAR *)) + (sizeof(ALIGN_TYPE)));
/* Determine if the search pointer needs to be updated. This is only done
if the search pointer matches the block to be returned. */
if (current_ptr == pool_ptr -> tx_byte_pool_search)
{
/* Yes, update the search pointer to the next block. */
this_block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(current_ptr);
pool_ptr -> tx_byte_pool_search = *this_block_link_ptr;
}
/* Restore interrupts. */
TX_RESTORE
/* Adjust the pointer for the application. */
current_ptr = TX_UCHAR_POINTER_ADD(current_ptr, (((sizeof(UCHAR *)) + (sizeof(ALIGN_TYPE)))));
}
else
{
/* Restore interrupts. */
TX_RESTORE
/* Set current pointer to NULL to indicate nothing was found. */
current_ptr = TX_NULL;
}
}
/* Return the search pointer. */
return(current_ptr);
}

View File

@@ -0,0 +1,376 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Byte Memory */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_trace.h"
#include "tx_thread.h"
#include "tx_byte_pool.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_byte_release PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function returns previously allocated memory to its */
/* associated memory byte pool. */
/* */
/* INPUT */
/* */
/* memory_ptr Pointer to allocated memory */
/* */
/* OUTPUT */
/* */
/* [TX_PTR_ERROR | TX_SUCCESS] Completion status */
/* */
/* CALLS */
/* */
/* _tx_thread_system_preempt_check Check for preemption */
/* _tx_thread_system_resume Resume thread service */
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
/* _tx_byte_pool_search Search the byte pool for memory */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_byte_release(VOID *memory_ptr)
{
TX_INTERRUPT_SAVE_AREA
UINT status;
TX_BYTE_POOL *pool_ptr;
TX_THREAD *thread_ptr;
UCHAR *work_ptr;
UCHAR *temp_ptr;
UCHAR *next_block_ptr;
TX_THREAD *susp_thread_ptr;
UINT suspended_count;
TX_THREAD *next_thread;
TX_THREAD *previous_thread;
ULONG memory_size;
ALIGN_TYPE *free_ptr;
TX_BYTE_POOL **byte_pool_ptr;
UCHAR **block_link_ptr;
UCHAR **suspend_info_ptr;
/* Default to successful status. */
status = TX_SUCCESS;
/* Set the pool pointer to NULL. */
pool_ptr = TX_NULL;
/* Lockout interrupts. */
TX_DISABLE
/* Determine if the memory pointer is valid. */
work_ptr = TX_VOID_TO_UCHAR_POINTER_CONVERT(memory_ptr);
if (work_ptr != TX_NULL)
{
/* Back off the memory pointer to pickup its header. */
work_ptr = TX_UCHAR_POINTER_SUB(work_ptr, ((sizeof(UCHAR *)) + (sizeof(ALIGN_TYPE))));
/* There is a pointer, pickup the pool pointer address. */
temp_ptr = TX_UCHAR_POINTER_ADD(work_ptr, (sizeof(UCHAR *)));
free_ptr = TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(temp_ptr);
if ((*free_ptr) != TX_BYTE_BLOCK_FREE)
{
/* Pickup the pool pointer. */
temp_ptr = TX_UCHAR_POINTER_ADD(work_ptr, (sizeof(UCHAR *)));
byte_pool_ptr = TX_UCHAR_TO_INDIRECT_BYTE_POOL_POINTER(temp_ptr);
pool_ptr = *byte_pool_ptr;
/* See if we have a valid pool pointer. */
if (pool_ptr == TX_NULL)
{
/* Return pointer error. */
status = TX_PTR_ERROR;
}
else
{
/* See if we have a valid pool. */
if (pool_ptr -> tx_byte_pool_id != TX_BYTE_POOL_ID)
{
/* Return pointer error. */
status = TX_PTR_ERROR;
/* Reset the pool pointer is NULL. */
pool_ptr = TX_NULL;
}
}
}
else
{
/* Return pointer error. */
status = TX_PTR_ERROR;
}
}
else
{
/* Return pointer error. */
status = TX_PTR_ERROR;
}
/* Determine if the pointer is valid. */
if (pool_ptr == TX_NULL)
{
/* Restore interrupts. */
TX_RESTORE
}
else
{
/* At this point, we know that the pointer is valid. */
/* Pickup thread pointer. */
TX_THREAD_GET_CURRENT(thread_ptr)
/* Indicate that this thread is the current owner. */
pool_ptr -> tx_byte_pool_owner = thread_ptr;
#ifdef TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
/* Increment the total release counter. */
_tx_byte_pool_performance_release_count++;
/* Increment the number of releases on this pool. */
pool_ptr -> tx_byte_pool_performance_release_count++;
#endif
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_BYTE_RELEASE, pool_ptr, TX_POINTER_TO_ULONG_CONVERT(memory_ptr), pool_ptr -> tx_byte_pool_suspended_count, pool_ptr -> tx_byte_pool_available, TX_TRACE_BYTE_POOL_EVENTS)
/* Log this kernel call. */
TX_EL_BYTE_RELEASE_INSERT
/* Release the memory. */
temp_ptr = TX_UCHAR_POINTER_ADD(work_ptr, (sizeof(UCHAR *)));
free_ptr = TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(temp_ptr);
*free_ptr = TX_BYTE_BLOCK_FREE;
/* Update the number of available bytes in the pool. */
block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(work_ptr);
next_block_ptr = *block_link_ptr;
pool_ptr -> tx_byte_pool_available =
pool_ptr -> tx_byte_pool_available + TX_UCHAR_POINTER_DIF(next_block_ptr, work_ptr);
/* Determine if the free block is prior to current search pointer. */
if (work_ptr < (pool_ptr -> tx_byte_pool_search))
{
/* Yes, update the search pointer to the released block. */
pool_ptr -> tx_byte_pool_search = work_ptr;
}
/* Determine if there are threads suspended on this byte pool. */
if (pool_ptr -> tx_byte_pool_suspended_count != TX_NO_SUSPENSIONS)
{
/* Now examine the suspension list to find threads waiting for
memory. Maybe it is now available! */
while (pool_ptr -> tx_byte_pool_suspended_count != TX_NO_SUSPENSIONS)
{
/* Pickup the first suspended thread pointer. */
susp_thread_ptr = pool_ptr -> tx_byte_pool_suspension_list;
/* Pickup the size of the memory the thread is requesting. */
memory_size = susp_thread_ptr -> tx_thread_suspend_info;
/* Restore interrupts. */
TX_RESTORE
/* See if the request can be satisfied. */
work_ptr = _tx_byte_pool_search(pool_ptr, memory_size);
/* Optional processing extension. */
TX_BYTE_RELEASE_EXTENSION
/* Disable interrupts. */
TX_DISABLE
/* Indicate that this thread is the current owner. */
pool_ptr -> tx_byte_pool_owner = thread_ptr;
/* If there is not enough memory, break this loop! */
if (work_ptr == TX_NULL)
{
/* Break out of the loop. */
break;
}
/* Check to make sure the thread is still suspended. */
if (susp_thread_ptr == pool_ptr -> tx_byte_pool_suspension_list)
{
/* Also, makes sure the memory size is the same. */
if (susp_thread_ptr -> tx_thread_suspend_info == memory_size)
{
/* Remove the suspended thread from the list. */
/* Decrement the number of threads suspended. */
pool_ptr -> tx_byte_pool_suspended_count--;
/* Pickup the suspended count. */
suspended_count = pool_ptr -> tx_byte_pool_suspended_count;
/* See if this is the only suspended thread on the list. */
if (suspended_count == TX_NO_SUSPENSIONS)
{
/* Yes, the only suspended thread. */
/* Update the head pointer. */
pool_ptr -> tx_byte_pool_suspension_list = TX_NULL;
}
else
{
/* At least one more thread is on the same expiration list. */
/* Update the list head pointer. */
next_thread = susp_thread_ptr -> tx_thread_suspended_next;
pool_ptr -> tx_byte_pool_suspension_list = next_thread;
/* Update the links of the adjacent threads. */
previous_thread = susp_thread_ptr -> tx_thread_suspended_previous;
next_thread -> tx_thread_suspended_previous = previous_thread;
previous_thread -> tx_thread_suspended_next = next_thread;
}
/* Prepare for resumption of the thread. */
/* Clear cleanup routine to avoid timeout. */
susp_thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
/* Return this block pointer to the suspended thread waiting for
a block. */
suspend_info_ptr = TX_VOID_TO_INDIRECT_UCHAR_POINTER_CONVERT(susp_thread_ptr -> tx_thread_additional_suspend_info);
*suspend_info_ptr = work_ptr;
/* Clear the memory pointer to indicate that it was given to the suspended thread. */
work_ptr = TX_NULL;
/* Put return status into the thread control block. */
susp_thread_ptr -> tx_thread_suspend_status = TX_SUCCESS;
#ifdef TX_NOT_INTERRUPTABLE
/* Resume the thread! */
_tx_thread_system_ni_resume(susp_thread_ptr);
/* Restore interrupts. */
TX_RESTORE
#else
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Restore interrupts. */
TX_RESTORE
/* Resume thread. */
_tx_thread_system_resume(susp_thread_ptr);
#endif
/* Lockout interrupts. */
TX_DISABLE
}
}
/* Determine if the memory was given to the suspended thread. */
if (work_ptr != TX_NULL)
{
/* No, it wasn't given to the suspended thread. */
/* Put the memory back on the available list since this thread is no longer
suspended. */
work_ptr = TX_UCHAR_POINTER_SUB(work_ptr, (((sizeof(UCHAR *)) + (sizeof(ALIGN_TYPE)))));
temp_ptr = TX_UCHAR_POINTER_ADD(work_ptr, (sizeof(UCHAR *)));
free_ptr = TX_UCHAR_TO_ALIGN_TYPE_POINTER_CONVERT(temp_ptr);
*free_ptr = TX_BYTE_BLOCK_FREE;
/* Update the number of available bytes in the pool. */
block_link_ptr = TX_UCHAR_TO_INDIRECT_UCHAR_POINTER_CONVERT(work_ptr);
next_block_ptr = *block_link_ptr;
pool_ptr -> tx_byte_pool_available =
pool_ptr -> tx_byte_pool_available + TX_UCHAR_POINTER_DIF(next_block_ptr, work_ptr);
/* Determine if the current pointer is before the search pointer. */
if (work_ptr < (pool_ptr -> tx_byte_pool_search))
{
/* Yes, update the search pointer. */
pool_ptr -> tx_byte_pool_search = work_ptr;
}
}
}
/* Restore interrupts. */
TX_RESTORE
/* Check for preemption. */
_tx_thread_system_preempt_check();
}
else
{
/* No, threads suspended, restore interrupts. */
TX_RESTORE
}
}
/* Return completion status. */
return(status);
}

View File

@@ -0,0 +1,237 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Event Flags */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_thread.h"
#include "tx_event_flags.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_event_flags_cleanup PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function processes event flags timeout and thread terminate */
/* actions that require the event flags data structures to be cleaned */
/* up. */
/* */
/* INPUT */
/* */
/* thread_ptr Pointer to suspended thread's */
/* control block */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _tx_thread_system_resume Resume thread service */
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
/* */
/* CALLED BY */
/* */
/* _tx_thread_timeout Thread timeout processing */
/* _tx_thread_terminate Thread terminate processing */
/* _tx_thread_wait_abort Thread wait abort processing */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _tx_event_flags_cleanup(TX_THREAD *thread_ptr, ULONG suspension_sequence)
{
#ifndef TX_NOT_INTERRUPTABLE
TX_INTERRUPT_SAVE_AREA
#endif
TX_EVENT_FLAGS_GROUP *group_ptr;
UINT suspended_count;
TX_THREAD *suspension_head;
TX_THREAD *next_thread;
TX_THREAD *previous_thread;
#ifndef TX_NOT_INTERRUPTABLE
/* Disable interrupts to remove the suspended thread from the event flags group. */
TX_DISABLE
/* Determine if the cleanup is still required. */
if (thread_ptr -> tx_thread_suspend_cleanup == &(_tx_event_flags_cleanup))
{
/* Check for valid suspension sequence. */
if (suspension_sequence == thread_ptr -> tx_thread_suspension_sequence)
{
/* Setup pointer to event flags control block. */
group_ptr = TX_VOID_TO_EVENT_FLAGS_POINTER_CONVERT(thread_ptr -> tx_thread_suspend_control_block);
/* Check for a NULL event flags control block pointer. */
if (group_ptr != TX_NULL)
{
/* Is the group pointer ID valid? */
if (group_ptr -> tx_event_flags_group_id == TX_EVENT_FLAGS_ID)
{
/* Determine if there are any thread suspensions. */
if (group_ptr -> tx_event_flags_group_suspended_count != TX_NO_SUSPENSIONS)
{
#else
/* Setup pointer to event flags control block. */
group_ptr = TX_VOID_TO_EVENT_FLAGS_POINTER_CONVERT(thread_ptr -> tx_thread_suspend_control_block);
#endif
/* Yes, we still have thread suspension! */
/* Clear the suspension cleanup flag. */
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
/* Pickup the suspended count. */
suspended_count = group_ptr -> tx_event_flags_group_suspended_count;
/* Pickup the suspension head. */
suspension_head = group_ptr -> tx_event_flags_group_suspension_list;
/* Determine if the cleanup is being done while a set operation was interrupted. If the
suspended count is non-zero and the suspension head is NULL, the list is being processed
and cannot be touched from here. The suspension list removal will instead take place
inside the event flag set code. */
if (suspension_head != TX_NULL)
{
/* Remove the suspended thread from the list. */
/* Decrement the local suspension count. */
suspended_count--;
/* Store the updated suspended count. */
group_ptr -> tx_event_flags_group_suspended_count = suspended_count;
/* See if this is the only suspended thread on the list. */
if (suspended_count == TX_NO_SUSPENSIONS)
{
/* Yes, the only suspended thread. */
/* Update the head pointer. */
group_ptr -> tx_event_flags_group_suspension_list = TX_NULL;
}
else
{
/* At least one more thread is on the same suspension list. */
/* Update the links of the adjacent threads. */
next_thread = thread_ptr -> tx_thread_suspended_next;
previous_thread = thread_ptr -> tx_thread_suspended_previous;
next_thread -> tx_thread_suspended_previous = previous_thread;
previous_thread -> tx_thread_suspended_next = next_thread;
/* Determine if we need to update the head pointer. */
if (suspension_head == thread_ptr)
{
/* Update the list head pointer. */
group_ptr -> tx_event_flags_group_suspension_list = next_thread;
}
}
}
else
{
/* In this case, the search pointer in an interrupted event flag set must be reset. */
group_ptr -> tx_event_flags_group_reset_search = TX_TRUE;
}
/* Now we need to determine if this cleanup is from a terminate, timeout,
or from a wait abort. */
if (thread_ptr -> tx_thread_state == TX_EVENT_FLAG)
{
/* Timeout condition and the thread still suspended on the event flags group.
Setup return error status and resume the thread. */
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
/* Increment the total timeouts counter. */
_tx_event_flags_performance_timeout_count++;
/* Increment the number of timeouts on this event flags group. */
group_ptr -> tx_event_flags_group____performance_timeout_count++;
#endif
/* Setup return status. */
thread_ptr -> tx_thread_suspend_status = TX_NO_EVENTS;
#ifdef TX_NOT_INTERRUPTABLE
/* Resume the thread! */
_tx_thread_system_ni_resume(thread_ptr);
#else
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Restore interrupts. */
TX_RESTORE
/* Resume the thread! Check for preemption even though we are executing
from the system timer thread right now which normally executes at the
highest priority. */
_tx_thread_system_resume(thread_ptr);
/* Disable interrupts. */
TX_DISABLE
#endif
}
#ifndef TX_NOT_INTERRUPTABLE
}
}
}
}
}
/* Restore interrupts. */
TX_RESTORE
#endif
}

View File

@@ -0,0 +1,141 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Event Flags */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_trace.h"
#include "tx_event_flags.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_event_flags_create PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function creates a group of 32 event flags. All the flags are */
/* initially in a cleared state. */
/* */
/* INPUT */
/* */
/* group_ptr Pointer to event flags group */
/* control block */
/* name_ptr Pointer to event flags name */
/* */
/* OUTPUT */
/* */
/* TX_SUCCESS Successful completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_event_flags_create(TX_EVENT_FLAGS_GROUP *group_ptr, CHAR *name_ptr)
{
TX_INTERRUPT_SAVE_AREA
TX_EVENT_FLAGS_GROUP *next_group;
TX_EVENT_FLAGS_GROUP *previous_group;
/* Initialize event flags control block to all zeros. */
TX_MEMSET(group_ptr, 0, (sizeof(TX_EVENT_FLAGS_GROUP)));
/* Setup the basic event flags group fields. */
group_ptr -> tx_event_flags_group_name = name_ptr;
/* Disable interrupts to put the event flags group on the created list. */
TX_DISABLE
/* Setup the event flags ID to make it valid. */
group_ptr -> tx_event_flags_group_id = TX_EVENT_FLAGS_ID;
/* Place the group on the list of created event flag groups. First,
check for an empty list. */
if (_tx_event_flags_created_count == TX_EMPTY)
{
/* The created event flags list is empty. Add event flag group to empty list. */
_tx_event_flags_created_ptr = group_ptr;
group_ptr -> tx_event_flags_group_created_next = group_ptr;
group_ptr -> tx_event_flags_group_created_previous = group_ptr;
}
else
{
/* This list is not NULL, add to the end of the list. */
next_group = _tx_event_flags_created_ptr;
previous_group = next_group -> tx_event_flags_group_created_previous;
/* Place the new event flag group in the list. */
next_group -> tx_event_flags_group_created_previous = group_ptr;
previous_group -> tx_event_flags_group_created_next = group_ptr;
/* Setup this group's created links. */
group_ptr -> tx_event_flags_group_created_previous = previous_group;
group_ptr -> tx_event_flags_group_created_next = next_group;
}
/* Increment the number of created event flag groups. */
_tx_event_flags_created_count++;
/* Optional event flag group create extended processing. */
TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
/* If trace is enabled, register this object. */
TX_TRACE_OBJECT_REGISTER(TX_TRACE_OBJECT_TYPE_EVENT_FLAGS, group_ptr, name_ptr, 0, 0)
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_EVENT_FLAGS_CREATE, group_ptr, TX_POINTER_TO_ULONG_CONVERT(&next_group), 0, 0, TX_TRACE_EVENT_FLAGS_EVENTS)
/* Log this kernel call. */
TX_EL_EVENT_FLAGS_CREATE_INSERT
/* Restore interrupts. */
TX_RESTORE
/* Return TX_SUCCESS. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,207 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Event Flags */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_trace.h"
#include "tx_thread.h"
#include "tx_event_flags.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_event_flags_delete PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function deletes the specified event flag group. All threads */
/* suspended on the group are resumed with the TX_DELETED status */
/* code. */
/* */
/* INPUT */
/* */
/* group_ptr Pointer to group control block */
/* */
/* OUTPUT */
/* */
/* TX_SUCCESS Successful completion status */
/* */
/* CALLS */
/* */
/* _tx_thread_system_preempt_check Check for preemption */
/* _tx_thread_system_resume Resume thread service */
/* _tx_thread_system_ni_resume Non-interruptable resume thread */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_event_flags_delete(TX_EVENT_FLAGS_GROUP *group_ptr)
{
TX_INTERRUPT_SAVE_AREA
TX_THREAD *thread_ptr;
TX_THREAD *next_thread;
UINT suspended_count;
TX_EVENT_FLAGS_GROUP *next_group;
TX_EVENT_FLAGS_GROUP *previous_group;
/* Disable interrupts to remove the group from the created list. */
TX_DISABLE
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_EVENT_FLAGS_DELETE, group_ptr, TX_POINTER_TO_ULONG_CONVERT(&thread_ptr), 0, 0, TX_TRACE_EVENT_FLAGS_EVENTS)
/* Optional event flags group delete extended processing. */
TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
/* If trace is enabled, unregister this object. */
TX_TRACE_OBJECT_UNREGISTER(group_ptr)
/* Log this kernel call. */
TX_EL_EVENT_FLAGS_DELETE_INSERT
/* Clear the event flag group ID to make it invalid. */
group_ptr -> tx_event_flags_group_id = TX_CLEAR_ID;
/* Decrement the number of created event flag groups. */
_tx_event_flags_created_count--;
/* See if this group is the only one on the list. */
if (_tx_event_flags_created_count == TX_EMPTY)
{
/* Only created event flag group, just set the created list to NULL. */
_tx_event_flags_created_ptr = TX_NULL;
}
else
{
/* Link-up the neighbors. */
next_group = group_ptr -> tx_event_flags_group_created_next;
previous_group = group_ptr -> tx_event_flags_group_created_previous;
next_group -> tx_event_flags_group_created_previous = previous_group;
previous_group -> tx_event_flags_group_created_next = next_group;
/* See if we have to update the created list head pointer. */
if (_tx_event_flags_created_ptr == group_ptr)
{
/* Yes, move the head pointer to the next link. */
_tx_event_flags_created_ptr = next_group;
}
}
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Pickup the suspension information. */
thread_ptr = group_ptr -> tx_event_flags_group_suspension_list;
group_ptr -> tx_event_flags_group_suspension_list = TX_NULL;
suspended_count = group_ptr -> tx_event_flags_group_suspended_count;
group_ptr -> tx_event_flags_group_suspended_count = TX_NO_SUSPENSIONS;
/* Restore interrupts. */
TX_RESTORE
/* Walk through the event flag suspension list to resume any and all threads
suspended on this group. */
while (suspended_count != TX_NO_SUSPENSIONS)
{
/* Decrement the number of suspended threads. */
suspended_count--;
/* Lockout interrupts. */
TX_DISABLE
/* Clear the cleanup pointer, this prevents the timeout from doing
anything. */
thread_ptr -> tx_thread_suspend_cleanup = TX_NULL;
/* Set the return status in the thread to TX_DELETED. */
thread_ptr -> tx_thread_suspend_status = TX_DELETED;
/* Move the thread pointer ahead. */
next_thread = thread_ptr -> tx_thread_suspended_next;
#ifdef TX_NOT_INTERRUPTABLE
/* Resume the thread! */
_tx_thread_system_ni_resume(thread_ptr);
/* Restore interrupts. */
TX_RESTORE
#else
/* Temporarily disable preemption again. */
_tx_thread_preempt_disable++;
/* Restore interrupts. */
TX_RESTORE
/* Resume the thread. */
_tx_thread_system_resume(thread_ptr);
#endif
/* Move to next thread. */
thread_ptr = next_thread;
}
/* Execute Port-Specific completion processing. If needed, it is typically defined in tx_port.h. */
TX_EVENT_FLAGS_GROUP_DELETE_PORT_COMPLETION(group_ptr)
/* Disable interrupts. */
TX_DISABLE
/* Release previous preempt disable. */
_tx_thread_preempt_disable--;
/* Restore interrupts. */
TX_RESTORE
/* Check for preemption. */
_tx_thread_system_preempt_check();
/* Return TX_SUCCESS. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,401 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Event Flags */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_trace.h"
#include "tx_thread.h"
#include "tx_event_flags.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_event_flags_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function gets the specified event flags from the group, */
/* according to the get option. The get option also specifies whether */
/* or not the retrieved flags are cleared. */
/* */
/* INPUT */
/* */
/* group_ptr Pointer to group control block */
/* requested_event_flags Event flags requested */
/* get_option Specifies and/or and clear options*/
/* actual_flags_ptr Pointer to place the actual flags */
/* the service retrieved */
/* wait_option Suspension option */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* _tx_thread_system_suspend Suspend thread service */
/* _tx_thread_system_ni_suspend Non-interruptable suspend thread */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_event_flags_get(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG requested_flags,
UINT get_option, ULONG *actual_flags_ptr, ULONG wait_option)
{
TX_INTERRUPT_SAVE_AREA
UINT status;
UINT and_request;
UINT clear_request;
ULONG current_flags;
ULONG flags_satisfied;
#ifndef TX_NOT_INTERRUPTABLE
ULONG delayed_clear_flags;
#endif
UINT suspended_count;
TX_THREAD *thread_ptr;
TX_THREAD *next_thread;
TX_THREAD *previous_thread;
#ifndef TX_NOT_INTERRUPTABLE
UINT interrupted_set_request;
#endif
/* Disable interrupts to examine the event flags group. */
TX_DISABLE
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
/* Increment the total event flags get counter. */
_tx_event_flags_performance_get_count++;
/* Increment the number of event flags gets on this semaphore. */
group_ptr -> tx_event_flags_group__performance_get_count++;
#endif
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_EVENT_FLAGS_GET, group_ptr, requested_flags, group_ptr -> tx_event_flags_group_current, get_option, TX_TRACE_EVENT_FLAGS_EVENTS)
/* Log this kernel call. */
TX_EL_EVENT_FLAGS_GET_INSERT
/* Pickup current flags. */
current_flags = group_ptr -> tx_event_flags_group_current;
/* Apply the event flag option mask. */
and_request = (get_option & TX_AND);
#ifdef TX_NOT_INTERRUPTABLE
/* Check for AND condition. All flags must be present to satisfy request. */
if (and_request == TX_AND)
{
/* AND request is present. */
/* Calculate the flags present. */
flags_satisfied = (current_flags & requested_flags);
/* Determine if they satisfy the AND request. */
if (flags_satisfied != requested_flags)
{
/* No, not all the requested flags are present. Clear the flags present variable. */
flags_satisfied = ((ULONG) 0);
}
}
else
{
/* OR request is present. Simply or the requested flags and the current flags. */
flags_satisfied = (current_flags & requested_flags);
}
/* Determine if the request is satisfied. */
if (flags_satisfied != ((ULONG) 0))
{
/* Return the actual event flags that satisfied the request. */
*actual_flags_ptr = current_flags;
/* Pickup the clear bit. */
clear_request = (get_option & TX_EVENT_FLAGS_CLEAR_MASK);
/* Determine whether or not clearing needs to take place. */
if (clear_request == TX_TRUE)
{
/* Yes, clear the flags that satisfied this request. */
group_ptr -> tx_event_flags_group_current =
group_ptr -> tx_event_flags_group_current & (~requested_flags);
}
/* Return success. */
status = TX_SUCCESS;
}
#else
/* Pickup delayed clear flags. */
delayed_clear_flags = group_ptr -> tx_event_flags_group_delayed_clear;
/* Determine if there are any delayed clear operations pending. */
if (delayed_clear_flags != ((ULONG) 0))
{
/* Yes, apply them to the current flags. */
current_flags = current_flags & (~delayed_clear_flags);
}
/* Check for AND condition. All flags must be present to satisfy request. */
if (and_request == TX_AND)
{
/* AND request is present. */
/* Calculate the flags present. */
flags_satisfied = (current_flags & requested_flags);
/* Determine if they satisfy the AND request. */
if (flags_satisfied != requested_flags)
{
/* No, not all the requested flags are present. Clear the flags present variable. */
flags_satisfied = ((ULONG) 0);
}
}
else
{
/* OR request is present. Simply AND together the requested flags and the current flags
to see if any are present. */
flags_satisfied = (current_flags & requested_flags);
}
/* Determine if the request is satisfied. */
if (flags_satisfied != ((ULONG) 0))
{
/* Yes, this request can be handled immediately. */
/* Return the actual event flags that satisfied the request. */
*actual_flags_ptr = current_flags;
/* Pickup the clear bit. */
clear_request = (get_option & TX_EVENT_FLAGS_CLEAR_MASK);
/* Determine whether or not clearing needs to take place. */
if (clear_request == TX_TRUE)
{
/* Set interrupted set request flag to false. */
interrupted_set_request = TX_FALSE;
/* Determine if the suspension list is being processed by an interrupted
set request. */
if (group_ptr -> tx_event_flags_group_suspended_count != TX_NO_SUSPENSIONS)
{
if (group_ptr -> tx_event_flags_group_suspension_list == TX_NULL)
{
/* Set the interrupted set request flag. */
interrupted_set_request = TX_TRUE;
}
}
/* Was a set request interrupted? */
if (interrupted_set_request == TX_TRUE)
{
/* A previous set operation is was interrupted, we need to defer the
event clearing until the set operation is complete. */
/* Remember the events to clear. */
group_ptr -> tx_event_flags_group_delayed_clear =
group_ptr -> tx_event_flags_group_delayed_clear | requested_flags;
}
else
{
/* Yes, clear the flags that satisfied this request. */
group_ptr -> tx_event_flags_group_current =
group_ptr -> tx_event_flags_group_current & ~requested_flags;
}
}
/* Set status to success. */
status = TX_SUCCESS;
}
#endif
else
{
/* Determine if the request specifies suspension. */
if (wait_option != TX_NO_WAIT)
{
/* Determine if the preempt disable flag is non-zero. */
if (_tx_thread_preempt_disable != ((UINT) 0))
{
/* Suspension is not allowed if the preempt disable flag is non-zero at this point, return error completion. */
status = TX_NO_EVENTS;
}
else
{
/* Prepare for suspension of this thread. */
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
/* Increment the total event flags suspensions counter. */
_tx_event_flags_performance_suspension_count++;
/* Increment the number of event flags suspensions on this semaphore. */
group_ptr -> tx_event_flags_group___performance_suspension_count++;
#endif
/* Pickup thread pointer. */
TX_THREAD_GET_CURRENT(thread_ptr)
/* Setup cleanup routine pointer. */
thread_ptr -> tx_thread_suspend_cleanup = &(_tx_event_flags_cleanup);
/* Remember which event flags we are looking for. */
thread_ptr -> tx_thread_suspend_info = requested_flags;
/* Save the get option as well. */
thread_ptr -> tx_thread_suspend_option = get_option;
/* Save the destination for the current events. */
thread_ptr -> tx_thread_additional_suspend_info = (VOID *) actual_flags_ptr;
/* Setup cleanup information, i.e. this event flags group control
block. */
thread_ptr -> tx_thread_suspend_control_block = (VOID *) group_ptr;
#ifndef TX_NOT_INTERRUPTABLE
/* Increment the suspension sequence number, which is used to identify
this suspension event. */
thread_ptr -> tx_thread_suspension_sequence++;
#endif
/* Pickup the suspended count. */
suspended_count = group_ptr -> tx_event_flags_group_suspended_count;
/* Setup suspension list. */
if (suspended_count == TX_NO_SUSPENSIONS)
{
/* No other threads are suspended. Setup the head pointer and
just setup this threads pointers to itself. */
group_ptr -> tx_event_flags_group_suspension_list = thread_ptr;
thread_ptr -> tx_thread_suspended_next = thread_ptr;
thread_ptr -> tx_thread_suspended_previous = thread_ptr;
}
else
{
/* This list is not NULL, add current thread to the end. */
next_thread = group_ptr -> tx_event_flags_group_suspension_list;
thread_ptr -> tx_thread_suspended_next = next_thread;
previous_thread = next_thread -> tx_thread_suspended_previous;
thread_ptr -> tx_thread_suspended_previous = previous_thread;
previous_thread -> tx_thread_suspended_next = thread_ptr;
next_thread -> tx_thread_suspended_previous = thread_ptr;
}
/* Increment the number of threads suspended. */
group_ptr -> tx_event_flags_group_suspended_count++;
/* Set the state to suspended. */
thread_ptr -> tx_thread_state = TX_EVENT_FLAG;
#ifdef TX_NOT_INTERRUPTABLE
/* Call actual non-interruptable thread suspension routine. */
_tx_thread_system_ni_suspend(thread_ptr, wait_option);
/* Return the completion status. */
status = thread_ptr -> tx_thread_suspend_status;
#else
/* Set the suspending flag. */
thread_ptr -> tx_thread_suspending = TX_TRUE;
/* Setup the timeout period. */
thread_ptr -> tx_thread_timer.tx_timer_internal_remaining_ticks = wait_option;
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
/* Restore interrupts. */
TX_RESTORE
/* Call actual thread suspension routine. */
_tx_thread_system_suspend(thread_ptr);
/* Disable interrupts. */
TX_DISABLE
/* Return the completion status. */
status = thread_ptr -> tx_thread_suspend_status;
#endif
}
}
else
{
/* Immediate return, return error completion. */
status = TX_NO_EVENTS;
}
}
/* Restore interrupts. */
TX_RESTORE
/* Return completion status. */
return(status);
}

View File

@@ -0,0 +1,143 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Event Flags */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_trace.h"
#include "tx_event_flags.h"
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_event_flags_info_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function retrieves information from the specified event flag */
/* group. */
/* */
/* INPUT */
/* */
/* group_ptr Pointer to event flag group */
/* name Destination for the event flag */
/* group name */
/* current_flags Current event flags */
/* first_suspended Destination for pointer of first */
/* thread suspended on event flags */
/* suspended_count Destination for suspended count */
/* next_group Destination for pointer to next */
/* event flag group on the created */
/* list */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_event_flags_info_get(TX_EVENT_FLAGS_GROUP *group_ptr, CHAR **name, ULONG *current_flags,
TX_THREAD **first_suspended, ULONG *suspended_count,
TX_EVENT_FLAGS_GROUP **next_group)
{
TX_INTERRUPT_SAVE_AREA
/* Disable interrupts. */
TX_DISABLE
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_EVENT_FLAGS_INFO_GET, group_ptr, 0, 0, 0, TX_TRACE_EVENT_FLAGS_EVENTS)
/* Log this kernel call. */
TX_EL_EVENT_FLAGS_INFO_GET_INSERT
/* Retrieve all the pertinent information and return it in the supplied
destinations. */
/* Retrieve the name of the event flag group. */
if (name != TX_NULL)
{
*name = group_ptr -> tx_event_flags_group_name;
}
/* Retrieve the current event flags in the event flag group. */
if (current_flags != TX_NULL)
{
/* Pickup the current flags and apply delayed clearing. */
*current_flags = group_ptr -> tx_event_flags_group_current &
~group_ptr -> tx_event_flags_group_delayed_clear;
}
/* Retrieve the first thread suspended on this event flag group. */
if (first_suspended != TX_NULL)
{
*first_suspended = group_ptr -> tx_event_flags_group_suspension_list;
}
/* Retrieve the number of threads suspended on this event flag group. */
if (suspended_count != TX_NULL)
{
*suspended_count = (ULONG) group_ptr -> tx_event_flags_group_suspended_count;
}
/* Retrieve the pointer to the next event flag group created. */
if (next_group != TX_NULL)
{
*next_group = group_ptr -> tx_event_flags_group_created_next;
}
/* Restore interrupts. */
TX_RESTORE
/* Return completion status. */
return(TX_SUCCESS);
}

View File

@@ -0,0 +1,130 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Event Flags */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_event_flags.h"
#ifndef TX_INLINE_INITIALIZATION
/* Locate event flags component data in this file. */
/* Define the head pointer of the created event flags list. */
TX_EVENT_FLAGS_GROUP * _tx_event_flags_created_ptr;
/* Define the variable that holds the number of created event flag groups. */
ULONG _tx_event_flags_created_count;
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
/* Define the total number of event flag sets. */
ULONG _tx_event_flags_performance_set_count;
/* Define the total number of event flag gets. */
ULONG _tx_event_flags_performance_get_count;
/* Define the total number of event flag suspensions. */
ULONG _tx_event_flags_performance_suspension_count;
/* Define the total number of event flag timeouts. */
ULONG _tx_event_flags_performance_timeout_count;
#endif
#endif
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_event_flags_initialize PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function initializes the various control data structures for */
/* the event flags component. */
/* */
/* INPUT */
/* */
/* None */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* _tx_initialize_high_level High level initialization */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
VOID _tx_event_flags_initialize(VOID)
{
#ifndef TX_DISABLE_REDUNDANT_CLEARING
/* Initialize the head pointer of the created event flags list and the
number of event flags created. */
_tx_event_flags_created_ptr = TX_NULL;
_tx_event_flags_created_count = TX_EMPTY;
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
/* Initialize event flags performance counters. */
_tx_event_flags_performance_set_count = ((ULONG) 0);
_tx_event_flags_performance_get_count = ((ULONG) 0);
_tx_event_flags_performance_suspension_count = ((ULONG) 0);
_tx_event_flags_performance_timeout_count = ((ULONG) 0);
#endif
#endif
}

View File

@@ -0,0 +1,202 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Event Flags */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_event_flags.h"
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
#include "tx_trace.h"
#endif
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_event_flags_performance_info_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function retrieves performance information from the specified */
/* event flag group. */
/* */
/* INPUT */
/* */
/* group_ptr Pointer to event flag group */
/* sets Destination for the number of */
/* event flag sets on this group */
/* gets Destination for the number of */
/* event flag gets on this group */
/* suspensions Destination for the number of */
/* event flag suspensions on this */
/* group */
/* timeouts Destination for number of timeouts*/
/* on this event flag group */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_event_flags_performance_info_get(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG *sets, ULONG *gets,
ULONG *suspensions, ULONG *timeouts)
{
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
TX_INTERRUPT_SAVE_AREA
UINT status;
/* Determine if this is a legal request. */
if (group_ptr == TX_NULL)
{
/* Event flags group pointer is illegal, return error. */
status = TX_PTR_ERROR;
}
/* Determine if the event group ID is invalid. */
else if (group_ptr -> tx_event_flags_group_id != TX_EVENT_FLAGS_ID)
{
/* Event flags group pointer is illegal, return error. */
status = TX_PTR_ERROR;
}
else
{
/* Disable interrupts. */
TX_DISABLE
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_EVENT_FLAGS_PERFORMANCE_INFO_GET, group_ptr, 0, 0, 0, TX_TRACE_EVENT_FLAGS_EVENTS)
/* Log this kernel call. */
TX_EL_EVENT_FLAGS_PERFORMANCE_INFO_GET_INSERT
/* Retrieve all the pertinent information and return it in the supplied
destinations. */
/* Retrieve the number of set operations on this event flag group. */
if (sets != TX_NULL)
{
*sets = group_ptr -> tx_event_flags_group_performance_set_count;
}
/* Retrieve the number of get operations on this event flag group. */
if (gets != TX_NULL)
{
*gets = group_ptr -> tx_event_flags_group__performance_get_count;
}
/* Retrieve the number of thread suspensions on this event flag group. */
if (suspensions != TX_NULL)
{
*suspensions = group_ptr -> tx_event_flags_group___performance_suspension_count;
}
/* Retrieve the number of thread timeouts on this event flag group. */
if (timeouts != TX_NULL)
{
*timeouts = group_ptr -> tx_event_flags_group____performance_timeout_count;
}
/* Restore interrupts. */
TX_RESTORE
/* Return successful completion. */
status = TX_SUCCESS;
}
#else
UINT status;
/* Access input arguments just for the sake of lint, MISRA, etc. */
if (group_ptr != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (sets != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (gets != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (suspensions != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (timeouts != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
#endif
/* Return completion status. */
return(status);
}

View File

@@ -0,0 +1,174 @@
/**************************************************************************/
/* */
/* Copyright (c) Microsoft Corporation. All rights reserved. */
/* */
/* This software is licensed under the Microsoft Software License */
/* Terms for Microsoft Azure RTOS. Full text of the license can be */
/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
/* and in the root directory of this software. */
/* */
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** ThreadX Component */
/** */
/** Event Flags */
/** */
/**************************************************************************/
/**************************************************************************/
#define TX_SOURCE_CODE
/* Include necessary system files. */
#include "tx_api.h"
#include "tx_event_flags.h"
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
#include "tx_trace.h"
#endif
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _tx_event_flags_performance_system_info_get PORTABLE C */
/* 6.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function retrieves system event flag performance information. */
/* */
/* INPUT */
/* */
/* sets Destination for total number of */
/* event flag sets */
/* gets Destination for total number of */
/* event flag gets */
/* suspensions Destination for total number of */
/* event flag suspensions */
/* timeouts Destination for total number of */
/* timeouts */
/* */
/* OUTPUT */
/* */
/* status Completion status */
/* */
/* CALLS */
/* */
/* None */
/* */
/* CALLED BY */
/* */
/* Application Code */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* */
/**************************************************************************/
UINT _tx_event_flags_performance_system_info_get(ULONG *sets, ULONG *gets, ULONG *suspensions, ULONG *timeouts)
{
#ifdef TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
TX_INTERRUPT_SAVE_AREA
/* Disable interrupts. */
TX_DISABLE
/* If trace is enabled, insert this event into the trace buffer. */
TX_TRACE_IN_LINE_INSERT(TX_TRACE_EVENT_FLAGS__PERFORMANCE_SYSTEM_INFO_GET, 0, 0, 0, 0, TX_TRACE_EVENT_FLAGS_EVENTS)
/* Log this kernel call. */
TX_EL_EVENT_FLAGS__PERFORMANCE_SYSTEM_INFO_GET_INSERT
/* Retrieve all the pertinent information and return it in the supplied
destinations. */
/* Retrieve the total number of event flag set operations. */
if (sets != TX_NULL)
{
*sets = _tx_event_flags_performance_set_count;
}
/* Retrieve the total number of event flag get operations. */
if (gets != TX_NULL)
{
*gets = _tx_event_flags_performance_get_count;
}
/* Retrieve the total number of event flag thread suspensions. */
if (suspensions != TX_NULL)
{
*suspensions = _tx_event_flags_performance_suspension_count;
}
/* Retrieve the total number of event flag thread timeouts. */
if (timeouts != TX_NULL)
{
*timeouts = _tx_event_flags_performance_timeout_count;
}
/* Restore interrupts. */
TX_RESTORE
/* Return completion status. */
return(TX_SUCCESS);
#else
UINT status;
/* Access input arguments just for the sake of lint, MISRA, etc. */
if (sets != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (gets != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (suspensions != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else if (timeouts != TX_NULL)
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
else
{
/* Not enabled, return error. */
status = TX_FEATURE_NOT_ENABLED;
}
/* Return completion status. */
return(status);
#endif
}

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More