diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 442018cc6..9e05737f4 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,8 +1,9 @@
variables:
rpm_release: "0.$CI_PIPELINE_ID"
specfile: $project.spec
- other_repos: $yum_repo_url/redhawk-dependencies
- redhawk_version: '2.0.9'
+ other_repos: $s3_repo_url/redhawk-dependencies/redhawk-dependencies
+ redhawk_version: '2.2.1-rc2'
+ redhawk_deps: 'develop-2.2'
stages:
- package-redhawk-codegen
@@ -33,7 +34,7 @@ stages:
--build-arg "arch=$arch"
--build-arg "spec_file=$specfile"
--build-arg "rpm_release=$rpm_release"
- --build-arg "other_repos=$other_repos/$dist/$arch"
+ --build-arg "other_repos=${other_repos}/yum/${redhawk_deps}/$dist/$arch"
--build-arg "local_repo=$local_repo" .
# Create a yum repository from the packages we just built and any packages we've built in a previous stage
- id=$(docker create -it ${docker_registry}redhawk-rpmbuild:$proj_lower-$safe_ref-$dist-$arch bash -lc 'mkdir -p /tmp/repo;
@@ -44,11 +45,14 @@ stages:
createrepo .;
tar czf repo.tar.gz *')
- docker start -a $id
- #Cleanup any previous output we've inherited
+ # Cleanup any previous output we've inherited
- cd $CI_PROJECT_DIR
- rm -rf output && mkdir output
- docker cp $id:/tmp/repo/repo.tar.gz output/repo.tar.gz
- docker rm -f $id || true
+ - cd output
+ - tar xf repo.tar.gz
+ - cd $CI_PROJECT_DIR
artifacts:
name: $CI_JOB_NAME
paths:
@@ -58,18 +62,6 @@ stages:
- master
- /^(\d+\.)?(\d+)?(\.\d+)$/
-.deploy-common: &deploy-common
- image: ${docker_registry}centos:7
- stage: deploy
- dependencies: []
- script:
- - if [ -n "$jenkins_url" ]; then
- curl --insecure -X POST $jenkins_url/job/$jenkins_job/buildWithParameters?pipeline_id=$CI_PIPELINE_ID --user $jenkins_user:$jenkins_api_token;
- fi
- except:
- - master
- - /^(\d+\.)?(\d+)?(\.\d+)$/
-
redhawk:el6-i386:
stage: package-redhawk-codegen
variables:
@@ -261,11 +253,19 @@ frontend:el7:
local_repo: output
<<: *rpmbuild
-#Trigger a Jenkins job to aggregate artifacts there
deploy:
- variables:
- jenkins_job: redhawk/job/core-framework-$CI_COMMIT_REF_NAME
- <<: *deploy-common
+ image: ${docker_registry}centos:7
+ stage: deploy
+ dependencies: []
+ before_script:
+ - echo "Deploying to $jenkins_url/job/$CI_PROJECT_NAMESPACE/job/$CI_PROJECT_NAME-`basename $CI_COMMIT_REF_NAME`"
+ script:
+ - if [ -n "$jenkins_url" ]; then
+ curl --insecure -X POST $jenkins_url/job/$CI_PROJECT_NAMESPACE/job/$CI_PROJECT_NAME-`basename $CI_COMMIT_REF_NAME`/buildWithParameters?pipeline_id=$CI_PIPELINE_ID --user $jenkins_user:$jenkins_api_token;
+ fi
+ except:
+ - /^(\d+\.)?(\d+)?(\.\d+)$/
+ - master
#Trigger separate tests pipeline
test-trigger:
@@ -277,6 +277,7 @@ test-trigger:
-F token=$test_token
-F "variables[triggering_ref]=$CI_COMMIT_SHA"
-F "variables[triggering_ref_name]=$CI_COMMIT_REF_NAME"
+ -F "variables[triggering_ref_slug]=$CI_COMMIT_REF_SLUG"
$test_url
only:
- branches
@@ -287,14 +288,87 @@ test-trigger:release:
image: ${docker_registry}centos:7
stage: deploy
dependencies: []
+ variables:
+ redhawk_version: '2.2.0'
script:
- curl --insecure -X POST -F ref=$redhawk_version
-F token=$test_token
-F "variables[triggering_ref]=$CI_COMMIT_SHA"
-F "variables[triggering_ref_name]=$CI_COMMIT_REF_NAME"
+ -F "variables[triggering_ref_slug]=$CI_COMMIT_REF_SLUG"
$test_url
only:
- tags
- #Skip on tag of following format
except:
- /^(\d+\.)?(\d+)?(\.\d+)$/
+
+.s3: &s3
+ image: ${docker_registry}utils/s3cmd:el6-createrepo
+ stage: deploy
+ tags:
+ - s3
+ script:
+ - CI_COMMIT_REF_SLUG_NO_RC=${CI_COMMIT_REF_SLUG%-rc[0-9]*};
+ - mkdir -p $arch
+ - for file in `find output -name *.rpm`; do
+ cp $file $arch;
+ done
+ - createrepo $arch
+ - /usr/bin/s3cmd sync -F -v -P --delete-removed $arch s3://$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME/yum/$CI_COMMIT_REF_SLUG/$dist/
+ - if [ "$CI_COMMIT_REF_SLUG_NO_RC" != "$CI_COMMIT_REF_SLUG" ]; then
+ /usr/bin/s3cmd sync -F -v -P --delete-removed $arch s3://$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME/yum/$CI_COMMIT_REF_SLUG_NO_RC/$dist/;
+ fi
+ # Pull down dependencies to create aggregated "cf-and-deps" repo
+ - mkdir -p cf-and-deps/$arch
+ - curl ${s3_repo_url}/redhawk-dependencies/redhawk-dependencies/yum/${redhawk_deps}/$dist/$arch/redhawk-dependencies.repo > /etc/yum.repos.d/redhawk-dependencies.repo
+ - reposync --download_path=tmp
+ --newest-only
+ --repoid=redhawk-dependencies
+ - for file in `find tmp -name *.rpm`; do
+ cp $file cf-and-deps/$arch;
+ done
+ - for file in `find output -name *.rpm`; do
+ cp $file cf-and-deps/$arch;
+ done
+ - createrepo cf-and-deps/$arch
+ - cd cf-and-deps
+ - /usr/bin/s3cmd sync -F -v -P --delete-removed $arch s3://$CI_PROJECT_NAMESPACE/cf-and-deps/yum/$CI_COMMIT_REF_SLUG/$dist/
+
+deploy-el7:
+ variables:
+ dist: el7
+ arch: x86_64
+ dependencies:
+ - redhawk:el7
+ - bulkio:el7
+ - burstio:el7
+ - frontend:el7
+ - gpp:el7
+ - redhawk-codegen:el7
+ <<: *s3
+
+deploy-el6:
+ variables:
+ dist: el6
+ arch: x86_64
+ dependencies:
+ - redhawk:el6
+ - bulkio:el6
+ - burstio:el6
+ - frontend:el6
+ - gpp:el6
+ - redhawk-codegen:el6
+ <<: *s3
+
+deploy-el6-i386:
+ variables:
+ dist: el6
+ arch: i686
+ dependencies:
+ - redhawk:el6-i386
+ - bulkio:el6-i386
+ - burstio:el6-i386
+ - frontend:el6-i386
+ - gpp:el6-i386
+ - redhawk-codegen:el6-i386
+ <<: *s3
diff --git a/GPP/.gitignore b/GPP/.gitignore
index 2f78cf5b6..4ebbe450c 100644
--- a/GPP/.gitignore
+++ b/GPP/.gitignore
@@ -1,2 +1,12 @@
+*.o
*.pyc
-
+.deps/
+Makefile
+Makefile.in
+aclocal.m4
+autom4te.cache/
+config.*
+configure
+depcomp
+install-sh
+missing
diff --git a/GPP/GPP.prf.xml b/GPP/GPP.prf.xml
index 51dfb675b..4463af5c6 100644
--- a/GPP/GPP.prf.xml
+++ b/GPP/GPP.prf.xml
@@ -69,15 +69,12 @@ with this program. If not, see http://www.gnu.org/licenses/.
-
If provided, all component output will be redirected to this file. The GPP will not delete or rotate these logs. The provided value may contain environment variables or reference component exec-params with @EXEC_PARAM@. For example, this would be a valid value $SDRROOT/logs/@COMPONENT_IDENTIFIER@.log
-
-
DCE:e4e86070-a121-45d4-a144-00386f2188e3
@@ -86,6 +83,7 @@ with this program. If not, see http://www.gnu.org/licenses/.
Required
+
Data rate being allocated. See data_size for unit of measurement.
@@ -114,11 +112,13 @@ Optional
Requires the IP address to be addressable from the interface.
Optional
+
Requires this specific interface.
Optional
+
@@ -153,35 +153,85 @@ Optional
-
-
+
+
+
+
+
+
0.0
Mbps
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
False
@@ -189,7 +239,9 @@ Optional
0
Mbps
-
+
+
+
0
@@ -200,7 +252,6 @@ Optional
-
The Multicast NIC interface associated with this GPP (e.g. eth1). If not provided no multicast allocations are permitted.
@@ -251,7 +302,6 @@ Optional
-
Percentage of total Multicast NIC this GPP can use for capacity management
80
@@ -260,13 +310,11 @@ Optional
-
When queired, returns the list of vlans on this host. When used as an allocation, defines the list of VLANS the component requires.
-
80.0
@@ -296,7 +344,6 @@ Optional
-
Identifier of component or device that generated this message
@@ -331,7 +378,6 @@ THRESHOLD_NOT_EXCEEDED: The measured value no longer exceeds the configured thr
-
cycle time between updates of metric capture, calculations and threshold evaluations.
500
@@ -339,57 +385,61 @@ THRESHOLD_NOT_EXCEEDED: The measured value no longer exceeds the configured thr
-
Report reason why the GPP had it's usage state set to BUSY.
-
+
+ Select a cache directory other than the default.
+
+
+
+
+
+ Select a working directory other than the default.
+
+
+
+
The thresholds that cause a failure for allocations
+
+ false
+
10
%
-
-
80
%
-
-
10
MB
-
-
900
MB/s
-
-
The percentage of file handles remaining to the GPP that triggers a threshold condition
3
%
-
-
The percentage of threads available to the GPP that triggers a threshold condition
3
%
-
-
+
+
+ 10
+ MB
-
Amount of RAM in the GPP not in use (measured)
MiB
@@ -403,6 +453,16 @@ THRESHOLD_NOT_EXCEEDED: The measured value no longer exceeds the configured thr
+
+ MB
+
+
+
+
+ MB
+
+
+
Equal to "processor_cores" x "loadCapacityPerCore".
@@ -435,42 +495,28 @@ THRESHOLD_NOT_EXCEEDED: The measured value no longer exceeds the configured thr
-
The current load average, as reported by /proc/loadavg. Each core on a computer can have a load average between 0.0 and 1.0. This differs greatly from CPU percentage (as reported by top). Load averages differ in two significant ways: 1) they measure the trend of CPU utlization, and 2) they include all demand for the CPU not only how much was active at the time of measurement. Load averages do not include any processes or threads waiting on I/O, networking, databases, or anything else not demanding the CPU.
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
+
0.1
-
-
list of cpu ids that are being monitored for loadavg and idle utilization.
-
The current number of threads for the GPP
@@ -486,7 +532,6 @@ THRESHOLD_NOT_EXCEEDED: The measured value no longer exceeds the configured thr
-
The current number of threads running on the system
@@ -502,7 +547,6 @@ THRESHOLD_NOT_EXCEEDED: The measured value no longer exceeds the configured thr
-
@@ -513,8 +557,6 @@ THRESHOLD_NOT_EXCEEDED: The measured value no longer exceeds the configured thr
-
-
@@ -535,14 +577,16 @@ THRESHOLD_NOT_EXCEEDED: The measured value no longer exceeds the configured thr
-
-
+
+
+
+
+
+
The context specification for the exec_directive_class. See numa library manpage for socket(numa node) and cpu list specifications. For cgroup/cpuset option then a pre-existing cgroup name is required.
0
-
-
The classification of the affinity policy to apply.
@@ -553,35 +597,23 @@ THRESHOLD_NOT_EXCEEDED: The measured value no longer exceeds the configured thr
-
-
determines if the specified affinity policy (exec_directive_value, exec_directive_class) is inherited by RH resources started from this GPP.
false
-
-
list of cpu ids to black list when making affinity requests. see numa library manpage for cpu list specifications.
-
-
If no affinity specification is provide during deployment, then enabling this will deploy resources on next available processor socket. (force_override will ignore this)
false
-
-
controls if affinity requests are processed by the GPP.
true
-
-
-
-
-
+
\ No newline at end of file
diff --git a/GPP/GPP.scd.xml b/GPP/GPP.scd.xml
index 1a022e95e..df6b1aa54 100644
--- a/GPP/GPP.scd.xml
+++ b/GPP/GPP.scd.xml
@@ -66,4 +66,4 @@ with this program. If not, see http://www.gnu.org/licenses/.
-
+
\ No newline at end of file
diff --git a/GPP/GPP.spd.xml b/GPP/GPP.spd.xml
index 6d9b8aa43..7027a8c5d 100644
--- a/GPP/GPP.spd.xml
+++ b/GPP/GPP.spd.xml
@@ -1,5 +1,4 @@
-
-
+
-
+
+
Redhawk GPP
null
diff --git a/GPP/GPP.spec b/GPP/GPP.spec
index ce24d7da0..82c1546b4 100644
--- a/GPP/GPP.spec
+++ b/GPP/GPP.spec
@@ -31,8 +31,8 @@ Prefix: %{_prefix}
%define _infodir %{_prefix}/info
Name: GPP
-Version: 2.0.9
-Release: 1%{?dist}
+Version: 2.2.1
+Release: 2%{?dist}
Summary: REDHAWK GPP
Group: Applications/Engineering
@@ -41,10 +41,8 @@ URL: http://redhawksdr.org/
Source: %{name}-%{version}.tar.gz
Vendor: REDHAWK
-BuildRoot: %{_tmppath}/%{name}-root
-
-Requires(post): redhawk >= 2.0
-BuildRequires: redhawk-devel >= 2.0
+Requires(post): redhawk = %{version}
+BuildRequires: redhawk-devel = %{version}
BuildRequires: numactl-devel >= 2.0
Obsoletes: %{name} < 2.0
@@ -126,6 +124,12 @@ find %{_prefix}/dev/nodes -type d -name 'DevMgr_*' -uid 0 -exec chown -R redhawk
%changelog
+* Wed Jun 28 2017 Ryan Bauman - 2.1.2-1
+- Update for 2.1.2-rc1
+
+* Wed Jun 28 2017 Ryan Bauman - 2.1.1-2
+- Bump for 2.1.1-rc2
+
* Fri Jan 9 2015 1.11.0-1
- Update for cpp GPP
diff --git a/GPP/HEADER b/GPP/HEADER
new file mode 100644
index 000000000..3df23d2b5
--- /dev/null
+++ b/GPP/HEADER
@@ -0,0 +1,17 @@
+This file is protected by Copyright. Please refer to the COPYRIGHT file
+distributed with this source distribution.
+
+This file is part of REDHAWK GPP.
+
+REDHAWK GPP is free software: you can redistribute it and/or modify it under
+the terms of the GNU Lesser General Public License as published by the Free
+Software Foundation, either version 3 of the License, or (at your option) any
+later version.
+
+REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see http://www.gnu.org/licenses/.
\ No newline at end of file
diff --git a/GPP/build.sh b/GPP/build.sh
index 118b4cce5..1fecacc9c 100755
--- a/GPP/build.sh
+++ b/GPP/build.sh
@@ -24,9 +24,9 @@ if [ "$1" = "rpm" ]; then
if [ -e GPP.spec ]; then
mydir=`dirname $0`
tmpdir=`mktemp -d`
- cp -r ${mydir} ${tmpdir}/GPP-2.0.9
- tar czf ${tmpdir}/GPP-2.0.9.tar.gz --exclude=".svn" --exclude=".git" -C ${tmpdir} GPP-2.0.9
- rpmbuild -ta ${tmpdir}/GPP-2.0.9.tar.gz
+ cp -r ${mydir} ${tmpdir}/GPP-2.2.1
+ tar czf ${tmpdir}/GPP-2.2.1.tar.gz --exclude=".svn" -C ${tmpdir} GPP-2.2.1
+ rpmbuild -ta ${tmpdir}/GPP-2.2.1.tar.gz
rm -rf $tmpdir
else
echo "Missing RPM spec file in" `pwd`
diff --git a/GPP/cpp/.gitignore b/GPP/cpp/.gitignore
index bc1a67473..c2b075fa7 100644
--- a/GPP/cpp/.gitignore
+++ b/GPP/cpp/.gitignore
@@ -1,13 +1,3 @@
-.deps
.dirstamp
GPP
-Makefile
-Makefile.in
-aclocal.m4
-autom4te.cache/
compile
-config.*
-configure
-depcomp
-install-sh
-missing
diff --git a/GPP/cpp/.md5sums b/GPP/cpp/.md5sums
index e9a105a73..14d039834 100644
--- a/GPP/cpp/.md5sums
+++ b/GPP/cpp/.md5sums
@@ -1,11 +1,11 @@
-9a98d99db1969fd0d9d15997f4e17a2b GPP_base.cpp
+8580ff5ad75dd6c08534c1b70d2d531d GPP_base.cpp
63f09d1ebc0f9bc23cde5f0ba62bfe92 main.cpp
-c99df9fa4ab0cd042eac42fcee6441c3 reconf
+222775e71f94ed287b5265eb43029af4 reconf
0d4ac7556a5e6a8ae5c1af00b1e60294 GPP.cpp
-380674a5e3e6aad2c33ae49b11604261 GPP_base.h
+d9201d8ccb494530596eb36fea85b5fb GPP_base.h
ed52e5c18685dbea09f982b35fb4b244 configure.ac
27c738bb146931b195b29a3f05a7dccb Makefile.am
32a7fdea0a2b8c7378333703d831ed8d GPP.h
9ed0b24c3ac3d024b71659ce764c1fdc Makefile.am.ide
-fbe69e2e989cfda455bc149083a5ff58 struct_props.h
-0d1975802982b41325f73129696f8a63 build.sh
+39bc4c07bada48e93495cce426a74e2a struct_props.h
+82a9e0259f502aa6171972509a8cca50 build.sh
diff --git a/GPP/cpp/GPP.cpp b/GPP/cpp/GPP.cpp
index 1ce845f6b..f1b3769fb 100644
--- a/GPP/cpp/GPP.cpp
+++ b/GPP/cpp/GPP.cpp
@@ -42,6 +42,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -71,25 +72,19 @@
#include
#endif
-#include "ossie/Events.h"
-#include "ossie/affinity.h"
-
+#include
+#include
+#include
+#include
+#include
#include "GPP.h"
#include "utils/affinity.h"
#include "utils/SymlinkReader.h"
-#include "utils/ReferenceWrapper.h"
#include "parsers/PidProcStatParser.h"
#include "states/ProcStat.h"
#include "states/ProcMeminfo.h"
#include "statistics/CpuUsageStats.h"
-#include "reports/NicThroughputThresholdMonitor.h"
-#include "reports/FreeMemoryThresholdMonitor.h"
-
-#define PROCESSOR_NAME "DCE:fefb9c66-d14a-438d-ad59-2cfd1adb272b"
-#define OS_NAME "DCE:4a23ad60-0b25-4121-a630-68803a498f75"
-#define OS_VERSION "DCE:0f3a9a37-a342-43d8-9b7f-78dc6da74192"
-
class SigChildThread : public ThreadedComponent {
@@ -120,6 +115,8 @@ class RedirectedIO : public ThreadedComponent {
};
+static const uint64_t MB_TO_BYTES = 1024*1024;
+
uint64_t conv_units( const std::string &units ) {
uint64_t unit_m=1024*1024;
if ( units == "Kb" ) unit_m = 1e3;
@@ -127,7 +124,7 @@ uint64_t conv_units( const std::string &units ) {
if ( units == "Gb" ) unit_m = 1e9;
if ( units == "Tb" ) unit_m = 1e12;
if ( units == "KB" ) unit_m = 1024;
- if ( units == "MB" || units == "MiB" ) unit_m = 1024*1024;
+ if ( units == "MB" || units == "MiB" ) unit_m = MB_TO_BYTES;
if ( units == "GB" ) unit_m = 1024*1024*1024;
if ( units == "TB" ) unit_m = (uint64_t)1024*1024*1024*1024;
return unit_m;
@@ -203,11 +200,12 @@ namespace rh_logger {
//
// proc_redirect class and helpers
//
-class FindRedirect : public std::binary_function< GPP_i::proc_redirect, int, bool > {
+class FindRedirect : public std::binary_function< GPP_i::ProcRedirectPtr, int, bool > {
public:
- bool operator() ( const GPP_i::proc_redirect &a, const int &pid ) const {
- return a.pid == pid;
+ // bool operator() ( const GPP_i::proc_redirect &a, const int &pid ) const {
+ bool operator() ( const GPP_i::ProcRedirectPtr a, const int &pid ) const {
+ return a->pid == pid;
};
};
@@ -409,6 +407,7 @@ void GPP_i::_init() {
//
_handle_io_redirects = false;
_componentOutputLog ="";
+ epfd=epoll_create(400);
//
// add our local set affinity method that performs numa library calls
@@ -443,25 +442,26 @@ void GPP_i::_init() {
// default cycle time setting for updating data model, metrics and state
threshold_cycle_time = 500;
+ thresholds.ignore = false;
//
// Add property change listeners and allocation modifiers
//
// Add property change listeners for affinity information...
- addPropertyChangeListener( "affinity", this, &GPP_i::_affinity_changed );
+ addPropertyListener(affinity, this, &GPP_i::_affinity_changed);
// add property change listener
- addPropertyChangeListener("reserved_capacity_per_component", this, &GPP_i::reservedChanged);
+ addPropertyListener(reserved_capacity_per_component, this, &GPP_i::reservedChanged);
// add property change listener
- addPropertyChangeListener("DCE:c80f6c5a-e3ea-4f57-b0aa-46b7efac3176", this, &GPP_i::_component_output_changed);
+ addPropertyListener(componentOutputLog, this, &GPP_i::_component_output_changed);
// add property change listener
- addPropertyChangeListener("DCE:89be90ae-6a83-4399-a87d-5f4ae30ef7b1", this, &GPP_i::mcastnicThreshold_changed);
+ addPropertyListener(mcastnicThreshold, this, &GPP_i::mcastnicThreshold_changed);
// add property change listener thresholds
- addPropertyChangeListener("thresholds", this, &GPP_i::thresholds_changed);
+ addPropertyListener(thresholds, this, &GPP_i::thresholds_changed);
utilization_entry_struct cpu;
cpu.description = "CPU cores";
@@ -471,9 +471,6 @@ void GPP_i::_init() {
cpu.maximum = 0;
utilization.push_back(cpu);
- // shadow property to allow for disabling of values
- __thresholds = thresholds;
-
setPropertyQueryImpl(this->component_monitor, this, &GPP_i::get_component_monitor);
// tie allocation modifier callbacks to identifiers
@@ -494,7 +491,43 @@ void GPP_i::_init() {
setAllocationImpl("DCE:8dcef419-b440-4bcf-b893-cab79b6024fb", this, &GPP_i::allocate_memCapacity, &GPP_i::deallocate_memCapacity);
//setAllocationImpl("diskCapacity", this, &GPP_i::allocate_diskCapacity, &GPP_i::deallocate_diskCapacity);
+
+ // check reservation allocations
+ setAllocationImpl(this->redhawk__reservation_request, this, &GPP_i::allocate_reservation_request, &GPP_i::deallocate_reservation_request);
+
+}
+
+void GPP_i::constructor()
+{
+ // Get the initial working directory
+ char buf[PATH_MAX+1];
+ getcwd(buf, sizeof(buf));
+ std::string path = buf;
+
+ // If a working directory was given, change to that
+ if (!workingDirectory.empty()) {
+ if (chdir(workingDirectory.c_str())) {
+ RH_ERROR(_baseLog, "Cannot change working directory to " << workingDirectory);
+ workingDirectory = "";
+ }
+ }
+ // Otherwise, default to the initial working directory
+ if (workingDirectory.empty()) {
+ workingDirectory = path;
+ }
+
+ // If no cache directory given, use initial working directory
+ if (cacheDirectory.empty()) {
+ cacheDirectory = path;
+ }
+
+ RH_DEBUG(_baseLog, "Working directory: " << workingDirectory);
+ RH_DEBUG(_baseLog, "Cache directory: " << cacheDirectory);
+
+ shmCapacity = redhawk::shm::getSystemTotalMemory() / MB_TO_BYTES;
+ // Initialize system and user CPU ticks
+ ProcStat::GetTicks(_systemTicks, _userTicks);
}
@@ -532,7 +565,7 @@ void GPP_i::update_grp_child_pids() {
catch(...){
std::stringstream errstr;
errstr << "Unable to process id: "<_baseLog, __FUNCTION__ << ": " << errstr.str() );
continue;
}
}
@@ -574,20 +607,20 @@ void GPP_i::update_grp_child_pids() {
} catch ( ... ) {
std::stringstream errstr;
errstr << "Invalid line format in stat file, pid :" << _pid << " field number " << fcnt << " line " << line ;
- LOG_WARN(GPP_i, __FUNCTION__ << ": " << errstr.str() );
+ RH_WARN(this->_baseLog, __FUNCTION__ << ": " << errstr.str() );
continue;
}
} catch ( ... ) {
std::stringstream errstr;
errstr << "Unable to read "<_baseLog, __FUNCTION__ << ": " << errstr.str() );
continue;
}
if ( fcnt < 37 ) {
std::stringstream errstr;
errstr << "Insufficient fields proc//stat: "<=37 received=" << fcnt << ")";
- LOG_DEBUG(GPP_i, __FUNCTION__ << ": " << errstr.str() );
+ RH_DEBUG(this->_baseLog, __FUNCTION__ << ": " << errstr.str() );
continue;
}
parsed_stat[pid] = tmp;
@@ -631,7 +664,7 @@ std::vector GPP_i::get_component_monitor() {
if ((grp_children.find(_pid.pid) == grp_children.end()) or (parsed_stat.find(_pid.pid) == parsed_stat.end())) {
std::stringstream errstr;
errstr << "Could not find /proc/"<<_pid.pid<<"/stat. The process corresponding to component "<<_pid.identifier<<" is no longer there";
- LOG_WARN(GPP_i, __FUNCTION__ << ": " << errstr.str() );
+ RH_WARN(this->_baseLog, __FUNCTION__ << ": " << errstr.str() );
continue;
}
component_monitor_struct tmp;
@@ -682,7 +715,7 @@ void GPP_i::process_ODM(const CORBA::Any &data) {
i=std::find_if( i, pids.end(), std::bind2nd( FindApp(), appId ) );
if ( i != pids.end() ) {
i->app_started = true;
- LOG_TRACE(GPP_i, "Monitor_Processes.. APP STARTED:" << i->pid << " app: " << i->appName );
+ RH_TRACE(this->_baseLog, "Monitor_Processes.. APP STARTED:" << i->pid << " app: " << i->appName );
i++;
}
}
@@ -695,49 +728,68 @@ void GPP_i::process_ODM(const CORBA::Any &data) {
i=std::find_if( i, pids.end(), std::bind2nd( FindApp(), appId ) );
if ( i != pids.end() ) {
i->app_started = false;
- LOG_TRACE(GPP_i, "Monitor_Processes.. APP STOPPED :" << i->pid << " app: " << i->appName );
+ RH_TRACE(this->_baseLog, "Monitor_Processes.. APP STOPPED :" << i->pid << " app: " << i->appName );
i++;
}
}
}
}
+ const StandardEvent::DomainManagementObjectRemovedEventType* app_removed;
+ if (data >>= app_removed) {
+ if (app_removed->sourceCategory == StandardEvent::APPLICATION) {
+ WriteLock rlock(pidLock);
+ std::string producerId(app_removed->producerId);
+ for (ApplicationReservationMap::iterator app_it=applicationReservations.begin(); app_it!=applicationReservations.end(); app_it++) {
+ if (app_it->first == producerId) {
+ applicationReservations.erase(app_it);
+ break;
+ }
+ }
+ }
+ }
}
int GPP_i::_setupExecPartitions( const CpuList &bl_cpus ) {
#if HAVE_LIBNUMA
- // fill in the exec partitions for each numa node identified on the system
- std::string nodestr("all");
- struct bitmask *node_mask = numa_parse_nodestring((char *)nodestr.c_str());
+ if ( gpp::affinity::check_numa() == true ) {
+ // fill in the exec partitions for each numa node identified on the system
+ std::string nodestr("all");
+ struct bitmask *node_mask = numa_parse_nodestring((char *)nodestr.c_str());
- bitmask *cpu_mask = numa_allocate_cpumask();
+ bitmask *cpu_mask = numa_allocate_cpumask();
- // for each node bit set in the mask then get cpu list
- int nbytes = numa_bitmask_nbytes(node_mask);
- for (int i=0; i < nbytes*8; i++ ){
- if ( numa_bitmask_isbitset( node_mask, i ) ) {
- numa_node_to_cpus( i, cpu_mask );
+ // for each node bit set in the mask then get cpu list
+ int nbytes = numa_bitmask_nbytes(node_mask);
+ for (int i=0; i < nbytes*8; i++ ){
+ if ( numa_bitmask_isbitset( node_mask, i ) ) {
+ numa_node_to_cpus( i, cpu_mask );
- // foreach cpu identified add to list
- int nb = numa_bitmask_nbytes(cpu_mask);
- CpuUsageStats::CpuList cpus;
- for (int j=0; j < nb*8; j++ ){
- int count = std::count( bl_cpus.begin(), bl_cpus.end(), j );
- if ( numa_bitmask_isbitset( cpu_mask, j ) && count == 0 ) {
- cpus.push_back( j );
- }
+ // foreach cpu identified add to list
+ int nb = numa_bitmask_nbytes(cpu_mask);
+ CpuUsageStats::CpuList cpus;
+ for (int j=0; j < nb*8; j++ ){
+ int count = std::count( bl_cpus.begin(), bl_cpus.end(), j );
+ if ( numa_bitmask_isbitset( cpu_mask, j ) && count == 0 ) {
+ cpus.push_back( j );
+ }
+ }
+ CpuUsageStats cpu_usage(cpus);
+ exec_socket soc;
+ soc.id = i;
+ soc.cpus = cpus;
+ soc.stats = cpu_usage;
+ if (!thresholds.ignore && (thresholds.cpu_idle >= 0.0)) {
+ soc.idle_threshold = thresholds.cpu_idle;
+ } else {
+ soc.idle_threshold = 0.0;
+ }
+ soc.load_capacity.max = cpus.size() * 1.0;
+ soc.load_capacity.measured = 0.0;
+ soc.load_capacity.allocated = 0.0;
+ execPartitions.push_back( soc );
+ }
}
- CpuUsageStats cpu_usage(cpus);
- exec_socket soc;
- soc.id = i;
- soc.cpus = cpus;
- soc.stats = cpu_usage;
- soc.idle_threshold = __thresholds.cpu_idle;
- soc.load_capacity.max = cpus.size() * 1.0;
- soc.load_capacity.measured = 0.0;
- soc.load_capacity.allocated = 0.0;
- execPartitions.push_back( soc );
- }
}
#endif
@@ -746,13 +798,13 @@ int GPP_i::_setupExecPartitions( const CpuList &bl_cpus ) {
ExecPartitionList::iterator iter = execPartitions.begin();
std::ostringstream ss;
ss << boost::format("%-6s %-4s %-7s %-7s %-7s ") % "SOCKET" % "CPUS" % "USER" % "SYSTEM" % "IDLE" ;
- LOG_INFO(GPP_i, ss.str() );
+ RH_TRACE(this->_baseLog, ss.str() );
ss.clear();
ss.str("");
for ( ; iter != execPartitions.end(); iter++ ) {
iter->update(); iter->update();
ss << boost::format("%-6d %-4d %-7.2f %-7.2f %-7.2f ") % iter->id % iter->stats.get_ncpus() % iter->stats.get_user_percent() % iter->stats.get_system_percent() % iter->stats.get_idle_percent() ;
- LOG_INFO(GPP_i, ss.str() );
+ RH_TRACE(this->_baseLog, ss.str() );
ss.clear();
ss.str("");
}
@@ -774,25 +826,30 @@ GPP_i::initializeNetworkMonitor()
data_model.push_back( nic_facade );
+ _allNicsThresholdMonitor = boost::make_shared("nics", "NIC_THROUGHPUT");
+ threshold_monitors.push_back(_allNicsThresholdMonitor);
+
std::vector nic_devices( nic_facade->get_devices() );
std::vector filtered_devices( nic_facade->get_filtered_devices() );
for( size_t i=0; i(modified_thresholds.nic_usage),
- boost::bind(&NicFacade::get_throughput_by_device, nic_facade, nic_devices[i]) ) );
-
- // monitors that affect busy state...
- for ( size_t ii=0; ii < filtered_devices.size(); ii++ ) {
- if ( nic_devices[i] == filtered_devices[ii] ) {
- nic_monitors.push_back(nic_m);
- break;
- }
+ // Only use the filtered set of devices, which we can get away with
+ // here because it cannot be updated after this method runs. In the
+ // future, if the available NICs can be dynamically changed, all of the
+ // possible NICs will need to be created here and selectively marked as
+ // active/inactive (distinct from threshold enable/disable).
+ const std::string& nic = nic_devices[i];
+ if (std::find(filtered_devices.begin(), filtered_devices.end(), nic) == filtered_devices.end()) {
+ RH_INFO(_baseLog, __FUNCTION__ << ": Skipping interface (" << nic << ")");
+ continue;
}
- addThresholdMonitor(nic_m);
+
+ RH_INFO(_baseLog, __FUNCTION__ << ": Adding interface (" << nic << ")");
+ ThresholdMonitorPtr nic_m = boost::make_shared(nic, "NIC_THROUGHPUT", this, &GPP_i::_nicThresholdCheck);
+ nic_m->add_listener(this, &GPP_i::_nicThresholdStateChanged);
+ _allNicsThresholdMonitor->add_monitor(nic_m);
}
+
}
void
@@ -800,7 +857,7 @@ GPP_i::initializeResourceMonitors()
{
// add cpu utilization calculator
- RH_NL_INFO("GPP", " initialize CPU Montior --- wl size " << wl_cpus.size());
+ RH_NL_INFO("GPP", " initialize CPU Monitor --- wl size " << wl_cpus.size());
// request a system monitor for this GPP
system_monitor.reset( new SystemMonitor( wl_cpus ) );
@@ -819,30 +876,188 @@ GPP_i::initializeResourceMonitors()
data_model.push_back( process_limits );
// observer to monitor when cpu idle pass threshold value
- addThresholdMonitor( ThresholdMonitorPtr( new CpuThresholdMonitor(_identifier, &modified_thresholds.cpu_idle,
- *(system_monitor->getCpuStats()), false )));
+ _cpuIdleThresholdMonitor = boost::make_shared("cpu", "CPU_IDLE", this, &GPP_i::_cpuIdleThresholdCheck);
+ _cpuIdleThresholdMonitor->add_listener(this, &GPP_i::_cpuIdleThresholdStateChanged);
+ threshold_monitors.push_back(_cpuIdleThresholdMonitor);
+
+ _loadAvgThresholdMonitor = boost::make_shared("cpu", "LOAD_AVG", this, &GPP_i::_loadAvgThresholdCheck);
+ _loadAvgThresholdMonitor->add_listener(this, &GPP_i::_loadAvgThresholdStateChanged);
+ threshold_monitors.push_back(_loadAvgThresholdMonitor);
- // add available memory monitor, mem_free defaults to MB
- addThresholdMonitor( ThresholdMonitorPtr( new FreeMemoryThresholdMonitor(_identifier,
- MakeCref(modified_thresholds.mem_free),
- ConversionWrapper(memCapacity, mem_cap_units, std::multiplies() ) )));
+ _freeMemThresholdMonitor = boost::make_shared("physical_ram", "MEMORY_FREE", this, &GPP_i::_freeMemThresholdCheck);
+ _freeMemThresholdMonitor->add_listener(this, &GPP_i::_freeMemThresholdStateChanged);
+ threshold_monitors.push_back(_freeMemThresholdMonitor);
+
+ _threadThresholdMonitor = boost::make_shared("ulimit", "THREADS", this, &GPP_i::_threadThresholdCheck);
+ _threadThresholdMonitor->add_listener(this, &GPP_i::_threadThresholdStateChanged);
+ threshold_monitors.push_back(_threadThresholdMonitor);
+
+ _fileThresholdMonitor = boost::make_shared("ulimit", "OPEN_FILES", this, &GPP_i::_fileThresholdCheck);
+ _fileThresholdMonitor->add_listener(this, &GPP_i::_fileThresholdStateChanged);
+ threshold_monitors.push_back(_fileThresholdMonitor);
+
+ _shmThresholdMonitor = boost::make_shared("shm", "SHM_FREE", this, &GPP_i::_shmThresholdCheck);
+ _shmThresholdMonitor->add_listener(this, &GPP_i::_shmThresholdStateChanged);
+ threshold_monitors.push_back(_shmThresholdMonitor);
}
-void
-GPP_i::addThresholdMonitor( ThresholdMonitorPtr t )
+//
+// Threshold policy and event handling
+//
+
+bool GPP_i::_cpuIdleThresholdCheck(ThresholdMonitor* monitor)
{
- t->attach_listener( boost::bind(&GPP_i::send_threshold_event, this, _1) );
- threshold_monitors.push_back( t );
+ double sys_idle = system_monitor->get_idle_percent();
+ double sys_idle_avg = system_monitor->get_idle_average();
+ RH_TRACE(_baseLog, "Update CPU idle threshold monitor, threshold=" << modified_thresholds.cpu_idle
+ << " current=" << sys_idle << " average=" << sys_idle_avg);
+ return (sys_idle < modified_thresholds.cpu_idle) && (sys_idle_avg < modified_thresholds.cpu_idle);
}
-void
-GPP_i::setShadowThresholds( const thresholds_struct &nv ) {
- if ( nv.cpu_idle >= 0.0 ) __thresholds.cpu_idle = nv.cpu_idle;
- if ( nv.load_avg >= 0.0 ) __thresholds.load_avg = nv.load_avg;
- if ( nv.mem_free >= 0 ) __thresholds.mem_free = nv.mem_free;
- if ( nv.nic_usage >= 0 ) __thresholds.nic_usage = nv.nic_usage;
- if ( nv.files_available >= 0.0 ) __thresholds.files_available = nv.files_available;
- if ( nv.threads >= 0.0 ) __thresholds.threads = nv.threads;
+void GPP_i::_cpuIdleThresholdStateChanged(ThresholdMonitor* monitor)
+{
+ _sendThresholdMessage(monitor, system_monitor->get_idle_percent(), modified_thresholds.cpu_idle);
+}
+
+bool GPP_i::_loadAvgThresholdCheck(ThresholdMonitor* monitor)
+{
+ double load_avg = system_monitor->get_loadavg();
+ RH_TRACE(_baseLog, "Update load average threshold monitor, threshold=" << modified_thresholds.load_avg
+ << " measured=" << load_avg);
+ return (load_avg > modified_thresholds.load_avg);
+}
+
+void GPP_i::_loadAvgThresholdStateChanged(ThresholdMonitor* monitor)
+{
+ _sendThresholdMessage(monitor, system_monitor->get_loadavg(), modified_thresholds.load_avg);
+}
+
+bool GPP_i::_freeMemThresholdCheck(ThresholdMonitor* monitor)
+{
+ int64_t mem_free = system_monitor->get_mem_free();
+ RH_TRACE(_baseLog, "Update free memory threshold monitor, threshold=" << modified_thresholds.mem_free
+ << " measured=" << mem_free);
+ return (mem_free < modified_thresholds.mem_free);
+}
+
+void GPP_i::_freeMemThresholdStateChanged(ThresholdMonitor* monitor)
+{
+ _sendThresholdMessage(monitor, system_monitor->get_mem_free(), modified_thresholds.mem_free);
+}
+
+bool GPP_i::_threadThresholdCheck(ThresholdMonitor* monitor)
+{
+ int gpp_max_threads = gpp_limits.max_threads * modified_thresholds.threads;
+ if (gpp_limits.max_threads != -1) {
+ RH_TRACE(_baseLog, "Update thread threshold monitor (GPP), threshold=" << gpp_max_threads
+ << " measured=" << gpp_limits.current_threads);
+ if (gpp_limits.current_threads > gpp_max_threads) {
+ return true;
+ }
+ }
+ int sys_max_threads = sys_limits.max_threads * modified_thresholds.threads;
+ if (sys_limits.max_threads != -1) {
+ RH_TRACE(_baseLog, "Update thread threshold monitor (system), threshold=" << sys_max_threads
+ << " measured=" << sys_limits.current_threads);
+ if (sys_limits.current_threads > sys_max_threads) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void GPP_i::_threadThresholdStateChanged(ThresholdMonitor* monitor)
+{
+ _sendThresholdMessage(monitor, gpp_limits.current_threads, gpp_limits.max_threads * modified_thresholds.threads);
+}
+
+bool GPP_i::_fileThresholdCheck(ThresholdMonitor* monitor)
+{
+ int gpp_max_open_files = gpp_limits.max_open_files * modified_thresholds.files_available;
+ int sys_max_open_files = sys_limits.max_open_files * modified_thresholds.files_available;
+ RH_TRACE(_baseLog, "Update file threshold monitor (GPP), threshold=" << gpp_max_open_files
+ << " measured=" << gpp_limits.current_open_files);
+ RH_TRACE(_baseLog, "Update file threshold monitor (system), threshold=" << sys_max_open_files
+ << " measured=" << sys_limits.current_open_files);
+ if (gpp_limits.current_open_files > gpp_max_open_files) {
+ return true;
+ } else if (sys_limits.current_open_files > sys_max_open_files) {
+ return true;
+ }
+ return false;
+}
+
+void GPP_i::_fileThresholdStateChanged(ThresholdMonitor* monitor)
+{
+ _sendThresholdMessage(monitor, gpp_limits.current_open_files,
+ gpp_limits.max_open_files * modified_thresholds.files_available);
+}
+
+bool GPP_i::_shmThresholdCheck(ThresholdMonitor* monitor)
+{
+ RH_TRACE(_baseLog, "Update shared memory threshold monitor, threshold=" << modified_thresholds.shm_free
+ << " measured=" << shmFree);
+ return shmFree < modified_thresholds.shm_free;
+}
+
+void GPP_i::_shmThresholdStateChanged(ThresholdMonitor* monitor)
+{
+ _sendThresholdMessage(monitor, shmFree, modified_thresholds.shm_free);
+}
+
+bool GPP_i::_nicThresholdCheck(ThresholdMonitor* monitor)
+{
+ const std::string& nic = monitor->get_resource_id();
+ float measured = nic_facade->get_throughput_by_device(nic);
+ RH_TRACE(_baseLog, "Update NIC threshold monitor " << nic
+ << " threshold=" << modified_thresholds.nic_usage
+ << " measured=" << measured);
+ return measured >= modified_thresholds.nic_usage;
+}
+
+void GPP_i::_nicThresholdStateChanged(ThresholdMonitor* monitor)
+{
+ std::string nic = monitor->get_resource_id();
+ float measured = nic_facade->get_throughput_by_device(nic);
+ _sendThresholdMessage(monitor, measured, modified_thresholds.nic_usage);
+}
+
+template
+void GPP_i::_sendThresholdMessage(ThresholdMonitor* monitor, const T1& measured, const T2& threshold)
+{
+ bool exceeded = monitor->is_threshold_exceeded();
+
+ threshold_event_struct message;
+ message.source_id = _identifier;
+ message.resource_id = monitor->get_resource_id();
+ message.threshold_class = monitor->get_threshold_class();
+ if (exceeded) {
+ message.type = enums::threshold_event::type::Threshold_Exceeded;
+ } else {
+ message.type = enums::threshold_event::type::Threshold_Not_Exceeded;
+ }
+ if (monitor->is_enabled()) {
+ message.threshold_value = boost::lexical_cast(threshold);
+ } else {
+ message.threshold_value = "";
+ }
+ message.measured_value = boost::lexical_cast(measured);
+
+ std::stringstream sstr;
+ sstr << message.threshold_class << " threshold ";
+ if (!exceeded) {
+ sstr << "not ";
+ }
+ sstr << "exceeded "
+ << "(resource_id=" << message.resource_id
+ << " threshold_value=" << message.threshold_value
+ << " measured_value=" << message.measured_value << ")";
+ message.message = sstr.str();
+
+ message.timestamp = time(NULL);
+
+ send_threshold_event(message);
}
//
@@ -860,7 +1075,7 @@ void GPP_i::initialize() throw (CF::LifeCycle::InitializeError, CORBA::SystemExc
odm_consumer = mymgr->Subscriber("ODM_Channel");
odm_consumer->setDataArrivedListener(this, &GPP_i::process_ODM);
} catch ( ... ) {
- LOG_WARN(GPP_i, "Unable to register with EventChannelManager, disabling domain event notification.");
+ RH_WARN(this->_baseLog, "Unable to register with EventChannelManager, disabling domain event notification.");
}
//
@@ -869,10 +1084,10 @@ void GPP_i::initialize() throw (CF::LifeCycle::InitializeError, CORBA::SystemExc
if ( componentOutputLog != "" ) {
_componentOutputLog =__ExpandEnvVars(componentOutputLog);
_handle_io_redirects = true;
- LOG_INFO(GPP_i, "Turning on Component Output Redirection file: " << _componentOutputLog );
+ RH_INFO(this->_baseLog, "Turning on Component Output Redirection file: " << _componentOutputLog );
}
else {
- LOG_INFO(GPP_i, "Component Output Redirection is DISABLED." << componentOutputLog );
+ RH_INFO(this->_baseLog, "Component Output Redirection is DISABLED." << componentOutputLog );
}
//
@@ -924,14 +1139,14 @@ void GPP_i::initialize() throw (CF::LifeCycle::InitializeError, CORBA::SystemExc
//
const SystemMonitor::Report &rpt = system_monitor->getReport();
- // thresholds can be individually disabled, use shadow thresholds for actual calculations and conditions
- setShadowThresholds( thresholds );
-
//
// load average attributes
//
loadTotal = loadCapacityPerCore * (float)processor_cores;
- loadCapacity = loadTotal * ((double)__thresholds.load_avg / 100.0);
+ loadCapacity = loadTotal;
+ if (!thresholds.ignore && thresholds.load_avg >= 0.0) {
+ loadCapacity *= thresholds.load_avg / 100.0;
+ }
loadFree = loadCapacity;
idle_capacity_modifier = 100.0 * reserved_capacity_per_component/((float)processor_cores);
@@ -940,19 +1155,25 @@ void GPP_i::initialize() throw (CF::LifeCycle::InitializeError, CORBA::SystemExc
//
memInitVirtFree=rpt.virtual_memory_free; // assume current state to be total available
int64_t init_mem_free = (int64_t) memInitVirtFree;
- memInitCapacityPercent = (double)( (int64_t)init_mem_free - (int64_t)(__thresholds.mem_free*thresh_mem_free_units) )/ (double)init_mem_free;
- if ( memInitCapacityPercent < 0.0 ) memInitCapacityPercent = 100.0;
+ if (!thresholds.ignore && thresholds.mem_free >= 0) {
+ memInitCapacityPercent = (double)( (int64_t)init_mem_free - (int64_t)(thresholds.mem_free*thresh_mem_free_units) )/ (double)init_mem_free;
+ if (memInitCapacityPercent < 0.0) {
+ memInitCapacityPercent = 100.0;
+ }
+ } else {
+ memInitCapacityPercent = 100.0;
+ }
memFree = init_mem_free / mem_free_units;
memCapacity = ((int64_t)( init_mem_free * memInitCapacityPercent)) / mem_cap_units ;
memCapacityThreshold = memCapacity;
+ shmFree = redhawk::shm::getSystemFreeMemory() / MB_TO_BYTES;
+
//
// set initial modified thresholds
//
modified_thresholds = thresholds;
- modified_thresholds.mem_free = __thresholds.mem_free*thresh_mem_free_units;
- modified_thresholds.load_avg = loadTotal * ( (double)__thresholds.load_avg / 100.0);
- modified_thresholds.cpu_idle = __thresholds.cpu_idle;
+ thresholds_changed(thresholds, thresholds);
loadAverage.onemin = rpt.load.one_min;
loadAverage.fivemin = rpt.load.five_min;
@@ -973,12 +1194,6 @@ void GPP_i::initialize() throw (CF::LifeCycle::InitializeError, CORBA::SystemExc
gpp_limits.current_open_files = pid_rpt.files;
gpp_limits.max_open_files = pid_rpt.files_limit;
- // enable monitors to push out state change events..
- MonitorSequence::iterator iter=threshold_monitors.begin();
- for( ; iter != threshold_monitors.end(); iter++ ) {
- if ( *iter ) (*iter)->enable_dispatch();
- }
-
//
// setup mcast interface allocations, used by older systems -- need to deprecate
//
@@ -1004,44 +1219,97 @@ void GPP_i::initialize() throw (CF::LifeCycle::InitializeError, CORBA::SystemExc
}
-void GPP_i::thresholds_changed(const thresholds_struct *ov, const thresholds_struct *nv) {
-
- if ( !(nv->mem_free < 0 ) && ov->mem_free != nv->mem_free ) {
- LOG_DEBUG(GPP_i, __FUNCTION__ << " THRESHOLDS.MEM_FREE CHANGED old/new " << ov->mem_free << "/" << nv->mem_free );
- WriteLock wlock(pidLock);
- int64_t init_mem_free = (int64_t) memInitVirtFree;
+void GPP_i::thresholds_changed(const thresholds_struct& ov, const thresholds_struct& nv)
+{
+ WriteLock wlock(monitorLock);
+ if (nv.ignore || (nv.mem_free < 0)) {
+ RH_DEBUG(_baseLog, __FUNCTION__ << " THRESHOLDS.MEM_FREE DISABLED");
+ modified_thresholds.mem_free = 0;
+ _freeMemThresholdMonitor->disable();
+ } else {
+ if (ov.mem_free != nv.mem_free) {
+ RH_DEBUG(_baseLog, __FUNCTION__ << " THRESHOLDS.MEM_FREE CHANGED old/new " << ov.mem_free << "/" << nv.mem_free);
+ }
+ int64_t init_mem_free = (int64_t) memInitVirtFree;
// type cast required for correct calc on 32bit os
- memInitCapacityPercent = (double)( (int64_t)init_mem_free - (int64_t)(nv->mem_free*thresh_mem_free_units) )/ (double) init_mem_free;
+ memInitCapacityPercent = (double)( (int64_t)init_mem_free - (int64_t)(nv.mem_free*thresh_mem_free_units) )/ (double) init_mem_free;
if ( memInitCapacityPercent < 0.0 ) memInitCapacityPercent = 100.0;
- memCapacity = ((int64_t)( init_mem_free * memInitCapacityPercent) ) / mem_cap_units ;
+ memCapacity = ((int64_t)( init_mem_free * memInitCapacityPercent) ) / mem_cap_units;
memCapacityThreshold = memCapacity;
- modified_thresholds.mem_free = nv->mem_free*thresh_mem_free_units;
+ modified_thresholds.mem_free = nv.mem_free*thresh_mem_free_units;
+ _freeMemThresholdMonitor->enable();
}
-
- if ( !(nv->load_avg < 0.0) && !(fabs(ov->load_avg - nv->load_avg ) < std::numeric_limits::epsilon()) ) {
- LOG_DEBUG(GPP_i, __FUNCTION__ << " THRESHOLDS.LOAD_AVG CHANGED old/new " << ov->load_avg << "/" << nv->load_avg );
- WriteLock wlock(pidLock);
- loadCapacity = loadTotal * ((double)nv->load_avg / 100.0);
+ if (nv.ignore || (nv.load_avg < 0.0)) {
+ RH_DEBUG(_baseLog, __FUNCTION__ << " THRESHOLDS.LOAD_AVG DISABLED");
+ modified_thresholds.load_avg = loadTotal;
+ _loadAvgThresholdMonitor->disable();
+ } else {
+ if (fabs(ov.load_avg - nv.load_avg) >= std::numeric_limits::epsilon()) {
+ RH_DEBUG(_baseLog, __FUNCTION__ << " THRESHOLDS.LOAD_AVG CHANGED old/new " << ov.load_avg << "/" << nv.load_avg);
+ }
+ loadCapacity = loadTotal * ((double)nv.load_avg / 100.0);
loadFree = loadCapacity;
- modified_thresholds.load_avg = loadTotal * ( (double)nv->load_avg / 100.0);
+ modified_thresholds.load_avg = loadTotal * ( (double)nv.load_avg / 100.0);
+ _loadAvgThresholdMonitor->enable();
}
- if ( !(nv->cpu_idle < 0.0) && !(fabs(ov->cpu_idle - nv->cpu_idle ) < std::numeric_limits::epsilon())) {
- LOG_DEBUG(GPP_i, __FUNCTION__ << " THRESHOLDS.CPU_IDLE CHANGED old/new " << ov->cpu_idle << "/" << nv->cpu_idle );
- WriteLock wlock(pidLock);
- modified_thresholds.cpu_idle = nv->cpu_idle;
+ if (nv.ignore || (nv.cpu_idle < 0.0)) {
+ RH_DEBUG(_baseLog, __FUNCTION__ << " THRESHOLDS.CPU_IDLE DISABLED");
+ modified_thresholds.cpu_idle = 0.0;
+ _cpuIdleThresholdMonitor->disable();
+ } else {
+ if (fabs(ov.cpu_idle - nv.cpu_idle) >= std::numeric_limits::epsilon()) {
+ RH_DEBUG(_baseLog, __FUNCTION__ << " THRESHOLDS.CPU_IDLE CHANGED old/new " << ov.cpu_idle << "/" << nv.cpu_idle);
+ }
+ modified_thresholds.cpu_idle = nv.cpu_idle;
+ _cpuIdleThresholdMonitor->enable();
}
+ if (nv.ignore || (nv.nic_usage < 0)) {
+ RH_DEBUG(_baseLog, __FUNCTION__ << " THRESHOLDS.NIC_USAGE DISABLED");
+ _allNicsThresholdMonitor->disable();
+ } else {
+ if (ov.nic_usage != nv.nic_usage) {
+ RH_DEBUG(_baseLog, __FUNCTION__ << " THRESHOLDS.NIC_USAGE CHANGED old/new " << ov.nic_usage << "/" << nv.nic_usage);
+ }
+ modified_thresholds.nic_usage = nv.nic_usage;
+ _allNicsThresholdMonitor->enable();
+ }
- if ( !(nv->nic_usage < 0) && !(fabs(ov->nic_usage - nv->nic_usage ) < std::numeric_limits::epsilon())) {
- LOG_DEBUG(GPP_i, __FUNCTION__ << " THRESHOLDS.NIC_USAGE CHANGED old/new " << ov->nic_usage << "/" << nv->nic_usage );
- WriteLock wlock(monitorLock);
- modified_thresholds.nic_usage = nv->nic_usage;
+ if (nv.ignore || (nv.shm_free < 0)) {
+ RH_DEBUG(_baseLog, __FUNCTION__ << " THRESHOLDS.SHM_FREE DISABLED");
+ _shmThresholdMonitor->disable();
+ } else {
+ if (ov.shm_free != nv.shm_free) {
+ RH_DEBUG(_baseLog, __FUNCTION__ << " THRESHOLDS.SHM_FREE CHANGED old/new "
+ << ov.shm_free << "/" << nv.shm_free);
+ }
+ modified_thresholds.shm_free = nv.shm_free;
+ _shmThresholdMonitor->enable();
}
- setShadowThresholds( *nv );
+ if (nv.ignore || (nv.threads < 0.0)) {
+ RH_DEBUG(_baseLog, __FUNCTION__ << " THRESHOLDS.THREADS DISABLED");
+ _threadThresholdMonitor->disable();
+ } else {
+ if (fabs(ov.threads - nv.threads) >= std::numeric_limits::epsilon()) {
+ RH_DEBUG(_baseLog, __FUNCTION__ << " THRESHOLDS.THREADS CHANGED old/new " << ov.threads << "/" << nv.threads);
+ }
+ modified_thresholds.threads = 1.0 - (nv.threads * .01);
+ _threadThresholdMonitor->enable();
+ }
+ if (nv.ignore || (nv.files_available < 0.0)) {
+ RH_DEBUG(_baseLog, __FUNCTION__ << " THRESHOLDS.FILES_AVAILABLE DISABLED");
+ _fileThresholdMonitor->disable();
+ } else {
+ if (fabs(ov.files_available - nv.files_available) >= std::numeric_limits::epsilon()) {
+ RH_DEBUG(_baseLog, __FUNCTION__ << " THRESHOLDS.FILES_AVAILABLE CHANGED old/new " << ov.files_available << "/" << nv.files_available);
+ }
+ modified_thresholds.files_available = 1.0 - (nv.files_available * .01);
+ _fileThresholdMonitor->enable();
+ }
}
void GPP_i::releaseObject() throw (CORBA::SystemException, CF::LifeCycle::ReleaseError) {
@@ -1060,7 +1328,6 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::execute (const char* name, const CF:
CF::ExecutableDevice::InvalidParameters, CF::ExecutableDevice::InvalidOptions,
CF::InvalidFileName, CF::ExecutableDevice::ExecuteFail)
{
-
boost::recursive_mutex::scoped_lock lock;
try
{
@@ -1070,47 +1337,46 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::execute (const char* name, const CF:
{
std::stringstream errstr;
errstr << "Error acquiring lock (errno=" << e.native_error() << " msg=\"" << e.what() << "\")";
- LOG_ERROR(GPP_i, __FUNCTION__ << ": " << errstr.str() );
+ RH_ERROR(this->_baseLog, __FUNCTION__ << ": " << errstr.str() );
throw CF::Device::InvalidState(errstr.str().c_str());
}
- std::vector prepend_args;
- std::string naming_context_ior;
- CF::Properties variable_parameters;
- variable_parameters = parameters;
- redhawk::PropertyMap& tmp_params = redhawk::PropertyMap::cast(variable_parameters);
+ redhawk::PropertyMap tmp_params(parameters);
float reservation_value = -1;
if (tmp_params.find("RH::GPP::MODIFIED_CPU_RESERVATION_VALUE") != tmp_params.end()) {
- double reservation_value_d;
- if (!tmp_params["RH::GPP::MODIFIED_CPU_RESERVATION_VALUE"].getValue(reservation_value)) {
- if (tmp_params["RH::GPP::MODIFIED_CPU_RESERVATION_VALUE"].getValue(reservation_value_d)) {
- reservation_value = reservation_value_d;
- } else {
- reservation_value = -1;
- }
+ try {
+ reservation_value = tmp_params["RH::GPP::MODIFIED_CPU_RESERVATION_VALUE"].toFloat();
+ } catch (const std::exception&) {
+ reservation_value = -1;
}
tmp_params.erase("RH::GPP::MODIFIED_CPU_RESERVATION_VALUE");
}
- naming_context_ior = tmp_params["NAMING_CONTEXT_IOR"].toString();
+
+ std::string component_id = tmp_params.get("COMPONENT_IDENTIFIER", std::string()).toString();
+ if (applicationReservations.find(component_id) != applicationReservations.end()) {
+ applicationReservations.erase(component_id);
+ }
+
+ std::string naming_context_ior = tmp_params.get("NAMING_CONTEXT_IOR", std::string()).toString();
std::string app_id;
- std::string component_id = tmp_params["COMPONENT_IDENTIFIER"].toString();
- std::string name_binding = tmp_params["NAME_BINDING"].toString();
- CF::Application_var _app = CF::Application::_nil();
- CORBA::Object_var obj = ossie::corba::Orb()->string_to_object(naming_context_ior.c_str());
- if (CORBA::is_nil(obj)) {
- LOG_WARN(GPP_i, "Invalid application registrar IOR");
- } else {
- CF::ApplicationRegistrar_var _appRegistrar = CF::ApplicationRegistrar::_nil();
- _appRegistrar = CF::ApplicationRegistrar::_narrow(obj);
- if (CORBA::is_nil(_appRegistrar)) {
- LOG_WARN(GPP_i, "Invalid application registrar IOR");
+ if (!naming_context_ior.empty()) {
+ CORBA::Object_var obj = ossie::corba::Orb()->string_to_object(naming_context_ior.c_str());
+ if (CORBA::is_nil(obj)) {
+ RH_WARN(_baseLog, "Invalid application registrar IOR");
} else {
- _app = _appRegistrar->app();
- if (not CORBA::is_nil(_app)) {
- app_id = ossie::corba::returnString(_app->identifier());
+ CF::ApplicationRegistrar_var app_registrar = CF::ApplicationRegistrar::_narrow(obj);
+ if (CORBA::is_nil(app_registrar)) {
+ RH_WARN(_baseLog, "Invalid application registrar IOR");
+ } else {
+ CF::Application_var application = app_registrar->app();
+ if (!CORBA::is_nil(application)) {
+ app_id = ossie::corba::returnString(application->identifier());
+ }
}
}
}
+
+ std::vector prepend_args;
if (useScreen) {
std::string ld_lib_path(getenv("LD_LIBRARY_PATH"));
setenv("GPP_LD_LIBRARY_PATH",ld_lib_path.c_str(),1);
@@ -1146,6 +1412,8 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::execute (const char* name, const CF:
prepend_args.push_back("-m");
prepend_args.push_back("-c");
prepend_args.push_back(binary_location+"gpp.screenrc");
+
+ std::string name_binding = tmp_params.get("NAME_BINDING", std::string()).toString();
if ((not component_id.empty()) and (not name_binding.empty())) {
if (component_id.find("DCE:") != std::string::npos) {
component_id = component_id.substr(4, std::string::npos);
@@ -1160,6 +1428,60 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::execute (const char* name, const CF:
prepend_args.push_back(waveform_name+"."+name_binding);
}
}
+ bool useDocker = false;
+ if (tmp_params.find("__DOCKER_IMAGE__") != tmp_params.end()) {
+ std::string image_name = tmp_params["__DOCKER_IMAGE__"].toString();
+ LOG_DEBUG(GPP_i, __FUNCTION__ << "Component specified a Docker image: " << image_name);
+ std::string target = GPP_i::find_exec("docker");
+ if(!target.empty()) {
+ char buffer[128];
+ std::string result = "";
+ std::string docker_query = target + " image -q " + image_name;
+ FILE* pipe = popen(docker_query.c_str(), "r");
+ if (!pipe)
+ throw CF::ExecutableDevice::ExecuteFail(CF::CF_EINVAL, "Could not run popen");
+ try {
+ while (!feof(pipe)) {
+ if (fgets(buffer, 128, pipe) != NULL) {
+ result += buffer;
+ }
+ }
+ } catch (...) {
+ pclose(pipe);
+ throw;
+ }
+ pclose(pipe);
+ if (result.empty()) {
+ CF::Properties invalidParameters;
+ invalidParameters.length(invalidaParameters.length() + 1);
+ invalidParameters[invalidParameters.length() -1].id = "__DOCKER_IMAGE__";
+ invalidParameters[invalidParameters.length() -1].value <<= image_name.c_str();
+ throw CF::ExecutableDevice::InvalidParameters(invalidParameters);
+ }
+ std::string container_name(component_id);
+ std::replace(container_name.begin(), container_name.end(), ':', '-');
+ prepend_args.push_back(target);
+ prepend_args.push_back("run");
+ prepend_args.push_back("--sig-proxy=true");
+ prepend_args.push_back("--rm");
+ prepend_args.push_back("--name");
+ prepend_args.push_back(container_name);
+ prepend_args.push_back("--net=host");
+ prepend_args.push_back("-v");
+ prepend_args.push_back(docker_omniorb_cfg+":/etc/omniORB.cfg");
+ if ( tmp_params.find("__DOCKER_ARGS__") != tmp_params.end()) {
+ std::string docker_args_raw = tmp_params["__DOCKER_ARGS__"].toString();
+ std::vector docker_args;
+ boost::split(docker_args, docker_args_raw, boost::is_any_of(" "));
+ BOOST_FOREACH( const std::string& arg, docker_args) {
+ prepend_args.push_back(arg);
+ }
+ }
+ prepend_args.push_back(image_name);
+ LOG_DEBUG(GPP_i, __FUNCTION__ << "Component will launch within a Docker container using this image: " << image_name);
+ useDocker = true;
+ }
+ }
CF::ExecutableDevice::ProcessID_Type ret_pid;
try {
ret_pid = do_execute(name, options, tmp_params, prepend_args);
@@ -1200,7 +1522,7 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::do_execute (const char* name, const
invalidOptions[invalidOptions.length() - 1].value
= options[i].value;
} else
- LOG_WARN(GPP_i, "Received a PRIORITY_ID execute option...ignoring.")
+ RH_WARN(this->_baseLog, "Received a PRIORITY_ID execute option...ignoring.")
}
if (options[i].id == CF::ExecutableDevice::STACK_SIZE_ID) {
CORBA::TypeCode_var atype = options[i].value.type();
@@ -1210,7 +1532,7 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::do_execute (const char* name, const
invalidOptions[invalidOptions.length() - 1].value
= options[i].value;
} else
- LOG_WARN(GPP_i, "Received a STACK_SIZE_ID execute option...ignoring.")
+ RH_WARN(this->_baseLog, "Received a STACK_SIZE_ID execute option...ignoring.")
}
}
@@ -1219,10 +1541,17 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::do_execute (const char* name, const
}
// retrieve current working directory
- tmp = getcwd(NULL, 200);
- if (tmp != NULL) {
- path = std::string(tmp);
- free(tmp);
+ if (this->cacheDirectory.empty()) {
+ tmp = getcwd(NULL, 200);
+ if (tmp != NULL) {
+ path = std::string(tmp);
+ free(tmp);
+ }
+ } else {
+ path = this->cacheDirectory;
+ if (!path.compare(path.length()-1, 1, "/")) {
+ path = path.erase(path.length()-1);
+ }
}
// append relative path of the executable
@@ -1237,7 +1566,7 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::do_execute (const char* name, const
// change permissions to 7--
if (chmod(path.c_str(), S_IRWXU) != 0) {
- LOG_ERROR(GPP_i, "Unable to change permission on executable");
+ RH_ERROR(this->_baseLog, "Unable to change permission on executable");
throw CF::ExecutableDevice::ExecuteFail(CF::CF_EACCES,
"Unable to change permission on executable");
}
@@ -1264,15 +1593,15 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::do_execute (const char* name, const
}
args.push_back(path);
- LOG_DEBUG(GPP_i, "Building param list for process " << path);
+ RH_DEBUG(this->_baseLog, "Building param list for process " << path);
for (CORBA::ULong i = 0; i < parameters.length(); ++i) {
- LOG_DEBUG(GPP_i, "id=" << ossie::corba::returnString(parameters[i].id) << " value=" << ossie::any_to_string(parameters[i].value));
+ RH_DEBUG(this->_baseLog, "id=" << ossie::corba::returnString(parameters[i].id) << " value=" << ossie::any_to_string(parameters[i].value));
CORBA::TypeCode_var atype = parameters[i].value.type();
args.push_back(ossie::corba::returnString(parameters[i].id));
args.push_back(ossie::any_to_string(parameters[i].value));
}
- LOG_DEBUG(GPP_i, "Forking process " << path);
+ RH_DEBUG(this->_baseLog, "Forking process " << path);
std::vector argv(args.size() + 1, NULL);
for (std::size_t i = 0; i < args.size(); ++i) {
@@ -1285,17 +1614,31 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::do_execute (const char* name, const
// setup to capture stdout and stderr from children.
int comp_fd[2];
+ std::string rfname;
if ( _handle_io_redirects ) {
- if ( pipe( comp_fd ) == -1 ) {
- LOG_ERROR(GPP_i, "Failure to create redirected IO for:" << path);
- throw CF::ExecutableDevice::ExecuteFail(CF::CF_EPERM, "Failure to create redirected IO for component");
- }
+ rfname=__ExpandEnvVars(componentOutputLog);
+ rfname=__ExpandProperties(rfname, parameters );
+ if ( rfname == _componentOutputLog ) {
+ RH_TRACE(this->_baseLog, "Redirect to common file for :" << path << " file: " << rfname );
+ if ( pipe( comp_fd ) == -1 ) {
+ RH_ERROR(this->_baseLog, "Failure to create redirected IO for:" << path);
+ throw CF::ExecutableDevice::ExecuteFail(CF::CF_EPERM, "Failure to create redirected IO for component");
+ }
- if ( fcntl( comp_fd[0], F_SETFD, FD_CLOEXEC ) == -1 ) {
- LOG_ERROR(GPP_i, "Failure to support redirected IO for:" << path);
- throw CF::ExecutableDevice::ExecuteFail(CF::CF_EPERM, "Failure to support redirected IO for component");
- }
-
+ if ( fcntl( comp_fd[0], F_SETFD, FD_CLOEXEC ) == -1 ) {
+ RH_ERROR(this->_baseLog, "Failure to support redirected IO for:" << path);
+ throw CF::ExecutableDevice::ExecuteFail(CF::CF_EPERM, "Failure to support redirected IO for component");
+ }
+ }
+ else { // per process logging
+ RH_TRACE(this->_baseLog, "Redirect per process for :" << path << " file: " << rfname );
+ comp_fd[0]=-1;
+ comp_fd[1] = open(rfname.c_str(), O_RDWR | O_CREAT | O_APPEND , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
+ if ( comp_fd[1] == -1 ) {
+ RH_ERROR(this->_baseLog, "Failure to create redirected IO for:" << path);
+ throw CF::ExecutableDevice::ExecuteFail(CF::CF_EPERM, "Failure to create redirected IO for component");
+ }
+ }
}
// fork child process
@@ -1356,7 +1699,7 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::do_execute (const char* name, const
exit(-1);
}
- close(comp_fd[0]);
+ if ( comp_fd[0] != -1 ) close(comp_fd[0]);
close(comp_fd[1]);
}
@@ -1389,7 +1732,7 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::do_execute (const char* name, const
exit(returnval);
}
else if (pid < 0 ){
- LOG_ERROR(GPP_i, "Error forking child process (errno: " << errno << " msg=\"" << strerror(errno) << "\")" );
+ RH_ERROR(this->_baseLog, "Error forking child process (errno: " << errno << " msg=\"" << strerror(errno) << "\")" );
switch (errno) {
case E2BIG:
throw CF::ExecutableDevice::ExecuteFail(CF::CF_E2BIG,
@@ -1423,16 +1766,20 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::do_execute (const char* name, const
if ( _handle_io_redirects ) {
close(comp_fd[1]);
- LOG_TRACE(GPP_i, "Adding Task for IO Redirection PID:" << pid << " : stdout "<< comp_fd[0] );
+ RH_TRACE(this->_baseLog, "Adding Task for IO Redirection PID:" << pid << " : stdout "<< comp_fd[0] );
WriteLock wlock(fdsLock);
- // trans form file name if contains env or exec param expansion
- std::string rfname=__ExpandEnvVars(componentOutputLog);
- rfname=__ExpandProperties(rfname, parameters );
- redirectedFds.push_front( proc_redirect( rfname, pid, comp_fd[0] ) );
+ if ( comp_fd[0] != -1 ) {
+ ProcRedirectPtr rd = ProcRedirectPtr( new proc_redirect( rfname, pid, comp_fd[0] ) );
+ redirectedFds.push_front( rd );
+ epoll_event event;
+ event.data.ptr = (void*)(rd.get());
+ event.events = EPOLLIN;
+ int ret __attribute__((unused)) = epoll_ctl (epfd, EPOLL_CTL_ADD, comp_fd[0], &event);
+ }
}
- LOG_DEBUG(GPP_i, "Execute success: name:" << name << " : "<< path);
+ RH_DEBUG(this->_baseLog, "Execute success: name:" << name << " : "<< path);
return pid;
}
@@ -1440,8 +1787,7 @@ CF::ExecutableDevice::ProcessID_Type GPP_i::do_execute (const char* name, const
void GPP_i::terminate (CF::ExecutableDevice::ProcessID_Type processId) throw (CORBA::SystemException, CF::ExecutableDevice::InvalidProcess, CF::Device::InvalidState)
{
- LOG_TRACE(GPP_i, " Terminate request, processID: " << processId);
- component_description comp;
+ RH_TRACE(this->_baseLog, " Terminate request, processID: " << processId);
try {
markPidTerminated( processId );
ExecutableDevice_impl::terminate(processId);
@@ -1451,116 +1797,36 @@ void GPP_i::terminate (CF::ExecutableDevice::ProcessID_Type processId) throw (CO
removeProcess(processId);
}
-bool GPP_i::_component_cleanup( const int child_pid, const int exit_status ) {
-
-
- bool ret=false;
- component_description comp;
- try {
- comp = getComponentDescription(child_pid);
- ret=true;
- if ( !comp.terminated ) {
- // release of component can exit process before terminate is called
- if ( WIFEXITED(exit_status) == 0 ) {
- LOG_ERROR(GPP_i, " Unexpected Component Failure, App/Identifier/Process: " <<
- comp.appName << "/" << comp.identifier << "/" << comp.terminated << "/" << child_pid <<
- " STATUS==" << WIFEXITED(exit_status) << "," << WEXITSTATUS(exit_status) <<
- "," <get_threshold_value();
- actual += monitor->get_measured_value();
-
- LOG_TRACE(GPP_i, __FUNCTION__ << ": NicThreshold: " << monitor->get_resource_id() << " exceeded " << monitor->is_threshold_exceeded() << " threshold=" << monitor->get_threshold() << " measured=" << monitor->get_measured());
- if ( monitor->is_threshold_exceeded() ) nic_exceeded++;
- }
-
- if ( nic_monitors.size() != 0 && nic_monitors.size() == nic_exceeded ) {
- std::ostringstream oss;
- oss << "Threshold (cumulative) : " << threshold << " Actual (cumulative) : " << actual;
- _setReason( "NIC USAGE ", oss.str() );
- retval = true;
- }
-
- return retval;
-}
-
-bool GPP_i::_check_thread_limits( const thresholds_struct &thresholds)
-{
- float _tthreshold = 1 - __thresholds.threads * .01;
-
- if (gpp_limits.max_threads != -1) {
- //
- // check current process limits
- //
- LOG_TRACE(GPP_i, "_gpp_check_limits threads (cur/max): " << gpp_limits.current_threads << "/" << gpp_limits.max_threads );
- if (gpp_limits.current_threads>(gpp_limits.max_threads*_tthreshold)) {
- LOG_WARN(GPP_i, "GPP process thread limit threshold exceeded, count/threshold: " << gpp_limits.current_threads << "/" << (gpp_limits.max_threads*_tthreshold) );
- return true;
- }
+ component_description comp;
+ try {
+ comp = getComponentDescription(pid);
+ } catch (...) {
+ // pass.. could be a pid from and popen or system commands..
+ return false;
}
- if ( sys_limits.max_threads != -1 ) {
- //
- // check current system limits
- //
- LOG_TRACE(GPP_i, "_sys_check_limits threads (cur/max): " << sys_limits.current_threads << "/" << sys_limits.max_threads );
- if (sys_limits.current_threads>( sys_limits.max_threads *_tthreshold)) {
- LOG_WARN(GPP_i, "SYSTEM thread limit threshold exceeded, count/threshold: " << sys_limits.current_threads << "/" << (sys_limits.max_threads*_tthreshold) );
- return true;
- }
+ if (!comp.terminated) {
+ // release of component can exit process before terminate is called
+ if (WIFEXITED(status) && (WEXITSTATUS(status) != 0)) {
+ RH_ERROR(this->_baseLog, "Unexpected component exit with non-zero status " << WEXITSTATUS(status)
+ << ", App/Identifier/Process: " << comp.appName << "/" << comp.identifier << "/" << pid);
+ sendChildNotification(comp.identifier, comp.appName);
+ } else if (WIFSIGNALED(status)) {
+ RH_ERROR(this->_baseLog, "Unexepected component termination with signal " << WTERMSIG(status)
+ << ", App/Identifier/Process: " << comp.appName << "/" << comp.identifier << "/" << pid);
+ sendChildNotification(comp.identifier, comp.appName);
+ }
}
- return false;
-}
-bool GPP_i::_check_file_limits( const thresholds_struct &thresholds)
-{
- float _fthreshold = 1 - __thresholds.files_available * .01;
+ removeProcess(pid);
- if (gpp_limits.max_open_files != -1) {
- //
- // check current process limits
- //
- LOG_TRACE(GPP_i, "_gpp_check_limits threads (cur/max): " << gpp_limits.current_open_files << "/" << gpp_limits.max_open_files );
- if (gpp_limits.current_open_files>(gpp_limits.max_open_files*_fthreshold)) {
- LOG_WARN(GPP_i, "GPP process thread limit threshold exceeded, count/threshold: " << gpp_limits.current_open_files << "/" << (gpp_limits.max_open_files*_fthreshold) );
- return true;
- }
- }
+ // Ensure that if the process created a shared memory heap, it gets removed
+ // to avoid wasting shared memory
+ _cleanupProcessShm(pid);
- if ( sys_limits.max_open_files != -1 ) {
- //
- // check current system limits
- //
- LOG_TRACE(GPP_i, "_sys_check_limits threads (cur/max): " << sys_limits.current_open_files << "/" << sys_limits.max_open_files );
- if (sys_limits.current_open_files>( sys_limits.max_open_files *_fthreshold)) {
- LOG_WARN(GPP_i, "SYSTEM thread limit threshold exceeded, count/threshold: " << sys_limits.current_open_files << "/" << (sys_limits.max_open_files*_fthreshold) );
- return true;
- }
- }
- return false;
+ return true;
}
@@ -1572,6 +1838,21 @@ bool GPP_i::_check_file_limits( const thresholds_struct &thresholds)
void GPP_i::updateUsageState()
{
+ // allow for global ignore of thresholds
+ if ( thresholds.ignore == true ) {
+ _resetBusyReason();
+ RH_TRACE(_baseLog, "Ignoring threshold checks ");
+ if (getPids().size() == 0) {
+ RH_TRACE(_baseLog, "Usage State IDLE (trigger) pids === 0... ");
+ setUsageState(CF::Device::IDLE);
+ }
+ else {
+ RH_TRACE(_baseLog, "Usage State ACTIVE..... ");
+ setUsageState(CF::Device::ACTIVE);
+ }
+ return;
+ }
+
double sys_idle = system_monitor->get_idle_percent();
double sys_idle_avg = system_monitor->get_idle_average();
double sys_load = system_monitor->get_loadavg();
@@ -1581,122 +1862,117 @@ void GPP_i::updateUsageState()
double max_allowable_load = utilization[0].maximum;
double subscribed = utilization[0].subscribed;
-
- {
- std::stringstream oss;
- ReadLock rlock(monitorLock);
- NicMonitorSequence::iterator iter=nic_monitors.begin();
- for( ; iter != nic_monitors.end(); iter++ ) {
- NicMonitorPtr m = *iter;
- oss << " Nic: " << m->get_resource_id() << " exceeded " << m->is_threshold_exceeded() << " threshold=" << m->get_threshold() << " measured=" << m->get_measured() << std::endl;
- }
-
- LOG_DEBUG(GPP_i, "USAGE STATE: " << std::endl <<
- " CPU: threshold " << modified_thresholds.cpu_idle << " Actual: " << sys_idle << " Avg: " << sys_idle_avg << std::endl <<
- " MEM: threshold " << modified_thresholds.mem_free << " Actual: " << mem_free << std::endl <<
- " LOAD: threshold " << modified_thresholds.load_avg << " Actual: " << sys_load << std::endl <<
- " RESRV: threshold " << max_allowable_load << " Actual: " << subscribed << std::endl <<
- " Ingress threshold: " << mcastnicIngressThresholdValue << " capacity: " << mcastnicIngressCapacity << std::endl <<
- " Egress threshold: " << mcastnicEgressThresholdValue << " capacity: " << mcastnicEgressCapacity << std::endl <<
- " Threads threshold: " << gpp_limits.max_threads << " Actual: " << gpp_limits.current_threads << std::endl <<
- " NIC: " << std::endl << oss.str()
- );
- }
+ uint64_t all_nics_threshold = 0;
+ double all_nics_throughput = 0.0;
+
+ ReadLock rlock(monitorLock);
+
+ std::stringstream nic_message;
+ std::vector filtered_nics = nic_facade->get_filtered_devices();
+ for (size_t index = 0; index < filtered_nics.size(); ++index) {
+ const std::string& nic = filtered_nics[index];
+ double throughput = nic_facade->get_throughput_by_device(nic);
+ nic_message << " Nic: " << nic
+ << " threshold=" << modified_thresholds.nic_usage
+ << " measured=" << throughput << std::endl;
+
+ all_nics_threshold += modified_thresholds.nic_usage;
+ all_nics_throughput += throughput;
+ }
+
+ RH_TRACE(_baseLog, "USAGE STATE: " << std::endl <<
+ " CPU: threshold " << modified_thresholds.cpu_idle << " Actual: " << sys_idle << " Avg: " << sys_idle_avg << std::endl <<
+ " MEM: threshold " << modified_thresholds.mem_free << " Actual: " << mem_free << std::endl <<
+ " LOAD: threshold " << modified_thresholds.load_avg << " Actual: " << sys_load << std::endl <<
+ " RESRV: threshold " << max_allowable_load << " Actual: " << subscribed << std::endl <<
+ " Ingress threshold: " << mcastnicIngressThresholdValue << " capacity: " << mcastnicIngressCapacity << std::endl <<
+ " Egress threshold: " << mcastnicEgressThresholdValue << " capacity: " << mcastnicEgressCapacity << std::endl <<
+ " Threads threshold: " << gpp_limits.max_threads << " Actual: " << gpp_limits.current_threads << std::endl <<
+ " NIC: " << std::endl << nic_message.str()
+ );
- if (!(thresholds.cpu_idle < 0) && !(thresholds.load_avg < 0)) {
- if (sys_idle < modified_thresholds.cpu_idle) {
- if ( sys_idle_avg < modified_thresholds.cpu_idle) {
- std::ostringstream oss;
- oss << "Threshold: " << modified_thresholds.cpu_idle << " Actual/Average: " << sys_idle << "/" << sys_idle_avg ;
- _setReason( "CPU IDLE", oss.str() );
- setUsageState(CF::Device::BUSY);
- return;
- }
- }
+ if (_cpuIdleThresholdMonitor->is_threshold_exceeded()) {
+ std::ostringstream oss;
+ oss << "Threshold: " << modified_thresholds.cpu_idle << " Actual/Average: " << sys_idle << "/" << sys_idle_avg ;
+ _setBusyReason("CPU IDLE", oss.str());
}
-
- if ( !(thresholds.mem_free < 0) && (mem_free < modified_thresholds.mem_free)) {
- std::ostringstream oss;
- oss << "Threshold: " << modified_thresholds.mem_free << " Actual: " << mem_free;
- _setReason( "FREE MEMORY", oss.str() );
- setUsageState(CF::Device::BUSY);
+ else if (_freeMemThresholdMonitor->is_threshold_exceeded()) {
+ std::ostringstream oss;
+ oss << "Threshold: " << modified_thresholds.mem_free << " Actual: " << mem_free;
+ _setBusyReason("FREE MEMORY", oss.str());
}
-
- else if ( !(thresholds.cpu_idle < 0) && !(thresholds.load_avg < 0) && ( sys_load > modified_thresholds.load_avg )) {
+ else if (_loadAvgThresholdMonitor->is_threshold_exceeded()) {
std::ostringstream oss;
oss << "Threshold: " << modified_thresholds.load_avg << " Actual: " << sys_load;
- _setReason( "LOAD AVG", oss.str() );
- setUsageState(CF::Device::BUSY);
+ _setBusyReason("LOAD AVG", oss.str());
}
- else if ( reserved_capacity_per_component != 0 && (subscribed > max_allowable_load) ) {
+ else if ((reserved_capacity_per_component != 0) && (subscribed > max_allowable_load)) {
std::ostringstream oss;
oss << "Threshold: " << max_allowable_load << " Actual(subscribed) " << subscribed;
- _setReason( "RESERVATION CAPACITY", oss.str() );
- setUsageState(CF::Device::BUSY);
+ _setBusyReason("RESERVATION CAPACITY", oss.str());
}
- else if ( !(thresholds.nic_usage < 0) && _check_nic_thresholds() ) {
- setUsageState(CF::Device::BUSY);
+ else if (_shmThresholdMonitor->is_threshold_exceeded()) {
+ std::ostringstream oss;
+ oss << "Threshold: " << modified_thresholds.shm_free << " Actual: " << shmFree;
+ _setBusyReason("SHARED MEMORY", oss.str());
+ }
+ else if (_allNicsThresholdMonitor->is_threshold_exceeded()) {
+ std::ostringstream oss;
+ oss << "Threshold (cumulative) : " << all_nics_threshold << " Actual (cumulative) : " << all_nics_throughput;
+ _setBusyReason("NIC USAGE ", oss.str());
}
- else if (!(thresholds.threads < 0) && _check_thread_limits(thresholds)) {
+ else if (_threadThresholdMonitor->is_threshold_exceeded()) {
std::ostringstream oss;
oss << "Threshold: " << gpp_limits.max_threads << " Actual: " << gpp_limits.current_threads;
- _setReason( "ULIMIT (MAX_THREADS)", oss.str() );
- setUsageState(CF::Device::BUSY);
+ _setBusyReason("ULIMIT (MAX_THREADS)", oss.str());
}
- else if (!(thresholds.files_available < 0) && _check_file_limits(thresholds)) {
+ else if (_fileThresholdMonitor->is_threshold_exceeded()) {
std::ostringstream oss;
oss << "Threshold: " << gpp_limits.max_open_files << " Actual: " << gpp_limits.current_open_files;
- _setReason( "ULIMIT (MAX_FILES)", oss.str() );
- setUsageState(CF::Device::BUSY);
+ _setBusyReason("ULIMIT (MAX_FILES)", oss.str());
}
else if (getPids().size() == 0) {
- LOG_TRACE(GPP_i, "Usage State IDLE (trigger) pids === 0... ");
- _resetReason();
+ RH_TRACE(_baseLog, "Usage State IDLE (trigger) pids === 0... ");
+ _resetBusyReason();
setUsageState(CF::Device::IDLE);
}
else {
- LOG_TRACE(GPP_i, "Usage State ACTIVE..... ");
- _resetReason();
+ RH_TRACE(_baseLog, "Usage State ACTIVE..... ");
+ _resetBusyReason();
setUsageState(CF::Device::ACTIVE);
}
}
-void GPP_i::_resetReason() {
- _setReason("","");
+void GPP_i::_resetBusyReason() {
+ _busy.mark = _busy.timestamp = boost::posix_time::not_a_date_time;
+ _busy.resource.clear();
+ busy_reason.clear();
}
-void GPP_i::_setReason( const std::string &reason, const std::string &event, const bool enable_timestamp ) {
-
- if ( reason != "" ) {
- if ( reason != _busy_reason ) {
- LOG_INFO(GPP_i, "GPP BUSY, REASON: " << reason << " " << event );
- _busy_timestamp = boost::posix_time::microsec_clock::local_time();
- _busy_mark = boost::posix_time::microsec_clock::local_time();
- _busy_reason = reason;
- std::ostringstream oss;
- oss << "(time: " << _busy_timestamp << ") REASON: " << _busy_reason << " EXCEEDED " << event;
- busy_reason = oss.str();
- }
- else if ( reason == _busy_reason ) {
- boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
- boost::posix_time::time_duration dur = now - _busy_timestamp;
- boost::posix_time::time_duration last_msg = now - _busy_mark;
- std::ostringstream oss;
- oss << "(first/duration: " << _busy_timestamp << "/" << dur << ") REASON: " << _busy_reason << " EXCEEDED " << event;
- busy_reason = oss.str();
- if ( last_msg.total_seconds() > 2 ) {
- _busy_mark = now;
- LOG_INFO(GPP_i, "GPP BUSY, " << oss.str() );
- }
+void GPP_i::_setBusyReason(const std::string& resource, const std::string& message)
+{
+ if (resource != _busy.resource) {
+ RH_INFO(_baseLog, "GPP BUSY, REASON: " << resource << " " << message);
+ _busy.timestamp = boost::posix_time::microsec_clock::local_time();
+ _busy.mark = boost::posix_time::microsec_clock::local_time();
+ _busy.resource = resource;
+ std::ostringstream oss;
+ oss << "(time: " << _busy.timestamp << ") REASON: " << _busy.resource << " EXCEEDED " << message;
+ busy_reason = oss.str();
+ } else {
+ boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
+ boost::posix_time::time_duration dur = now - _busy.timestamp;
+ boost::posix_time::time_duration last_msg = now - _busy.mark;
+ std::ostringstream oss;
+ oss << "(first/duration: " << _busy.timestamp << "/" << dur << ") REASON: " << _busy.resource << " EXCEEDED " << message;
+ busy_reason = oss.str();
+ if ( last_msg.total_seconds() > 2 ) {
+ _busy.mark = now;
+ RH_INFO(_baseLog, "GPP BUSY, " << oss.str() );
}
}
- else {
- _busy_timestamp = boost::posix_time::microsec_clock::local_time();
- _busy_mark = _busy_timestamp;
- busy_reason = reason;
- _busy_reason = reason;
- }
+ setUsageState(CF::Device::BUSY);
}
/**
@@ -1800,7 +2076,7 @@ int GPP_i::serviceFunction()
catch( const boost::thread_resource_error& e ){
std::stringstream errstr;
errstr << "Error acquiring lock (errno=" << e.native_error() << " msg=\"" << e.what() << "\")";
- LOG_ERROR(GPP_i, __FUNCTION__ << ": " << errstr.str() );
+ RH_ERROR(this->_baseLog, __FUNCTION__ << ": " << errstr.str() );
}
//
@@ -1813,25 +2089,20 @@ int GPP_i::serviceFunction()
ExecPartitionList::iterator iter = execPartitions.begin();
std::ostringstream ss;
ss << boost::format("%-6s %-4s %-7s %-7s %-7s ") % "SOCKET" % "CPUS" % "USER" % "SYSTEM" % "IDLE";
- LOG_DEBUG(GPP_i, ss.str() );
+ RH_TRACE(this->_baseLog, ss.str() );
ss.clear();
ss.str("");
for ( ; iter != execPartitions.end(); iter++ ) {
ss << boost::format("%-6d %-4d %-7.2f %-7.2f %-7.2f ") % iter->id % iter->stats.get_ncpus() % iter->stats.get_user_percent() % iter->stats.get_system_percent() % iter->stats.get_idle_percent() ;
- LOG_DEBUG(GPP_i, ss.str() );
+ RH_TRACE(this->_baseLog, ss.str() );
ss.clear();
ss.str("");
}
}
// update monitors to see if thresholds are exceeded
- std::for_each( threshold_monitors.begin(), threshold_monitors.end(), boost::bind( &Updateable::update, _1 ) );
-
- for( size_t i=0; iidle_cap_mod = 100.0 * reserved_capacity_per_component / ((float)iter->cpus.size());
+ iter->idle_cap_mod = 100.0 * reserved_capacity_per_component / ((float)iter->cpus.size());
}
- }
}
-void GPP_i::mcastnicThreshold_changed(const CORBA::Long *oldvalue, const CORBA::Long *newvalue) {
-
- if( newvalue ) {
- int threshold = *newvalue;
+void GPP_i::mcastnicThreshold_changed(int oldvalue, int newvalue)
+{
+ int threshold = newvalue;
if ( threshold >= 0 && threshold <= 100 ) {
double origIngressThreshold = mcastnicIngressThresholdValue;
double origEgressThreshold = mcastnicIngressThresholdValue;
@@ -1933,10 +2193,7 @@ void GPP_i::mcastnicThreshold_changed(const CORBA::Long *oldvalue, const CORBA:
mcastnicEgressCapacity = mcastnicEgressThresholdValue;
mcastnicEgressFree = mcastnicEgressCapacity;
}
-
}
- }
-
}
@@ -1950,18 +2207,18 @@ void GPP_i::_affinity_changed( const affinity_struct *ovp, const affinity_struct
if ( ovp ) {
const affinity_struct ov = *ovp;
- LOG_DEBUG(GPP_i, "OV: " );
- LOG_DEBUG(GPP_i, "OV: ov.policy/context " << ov.exec_directive_class << "/" << ov.exec_directive_value );
- LOG_DEBUG(GPP_i, "OV: ov.blacklist size " << ov.blacklist_cpus.size() );
- LOG_DEBUG(GPP_i, "OV: ov.force_override " << ov.force_override );
- LOG_DEBUG(GPP_i, "OV: ov.disabled " << ov.disabled );
+ RH_DEBUG(this->_baseLog, "OV: " );
+ RH_DEBUG(this->_baseLog, "OV: ov.policy/context " << ov.exec_directive_class << "/" << ov.exec_directive_value );
+ RH_DEBUG(this->_baseLog, "OV: ov.blacklist size " << ov.blacklist_cpus.size() );
+ RH_DEBUG(this->_baseLog, "OV: ov.force_override " << ov.force_override );
+ RH_DEBUG(this->_baseLog, "OV: ov.disabled " << ov.disabled );
}
- LOG_DEBUG(GPP_i, "NV: " );
- LOG_DEBUG(GPP_i, "NV: nv.policy/context " << nv.exec_directive_class << "/" << nv.exec_directive_value );
- LOG_DEBUG(GPP_i, "NV: nv.blacklist size " << nv.blacklist_cpus.size() );
- LOG_DEBUG(GPP_i, "NV: nv.force_override " << nv.force_override );
- LOG_DEBUG(GPP_i, "NV: nv.disabled " << nv.disabled );
+ RH_DEBUG(this->_baseLog, "NV: " );
+ RH_DEBUG(this->_baseLog, "NV: nv.policy/context " << nv.exec_directive_class << "/" << nv.exec_directive_value );
+ RH_DEBUG(this->_baseLog, "NV: nv.blacklist size " << nv.blacklist_cpus.size() );
+ RH_DEBUG(this->_baseLog, "NV: nv.force_override " << nv.force_override );
+ RH_DEBUG(this->_baseLog, "NV: nv.disabled " << nv.disabled );
// change affinity struct to affinity spec..
redhawk::affinity::AffinityDirective value;
@@ -2049,11 +2306,11 @@ bool GPP_i::allocate_mcastegress_capacity(const CORBA::Long &value)
boost::mutex::scoped_lock lock(propertySetAccess);
std::string except_msg("Invalid allocation");
bool retval=false;
- LOG_DEBUG(GPP_i, __FUNCTION__ << ": Allocating mcastegress allocation " << value);
+ RH_DEBUG(this->_baseLog, __FUNCTION__ << ": Allocating mcastegress allocation " << value);
if ( mcastnicInterface == "" ) {
std::string msg = "mcastnicEgressCapacity request failed because no mcastnicInterface has been configured";
- LOG_DEBUG(GPP_i, __FUNCTION__ << msg );
+ RH_DEBUG(this->_baseLog, __FUNCTION__ << msg );
throw CF::Device::InvalidState(msg.c_str());
return retval;
}
@@ -2063,7 +2320,7 @@ bool GPP_i::allocate_mcastegress_capacity(const CORBA::Long &value)
std::ostringstream os;
os << "mcastnicEgressCapacity request: " << value << " failed because of insufficent capacity available, current: " << mcastnicEgressCapacity;
std::string msg = os.str();
- LOG_DEBUG(GPP_i, __FUNCTION__ << msg );
+ RH_DEBUG(this->_baseLog, __FUNCTION__ << msg );
CF::Properties errprops;
errprops.length(1);
errprops[0].id = "mcastnicEgressCapacity";
@@ -2082,7 +2339,7 @@ bool GPP_i::allocate_mcastegress_capacity(const CORBA::Long &value)
void GPP_i::deallocate_mcastegress_capacity(const CORBA::Long &value)
{
boost::mutex::scoped_lock lock(propertySetAccess);
- LOG_DEBUG(GPP_i, __FUNCTION__ << ": Deallocating mcastegress allocation " << value);
+ RH_DEBUG(this->_baseLog, __FUNCTION__ << ": Deallocating mcastegress allocation " << value);
mcastnicEgressCapacity = value + mcastnicEgressCapacity;
if ( mcastnicEgressCapacity > mcastnicEgressThresholdValue ) {
@@ -2092,6 +2349,57 @@ void GPP_i::deallocate_mcastegress_capacity(const CORBA::Long &value)
mcastnicEgressFree = mcastnicEgressCapacity;
}
+bool GPP_i::allocate_reservation_request(const redhawk__reservation_request_struct &value)
+{
+ if (isBusy()) {
+ return false;
+ }
+ RH_DEBUG(this->_baseLog, __FUNCTION__ << ": allocating reservation_request allocation ");
+ {
+ WriteLock rlock(pidLock);
+ if (applicationReservations.find(value.obj_id) != applicationReservations.end()){
+ RH_INFO(_baseLog, __FUNCTION__ << ": Cannot make multiple reservations against the same application: "<& reservations = applicationReservations[value.obj_id].reservation;
+ for (unsigned int idx=0; idx_baseLog, __FUNCTION__ << ": Deallocating reservation_request allocation ");
+ for (ApplicationReservationMap::iterator app_it=applicationReservations.begin(); app_it!=applicationReservations.end(); app_it++) {
+ if (app_it->first == value.obj_id) {
+ applicationReservations.erase(app_it);
+ break;
+ }
+ }
+}
+
bool GPP_i::allocate_mcastingress_capacity(const CORBA::Long &value)
@@ -2099,11 +2407,11 @@ bool GPP_i::allocate_mcastingress_capacity(const CORBA::Long &value)
boost::mutex::scoped_lock lock(propertySetAccess);
std::string except_msg("Invalid allocation");
bool retval=false;
- LOG_DEBUG(GPP_i, __FUNCTION__ << ": Allocating mcastingress allocation " << value);
+ RH_DEBUG(this->_baseLog, __FUNCTION__ << ": Allocating mcastingress allocation " << value);
if ( mcastnicInterface == "" ) {
std::string msg = "mcastnicIngressCapacity request failed because no mcastnicInterface has been configured" ;
- LOG_DEBUG(GPP_i, __FUNCTION__ << msg );
+ RH_DEBUG(this->_baseLog, __FUNCTION__ << msg );
throw CF::Device::InvalidState(msg.c_str());
}
@@ -2112,7 +2420,7 @@ bool GPP_i::allocate_mcastingress_capacity(const CORBA::Long &value)
std::ostringstream os;
os << "mcastnicIngressCapacity request: " << value << " failed because of insufficent capacity available, current: " << mcastnicIngressCapacity;
std::string msg = os.str();
- LOG_DEBUG(GPP_i, __FUNCTION__ << msg );
+ RH_DEBUG(this->_baseLog, __FUNCTION__ << msg );
CF::Properties errprops;
errprops.length(1);
errprops[0].id = "mcastnicIngressCapacity";
@@ -2132,7 +2440,7 @@ bool GPP_i::allocate_mcastingress_capacity(const CORBA::Long &value)
void GPP_i::deallocate_mcastingress_capacity(const CORBA::Long &value)
{
boost::mutex::scoped_lock lock(propertySetAccess);
- LOG_DEBUG(GPP_i, __FUNCTION__ << ": Deallocating mcastingress deallocation " << value);
+ RH_DEBUG(this->_baseLog, __FUNCTION__ << ": Deallocating mcastingress deallocation " << value);
mcastnicIngressCapacity = value + mcastnicIngressCapacity;
if ( mcastnicIngressCapacity > mcastnicIngressThresholdValue ) {
@@ -2149,10 +2457,10 @@ bool GPP_i::allocateCapacity_nic_allocation(const nic_allocation_struct &alloc)
WriteLock wlock(nicLock);
std::string except_msg("Invalid allocation");
bool success=false;
- LOG_TRACE(GPP_i, __FUNCTION__ << ": Allocating nic_allocation (identifier=" << alloc.identifier << ")");
+ RH_TRACE(this->_baseLog, __FUNCTION__ << ": Allocating nic_allocation (identifier=" << alloc.identifier << ")");
try
{
- LOG_TRACE(GPP_i, __FUNCTION__ << ": ALLOCATION: { identifier: \"" << alloc.identifier << "\", data_rate: " << alloc.data_rate << ", data_size: " << alloc.data_size << ", multicast_support: \"" << alloc.multicast_support << "\", ip_addressable: \"" << alloc.ip_addressable << "\", interface: \"" << alloc.interface << "\" }");
+ RH_TRACE(this->_baseLog, __FUNCTION__ << ": ALLOCATION: { identifier: \"" << alloc.identifier << "\", data_rate: " << alloc.data_rate << ", data_size: " << alloc.data_size << ", multicast_support: \"" << alloc.multicast_support << "\", ip_addressable: \"" << alloc.ip_addressable << "\", interface: \"" << alloc.interface << "\" }");
success = nic_facade->allocate_capacity(alloc);
if( success )
@@ -2165,7 +2473,7 @@ bool GPP_i::allocateCapacity_nic_allocation(const nic_allocation_struct &alloc)
status = nic_allocation_status[i];
// need to check if processor socket servicing interface has enough idle capacity
if ( _check_exec_partition( status.interface ) == true ) {
- LOG_TRACE(GPP_i, __FUNCTION__ << ": SUCCESS: { identifier: \"" << status.identifier << "\", data_rate: " << status.data_rate << ", data_size: " << status.data_size << ", multicast_support: \"" << status.multicast_support << "\", ip_addressable: \"" << status.ip_addressable << "\", interface: \"" << status.interface << "\" }");
+ RH_TRACE(this->_baseLog, __FUNCTION__ << ": SUCCESS: { identifier: \"" << status.identifier << "\", data_rate: " << status.data_rate << ", data_size: " << status.data_size << ", multicast_support: \"" << status.multicast_support << "\", ip_addressable: \"" << status.ip_addressable << "\", interface: \"" << status.interface << "\" }");
break;
}
else {
@@ -2201,9 +2509,9 @@ bool GPP_i::allocateCapacity_nic_allocation(const nic_allocation_struct &alloc)
void GPP_i::deallocateCapacity_nic_allocation(const nic_allocation_struct &alloc)
{
WriteLock wlock(nicLock);
- LOG_TRACE(GPP_i, __FUNCTION__ << ": Deallocating nic_allocation (identifier=" << alloc.identifier << ")");
+ RH_TRACE(this->_baseLog, __FUNCTION__ << ": Deallocating nic_allocation (identifier=" << alloc.identifier << ")");
try {
- LOG_DEBUG(GPP_i, __FUNCTION__ << ": { identifier: \"" << alloc.identifier << "\", data_rate: " << alloc.data_rate << ", data_size: " << alloc.data_size << ", multicast_support: \"" << alloc.multicast_support << "\", ip_addressable: \"" << alloc.ip_addressable << "\", interface: \"" << alloc.interface << "\" }");
+ RH_DEBUG(this->_baseLog, __FUNCTION__ << ": { identifier: \"" << alloc.identifier << "\", data_rate: " << alloc.data_rate << ", data_size: " << alloc.data_size << ", multicast_support: \"" << alloc.multicast_support << "\", ip_addressable: \"" << alloc.ip_addressable << "\", interface: \"" << alloc.interface << "\" }");
nic_facade->deallocate_capacity(alloc);
}
catch( ... )
@@ -2216,16 +2524,6 @@ void GPP_i::deallocateCapacity_nic_allocation(const nic_allocation_struct &alloc
}
}
-void GPP_i::deallocateCapacity (const CF::Properties& capacities) throw (CF::Device::InvalidState, CF::Device::InvalidCapacity, CORBA::SystemException)
-{
- GPP_base::deallocateCapacity(capacities);
-}
-CORBA::Boolean GPP_i::allocateCapacity (const CF::Properties& capacities) throw (CF::Device::InvalidState, CF::Device::InvalidCapacity, CF::Device::InsufficientCapacity, CORBA::SystemException)
-{
- bool retval = GPP_base::allocateCapacity(capacities);
- return retval;
-}
-
bool GPP_i::allocate_diskCapacity(const double &value) {
@@ -2245,19 +2543,19 @@ bool GPP_i::allocate_memCapacity(const CORBA::LongLong &value) {
if (isBusy()) {
return false;
}
- LOG_DEBUG(GPP_i, "allocate memory (REQUEST) value: " << value << " memCapacity: " << memCapacity << " memFree:" << memFree );
+ RH_DEBUG(this->_baseLog, "allocate memory (REQUEST) value: " << value << " memCapacity: " << memCapacity << " memFree:" << memFree );
if ( value > memCapacity or value > memCapacityThreshold )
return false;
memCapacity -= value;
- LOG_DEBUG(GPP_i, "allocate memory (SUCCESS) value: " << value << " memCapacity: " << memCapacity << " memFree:" << memFree );
+ RH_DEBUG(this->_baseLog, "allocate memory (SUCCESS) value: " << value << " memCapacity: " << memCapacity << " memFree:" << memFree );
return true;
}
void GPP_i::deallocate_memCapacity(const CORBA::LongLong &value) {
- LOG_DEBUG(GPP_i, "deallocate memory (REQUEST) value: " << value << " memCapacity: " << memCapacity << " memFree:" << memFree );
+ RH_DEBUG(this->_baseLog, "deallocate memory (REQUEST) value: " << value << " memCapacity: " << memCapacity << " memFree:" << memFree );
memCapacity += value;
- LOG_DEBUG(GPP_i, "deallocate memory (SUCCESS) value: " << value << " memCapacity: " << memCapacity << " memFree:" << memFree );
+ RH_DEBUG(this->_baseLog, "deallocate memory (SUCCESS) value: " << value << " memCapacity: " << memCapacity << " memFree:" << memFree );
if ( memCapacity > memCapacityThreshold ) {
memCapacity = memCapacityThreshold;
}
@@ -2277,12 +2575,12 @@ bool GPP_i::allocate_loadCapacity(const double &value) {
// get current system load and calculated reservation load
if ( reserved_capacity_per_component == 0.0 ) {
- LOG_DEBUG(GPP_i, "allocate load capacity, (REQUEST) value: " << value << " loadCapacity: " << loadCapacity << " loadFree:" << loadFree );
+ RH_DEBUG(this->_baseLog, "allocate load capacity, (REQUEST) value: " << value << " loadCapacity: " << loadCapacity << " loadFree:" << loadFree );
// get system monitor report...
double load_threshold = modified_thresholds.load_avg;
double sys_load = system_monitor->get_loadavg();
if ( sys_load + value > load_threshold ) {
- LOG_WARN(GPP_i, "Allocate load capacity would exceed measured system load, current loadavg: " << sys_load << " requested: " << value << " threshold: " << load_threshold );
+ RH_WARN(this->_baseLog, "Allocate load capacity would exceed measured system load, current loadavg: " << sys_load << " requested: " << value << " threshold: " << load_threshold );
}
// perform classic load capacity
@@ -2290,7 +2588,7 @@ bool GPP_i::allocate_loadCapacity(const double &value) {
std::ostringstream os;
os << " Allocate load capacity failed due to insufficient capacity, available capacity:" << loadCapacity << " requested capacity: " << value;
std::string msg = os.str();
- LOG_DEBUG(GPP_i, msg );
+ RH_DEBUG(this->_baseLog, msg );
CF::Properties errprops;
errprops.length(1);
errprops[0].id = "DCE:72c1c4a9-2bcf-49c5-bafd-ae2c1d567056 (loadCapacity)";
@@ -2299,18 +2597,18 @@ bool GPP_i::allocate_loadCapacity(const double &value) {
}
loadCapacity -= value;
- LOG_DEBUG(GPP_i, "allocate load capacity, (SUCCESS) value: " << value << " loadCapacity: " << loadCapacity << " loadFree:" << loadFree );
+ RH_DEBUG(this->_baseLog, "allocate load capacity, (SUCCESS) value: " << value << " loadCapacity: " << loadCapacity << " loadFree:" << loadFree );
}
else {
// manage load capacity handled via reservation
- LOG_WARN(GPP_i, "Allocate load capacity allowed, GPP using component reservations for managing load capacity." );
+ RH_WARN(this->_baseLog, "Allocate load capacity allowed, GPP using component reservations for managing load capacity." );
loadCapacity -= value;
if ( loadCapacity < 0.0 ) {
loadCapacity = 0.0;
}
- LOG_DEBUG(GPP_i, "allocate load capacity, (SUCCESS) value: " << value << " loadCapacity: " << loadCapacity << " loadFree:" << loadFree );
+ RH_DEBUG(this->_baseLog, "allocate load capacity, (SUCCESS) value: " << value << " loadCapacity: " << loadCapacity << " loadFree:" << loadFree );
}
@@ -2319,12 +2617,12 @@ bool GPP_i::allocate_loadCapacity(const double &value) {
}
void GPP_i::deallocate_loadCapacity(const double &value) {
- LOG_DEBUG(GPP_i, "deallocate load capacity, (REQUEST) value: " << value << " loadCapacity: " << loadCapacity << " loadFree:" << loadFree );
+ RH_DEBUG(this->_baseLog, "deallocate load capacity, (REQUEST) value: " << value << " loadCapacity: " << loadCapacity << " loadFree:" << loadFree );
loadCapacity += value;
if ( loadCapacity > loadFree ) {
loadCapacity = loadFree;
}
- LOG_DEBUG(GPP_i, "deallocate load capacity, (SUCCESS) value: " << value << " loadCapacity: " << loadCapacity << " loadFree:" << loadFree );
+ RH_DEBUG(this->_baseLog, "deallocate load capacity, (SUCCESS) value: " << value << " loadCapacity: " << loadCapacity << " loadFree:" << loadFree );
updateThresholdMonitors();
updateUsageState();
return;
@@ -2341,13 +2639,13 @@ void GPP_i::deallocate_loadCapacity(const double &value) {
void GPP_i::send_threshold_event(const threshold_event_struct& message)
{
- LOG_INFO(GPP_i, __FUNCTION__ << ": " << message.message );
+ RH_INFO(this->_baseLog, __FUNCTION__ << ": " << message.message );
MessageEvent_out->sendMessage(message);
}
void GPP_i::sendChildNotification(const std::string &comp_id, const std::string &app_id)
{
- LOG_INFO(GPP_i, "Child termination notification on the IDM channel : comp:" << comp_id << " app:" <_baseLog, "Child termination notification on the IDM channel : comp:" << comp_id << " app:" <update();
- LOG_TRACE(GPP_i, __FUNCTION__ << ": resource_id=" << monitor->get_resource_id() << " threshold=" << monitor->get_threshold() << " measured=" << monitor->get_measured());
- }
+ std::for_each(threshold_monitors.begin(), threshold_monitors.end(), boost::bind(&Updateable::update, _1));
}
-void GPP_i::update()
+
+void GPP_i::updateProcessStats()
{
- // establish what the actual load is per floor_reservation
- // if the actual load -per is less than the reservation, compute the different and add the difference to the cpu_idle
- // read the clock from the system (start)
-
- int64_t user=0, system=0;
- ProcStat::GetTicks( system, user);
- int64_t f_start_total = system;
- int64_t f_use_start_total = user;
- float reservation_set = 0;
- size_t nres=0;
- int64_t usage=0;
+ // establish what the actual load is per floor_reservation
+ // if the actual load -per is less than the reservation, compute the
+ // different and add the difference to the cpu_idle
+ {
+ WriteLock rlock(pidLock);
+ this->update_grp_child_pids();
+ }
- {
- WriteLock rlock(pidLock);
-
- this->update_grp_child_pids();
-
- ProcessList::iterator i=this->pids.begin();
- for ( ; i!=pids.end(); i++) {
-
- if ( !i->terminated ) {
+ // Update system and user clocks and determine how much time has elapsed
+ // since the last measurement
+ int64_t last_system_ticks = _systemTicks;
+ int64_t last_user_ticks = _userTicks;
+ ProcStat::GetTicks(_systemTicks, _userTicks);
+ int64_t system_elapsed = _systemTicks - last_system_ticks;
+ int64_t user_elapsed = _userTicks - last_user_ticks;
- // update pstat usage for each process
- usage = i->get_pstat_usage();
+ float inverse_load_per_core = ((float)processor_cores)/(system_elapsed);
+ float aggregate_usage = 0;
+ float non_specialized_aggregate_usage = 0;
- if ( !i->app_started ) {
- nres++;
- if ( i->reservation == -1) {
- reservation_set += idle_capacity_modifier;
- } else {
- reservation_set += 100.0 * i->reservation/((float)processor_cores);
- }
- }
- }
+ ReadLock rlock(pidLock);
+ for (ApplicationReservationMap::iterator app_it=applicationReservations.begin(); app_it!=applicationReservations.end(); app_it++) {
+ app_it->second.usage = 0;
}
- }
- LOG_TRACE(GPP_i, __FUNCTION__ << " Completed first pass, record pstats for nproc: " << nres << " res_set " << reservation_set );
+ double reservation_set = 0;
+ size_t nres=0;
+ int usage_out=0;
- // set number reservations that are not started
- n_reservations = nres;
-
- // wait a little bit
- usleep(500000);
-
-
- user=0, system=0;
- ProcStat::GetTicks( system, user);
- int64_t f_end_total = system;
- int64_t f_use_end_total = user;
- float f_total = (float)(f_end_total-f_start_total);
- if ( f_total <= 0.0 ) {
- LOG_TRACE(GPP_i, __FUNCTION__ << std::endl<< " System Ticks end/start " << f_end_total << "/" << f_start_total << std::endl );
- f_total=1.0;
- }
- float inverse_load_per_core = ((float)processor_cores)/(f_total);
- float aggregate_usage = 0;
- float non_specialized_aggregate_usage = 0;
- double percent_core;
-
- ReadLock rlock(pidLock);
- ProcessList::iterator i=this->pids.begin();
- int usage_out=0;
- for ( ; i!=pids.end(); i++, usage_out++) {
-
- usage = 0;
- percent_core =0;
- if ( !i->terminated ) {
+ for (ProcessList::iterator i=this->pids.begin(); i!=pids.end(); i++, usage_out++) {
+ if (i->terminated) {
+ continue;
+ }
- // get delta from last pstat
- usage = i->get_pstat_usage();
+ // get delta from last pstat
+ int64_t usage = i->get_pstat_usage();
- percent_core = (double)usage * inverse_load_per_core;
- i->core_usage = percent_core;
- double res = i->reservation;
+ double percent_core = (double)usage * inverse_load_per_core;
+ i->core_usage = percent_core;
+ double res = i->reservation;
#if 0
- // debug assist
- if ( !(usage_out % 500) || usage < 0 || percent_core < 0.0 ) {
- uint64_t u, p2, p1;
- u = i->get_pstat_usage(p2,p1);
- LOG_INFO(GPP_i, __FUNCTION__ << std::endl<< "PROC SPEC PID: " << i->pid << std::endl <<
- " usage " << usage << std::endl <<
- " u " << usage << std::endl <<
- " p2 " << p2 << std::endl <<
- " p1 " << p1 << std::endl <<
- " percent_core: " << percent_core << std::endl <<
- " reservation: " << i->reservation << std::endl );
- }
+ // debug assist
+ if ( !(usage_out % 500) || usage < 0 || percent_core < 0.0 ) {
+ uint64_t u, p2, p1;
+ u = i->get_pstat_usage(p2,p1);
+ RH_INFO(_baseLog, __FUNCTION__ << std::endl<< "PROC SPEC PID: " << i->pid << std::endl <<
+ " usage " << usage << std::endl <<
+ " u " << usage << std::endl <<
+ " p2 " << p2 << std::endl <<
+ " p1 " << p1 << std::endl <<
+ " percent_core: " << percent_core << std::endl <<
+ " reservation: " << i->reservation << std::endl );
+ }
#endif
- if ( i->app_started ) {
-
- // if component is not using enough the add difference between minimum and current load
- if ( percent_core < res ) {
- reservation_set += 100.00 * ( res - percent_core)/((double)processor_cores);
- }
- // for components with non specific
- if ( res == -1.0 ) {
- non_specialized_aggregate_usage += percent_core / inverse_load_per_core;
+ if ( applicationReservations.find(i->appName) != applicationReservations.end()) {
+ if (applicationReservations[i->appName].reservation.find("cpucores") != applicationReservations[i->appName].reservation.end()) {
+ applicationReservations[i->appName].usage += percent_core;
+ }
}
- else {
- aggregate_usage += percent_core / inverse_load_per_core;
+
+ if (i->app_started) {
+ // if component is not using enough the add difference between minimum and current load
+ if ( percent_core < res ) {
+ reservation_set += 100.00 * ( res - percent_core)/((double)processor_cores);
+ }
+ // for components with non specific
+ if ( res == -1.0 ) {
+ non_specialized_aggregate_usage += percent_core / inverse_load_per_core;
+ }
+ else {
+ aggregate_usage += percent_core / inverse_load_per_core;
+ }
+ } else {
+ if ( applicationReservations.find(i->appName) != applicationReservations.end()) {
+ if (applicationReservations[i->appName].reservation.find("cpucores") != applicationReservations[i->appName].reservation.end()) {
+ continue;
+ }
+ }
+ nres++;
+ if ( i->reservation == -1) {
+ reservation_set += idle_capacity_modifier;
+ } else {
+ reservation_set += 100.0 * i->reservation/((float)processor_cores);
+ }
}
- }
}
- }
-
- LOG_TRACE(GPP_i, __FUNCTION__ << " Completed SECOND pass, record pstats for processes" );
-
- aggregate_usage *= inverse_load_per_core;
- non_specialized_aggregate_usage *= inverse_load_per_core;
- modified_thresholds.cpu_idle = __thresholds.cpu_idle + reservation_set;
- utilization[0].component_load = aggregate_usage + non_specialized_aggregate_usage;
- float estimate_total = (f_use_end_total-f_use_start_total) * inverse_load_per_core;
- utilization[0].system_load = (utilization[0].component_load > estimate_total) ? utilization[0].component_load : estimate_total; // for very light loads, sometimes there is a measurement mismatch because of timing
- utilization[0].subscribed = (reservation_set * (float)processor_cores) / 100.0 + utilization[0].component_load;
- utilization[0].maximum = processor_cores-(__thresholds.cpu_idle/100.0) * processor_cores;
-
- LOG_DEBUG(GPP_i, __FUNCTION__ << " LOAD and IDLE : " << std::endl <<
- " modified_threshold(req+res)=" << modified_thresholds.cpu_idle << std::endl <<
- " system: idle: " << system_monitor->get_idle_percent() << std::endl <<
- " idle avg: " << system_monitor->get_idle_average() << std::endl <<
- " threshold(req): " << __thresholds.cpu_idle << std::endl <<
- " idle modifier: " << idle_capacity_modifier << std::endl <<
- " reserved_cap_per_component: " << reserved_capacity_per_component << std::endl <<
- " number of reservations: " << n_reservations << std::endl <<
- " processes: " << pids.size() << std::endl <<
- " loadCapacity: " << loadCapacity << std::endl <<
- " loadTotal: " << loadTotal << std::endl <<
- " loadFree(Modified): " << loadFree <getReport();
- LOG_DEBUG(GPP_i, __FUNCTION__ << " SysInfo Load : " << std::endl <<
- " one: " << rpt.load.one_min << std::endl <<
- " five: " << rpt.load.five_min << std::endl <<
- " fifteen: " << rpt.load.fifteen_min << std::endl );
+ // set number reservations that are not started
+ n_reservations = nres;
- loadAverage.onemin = rpt.load.one_min;
- loadAverage.fivemin = rpt.load.five_min;
- loadAverage.fifteenmin = rpt.load.fifteen_min;
+ for (ApplicationReservationMap::iterator app_it=applicationReservations.begin(); app_it!=applicationReservations.end(); app_it++) {
+ if (app_it->second.reservation.find("cpucores") != app_it->second.reservation.end()) {
+ bool found_app = false;
+ for ( ProcessList::iterator _pid_it=this->pids.begin();_pid_it!=pids.end(); _pid_it++) {
+ if (applicationReservations.find(_pid_it->appName) != applicationReservations.end()) {
+ found_app = true;
+ break;
+ }
+ }
+ if (not found_app) {
+ if (app_it->second.reservation["cpucores"] == -1) {
+ reservation_set += idle_capacity_modifier;
+ } else {
+ reservation_set += 100.0 * app_it->second.reservation["cpucores"]/((float)processor_cores);
+ }
+ } else {
+ if (app_it->second.usage < app_it->second.reservation["cpucores"]) {
+ reservation_set += 100.00 * ( app_it->second.reservation["cpucores"] - app_it->second.usage)/((double)processor_cores);
+ }
+ }
+ }
+ }
- memFree = rpt.virtual_memory_free / mem_free_units;
- LOG_DEBUG(GPP_i, __FUNCTION__ << "Memory : " << std::endl <<
- " sys_monitor.vit_total: " << rpt.virtual_memory_total << std::endl <<
- " sys_monitor.vit_free: " << rpt.virtual_memory_free << std::endl <<
- " sys_monitor.mem_total: " << rpt.physical_memory_total << std::endl <<
- " sys_monitor.mem_free: " << rpt.physical_memory_free << std::endl <<
- " memFree: " << memFree << std::endl <<
- " memCapacity: " << memCapacity << std::endl <<
- " memCapacityThreshold: " << memCapacityThreshold << std::endl <<
- " memInitCapacityPercent: " << memInitCapacityPercent << std::endl );
+ RH_TRACE(_baseLog, __FUNCTION__ << " Completed pass, record pstats for processes" );
+
+ aggregate_usage *= inverse_load_per_core;
+ non_specialized_aggregate_usage *= inverse_load_per_core;
+ utilization[0].component_load = aggregate_usage + non_specialized_aggregate_usage;
+ float estimate_total = (user_elapsed) * inverse_load_per_core;
+ utilization[0].system_load = std::max(utilization[0].component_load, estimate_total); // for very light loads, sometimes there is a measurement mismatch because of timing
+ utilization[0].subscribed = (reservation_set * (float)processor_cores) / 100.0 + utilization[0].component_load;
+
+ // The maximum CPU utilization is in terms of cores; if a threshold is set,
+ // normalize it to the range [0,1] and scale the maximum by that ratio
+ float cpu_idle_threshold = 0.0;
+ utilization[0].maximum = processor_cores;
+ if (!thresholds.ignore && (thresholds.cpu_idle >= 0.0)) {
+ utilization[0].maximum *= (1.0 - thresholds.cpu_idle * 0.01);
+ modified_thresholds.cpu_idle = thresholds.cpu_idle + reservation_set;
+ cpu_idle_threshold = thresholds.cpu_idle;
+ }
+
+ RH_DEBUG(_baseLog, __FUNCTION__ << " LOAD and IDLE : " << std::endl <<
+ " modified_threshold(req+res)=" << modified_thresholds.cpu_idle << std::endl <<
+ " system: idle: " << system_monitor->get_idle_percent() << std::endl <<
+ " idle avg: " << system_monitor->get_idle_average() << std::endl <<
+ " threshold(req): " << cpu_idle_threshold << std::endl <<
+ " idle modifier: " << idle_capacity_modifier << std::endl <<
+ " reserved_cap_per_component: " << reserved_capacity_per_component << std::endl <<
+ " number of reservations: " << n_reservations << std::endl <<
+ " processes: " << pids.size() << std::endl <<
+ " loadCapacity: " << loadCapacity << std::endl <<
+ " loadTotal: " << loadTotal << std::endl <<
+ " loadFree(Modified): " << loadFree <update_state();
- const Limits::Contents &pid_rpt = process_limits->get();
- gpp_limits.current_threads = pid_rpt.threads;
- gpp_limits.max_threads = pid_rpt.threads_limit;
- gpp_limits.current_open_files = pid_rpt.files;
- gpp_limits.max_open_files = pid_rpt.files_limit;
+void GPP_i::update()
+{
+ updateProcessStats();
+
+ const SystemMonitor::Report &rpt = system_monitor->getReport();
+ RH_TRACE(_baseLog, __FUNCTION__ << " SysInfo Load : " << std::endl <<
+ " one: " << rpt.load.one_min << std::endl <<
+ " five: " << rpt.load.five_min << std::endl <<
+ " fifteen: " << rpt.load.fifteen_min << std::endl );
+
+ loadAverage.onemin = rpt.load.one_min;
+ loadAverage.fivemin = rpt.load.five_min;
+ loadAverage.fifteenmin = rpt.load.fifteen_min;
+
+ memFree = rpt.virtual_memory_free / mem_free_units;
+ RH_TRACE(_baseLog, __FUNCTION__ << "Memory : " << std::endl <<
+ " sys_monitor.vit_total: " << rpt.virtual_memory_total << std::endl <<
+ " sys_monitor.vit_free: " << rpt.virtual_memory_free << std::endl <<
+ " sys_monitor.mem_total: " << rpt.physical_memory_total << std::endl <<
+ " sys_monitor.mem_free: " << rpt.physical_memory_free << std::endl <<
+ " memFree: " << memFree << std::endl <<
+ " memCapacity: " << memCapacity << std::endl <<
+ " memCapacityThreshold: " << memCapacityThreshold << std::endl <<
+ " memInitCapacityPercent: " << memInitCapacityPercent << std::endl );
+
+ shmFree = redhawk::shm::getSystemFreeMemory() / MB_TO_BYTES;
+
+ //
+ // transfer limits to properties
+ //
+ const Limits::Contents &sys_rpt =rpt.sys_limits;
+ sys_limits.current_threads = sys_rpt.threads;
+ sys_limits.max_threads = sys_rpt.threads_limit;
+ sys_limits.current_open_files = sys_rpt.files;
+ sys_limits.max_open_files = sys_rpt.files_limit;
+ process_limits->update_state();
+ const Limits::Contents &pid_rpt = process_limits->get();
+ gpp_limits.current_threads = pid_rpt.threads;
+ gpp_limits.max_threads = pid_rpt.threads_limit;
+ gpp_limits.current_open_files = pid_rpt.files;
+ gpp_limits.max_open_files = pid_rpt.files_limit;
}
@@ -2566,11 +2882,11 @@ int GPP_i::sigchld_handler(int sig)
FD_SET(sig_fd, &readfds);
select(sig_fd+1, &readfds, NULL, NULL, &tv);
if (FD_ISSET(sig_fd, &readfds)) {
- LOG_TRACE(GPP_i, " Checking for signals from SIGNALFD(" << sig_fd << ") cnt:" << cnt++ );
+ RH_TRACE(this->_baseLog, " Checking for signals from SIGNALFD(" << sig_fd << ") cnt:" << cnt++ );
s = read(sig_fd, &si, sizeof(struct signalfd_siginfo));
- LOG_TRACE(GPP_i, " RETURN from SIGNALFD(" << sig_fd << ") cnt/ret:" << cnt << "/" << s );
+ RH_TRACE(this->_baseLog, " RETURN from SIGNALFD(" << sig_fd << ") cnt/ret:" << cnt << "/" << s );
if (s != sizeof(struct signalfd_siginfo)){
- LOG_ERROR(GPP_i, "SIGCHLD handling error ...");
+ RH_ERROR(this->_baseLog, "SIGCHLD handling error ...");
break;
}
@@ -2585,12 +2901,12 @@ int GPP_i::sigchld_handler(int sig)
// will issue a notification event message for non domain terminated resources.. ie. segfaults..
//
if ( si.ssi_signo == SIGCHLD) {
- LOG_TRACE(GPP_i, "Child died , pid .................................." << si.ssi_pid);
+ RH_TRACE(this->_baseLog, "Child died , pid .................................." << si.ssi_pid);
int status;
pid_t child_pid;
bool reap=false;
while( (child_pid = waitpid(-1, &status, WNOHANG)) > 0 ) {
- LOG_TRACE(GPP_i, "WAITPID died , pid .................................." << child_pid);
+ RH_TRACE(this->_baseLog, "WAITPID died , pid .................................." << child_pid);
if ( (uint)child_pid == si.ssi_pid ) reap=true;
_component_cleanup( child_pid, status );
}
@@ -2599,7 +2915,7 @@ int GPP_i::sigchld_handler(int sig)
}
}
else {
- LOG_TRACE(GPP_i, "read from signalfd --> signo:" << si.ssi_signo);
+ RH_TRACE(this->_baseLog, "read from signalfd --> signo:" << si.ssi_signo);
}
}
else {
@@ -2608,7 +2924,7 @@ int GPP_i::sigchld_handler(int sig)
}
}
- //LOG_TRACE(GPP_i, "sigchld_handler RETURN.........loop cnt:" << cnt);
+ //RH_TRACE(this->_baseLog, "sigchld_handler RETURN.........loop cnt:" << cnt);
return NOOP;
}
@@ -2622,99 +2938,68 @@ int GPP_i::redirected_io_handler()
// check we have a log file
if ( _componentOutputLog == "" ) {
- LOG_DEBUG(GPP_i, " Component IO redirect ON but no file specified. ");
+ RH_DEBUG(this->_baseLog, " Component IO redirect ON but no file specified. ");
return NOOP;
}
- LOG_DEBUG(GPP_i, " Locking For Redirect Processing............. ");
+ RH_DEBUG(this->_baseLog, " Locking For Redirect Processing............. ");
ReadLock lock(fdsLock);
- int redirect_file = open(_componentOutputLog.c_str(), O_RDWR | O_CREAT , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
+ int redirect_file = open(_componentOutputLog.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
if ( redirect_file != -1 ) {
if ( lseek(redirect_file, 0, SEEK_END) == -1 ) {
- LOG_DEBUG(GPP_i, " Unable to SEEK To file end, file: " << _componentOutputLog);
+ RH_DEBUG(this->_baseLog, " Unable to SEEK To file end, file: " << _componentOutputLog);
}
}
else {
- LOG_TRACE(GPP_i, " Unable to open up componentOutputLog, fallback to /dev/null tried log: " << _componentOutputLog);
+ RH_TRACE(this->_baseLog, " Unable to open up componentOutputLog, fallback to /dev/null tried log: " << _componentOutputLog);
redirect_file = open("/dev/null", O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
}
size_t size = 0;
uint64_t cnt = 0;
- uint64_t fopens = 0;
uint64_t fcloses = 0;
uint64_t nbytes = 0;
size_t result=0;
int rd_fd =0;
- ProcessFds::iterator fd = redirectedFds.begin();
- for ( ; fd != redirectedFds.end() && _handle_io_redirects ; fd++ ) {
-
- // set default redirect to be master
- rd_fd=redirect_file;
-
- // check if our pid is vaid
- if ( fd->pid > 0 and fd->cout > -1 ) {
-
- // open up a specific redirect file
- if ( fd->fname != "" && fd->fname != _componentOutputLog ) {
- LOG_TRACE(GPP_i, " OPEN FILE - PID: " << fd->pid << " fname " << fd->fname);
- rd_fd = open(fd->fname.c_str(), O_RDWR | O_CREAT , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
- if ( rd_fd == -1 ) {
- LOG_ERROR(GPP_i, " Unable to open component output log: " << fd->fname);
- rd_fd = redirect_file;
- }
- else {
- fopens++;
- if ( lseek(rd_fd, 0, SEEK_END) == -1 ) {
- LOG_DEBUG(GPP_i, " Unable to SEEK To file end, file: " << fd->fname);
- }
- }
- }
- fd_set readfds;
- FD_ZERO(&readfds);
- FD_SET(fd->cout, &readfds);
- struct timeval tv = {0, 50};
- select(fd->cout+1, &readfds, NULL, NULL, &tv);
- if (FD_ISSET(fd->cout, &readfds)) {
-
- result=0;
- size = 0;
- if (ioctl (fd->cout, FIONREAD, &size) == -1) {
- LOG_ERROR(GPP_i, "(redirected IO) Error requesting how much to read, PID: " << fd->pid << " FD:" << fd->cout );
- close(fd->cout);
- fd->cout = -1;
- }
- if ( fd->cout != -1 && rd_fd != -1 ) {
- LOG_TRACE(GPP_i, " SPLICE DATA From Child to Output SIZE " << size << "...... PID: " << fd->pid << " FD:" << fd->cout );
- result = splice( fd->cout, NULL, rd_fd, NULL, size,0 );
- LOG_TRACE(GPP_i, " SPLICE DATA From Child to Output RES:" << result << "... PID: " << fd->pid << " FD:" << fd->cout );
- }
- if ( (int64_t)result == -1 ) {
- LOG_ERROR(GPP_i, "(redirected IO) Error during transfer to redirected file, PID: " << fd->pid << " FD:" << fd->cout );
- close(fd->cout);
- fd->cout = -1;
- }
- else {
- nbytes += result;
- cnt++;
- }
+ size_t nfds=redirectedFds.size();
+ // set default redirect to be master
+ rd_fd=redirect_file;
+ std::vector events(nfds);
+ int rfds = epoll_wait(epfd, events.data(), nfds, 10);
+
+ if ( rfds > 0 ) {
+ for ( int i=0; i< rfds; i++ ) {
+ size = 0;
+ result=0;
+ proc_redirect *fd=(proc_redirect*)events[i].data.ptr;
+ if (ioctl (fd->cout, FIONREAD, &size) == -1) {
+ RH_ERROR(this->_baseLog, "(redirected IO) Error requesting how much to read, PID: " << fd->pid << " FD:" << fd->cout );
+ close(fd->cout);
+ fd->cout = -1;
+ fcloses++;
+ }
+ if ( fd->cout != -1 && rd_fd != -1 ) {
+ result = splice( fd->cout, NULL, rd_fd, NULL, size,0 );
+ RH_TRACE(this->_baseLog, " SPLICE DATA From Child to Output RES:" << result << "... PID: " << fd->pid << " FD:" << fd->cout );
+ }
+ if ( (int64_t)result == -1 ) {
+ RH_ERROR(this->_baseLog, "(redirected IO) Error during transfer to redirected file, PID: " << fd->pid << " FD:" << fd->cout );
+ close(fd->cout);
+ fd->cout = -1;
+ fcloses++;
+ }
+ else {
+ nbytes += result;
+ cnt++;
+ }
}
-
- }
-
- /// close our per component redirected io file if we opened one
- if ( rd_fd != -1 && rd_fd != redirect_file ) {
- fcloses++;
- close(rd_fd);
- }
-
}
-
+
// close file while we wait
if ( redirect_file ) close(redirect_file);
- LOG_DEBUG(GPP_i, " IO REDIRECT, NPROCS: "<< redirectedFds.size() << " OPEN/CLOSE " << fopens << "/" << fcloses <<" PROCESSED PROCS/Bytes " << cnt << "/" << nbytes );
+ RH_DEBUG(this->_baseLog, " IO REDIRECT, NPROCS: "<< redirectedFds.size() << " CLOSED: " << fcloses <<" PROCESSED PROCS/Bytes " << cnt << "/" << nbytes );
return NOOP;
}
@@ -2736,7 +3021,7 @@ void GPP_i::addProcess(int pid, const std::string &appName, const std::string &i
ProcessList:: iterator result = std::find_if( pids.begin(), pids.end(), std::bind2nd( FindPid(), pid ) );
if ( result != pids.end() ) return;
- LOG_DEBUG(GPP_i, "START Adding Process/RES: " << pid << "/" << req_reservation << " APP:" << appName );
+ RH_DEBUG(this->_baseLog, "START Adding Process/RES: " << pid << "/" << req_reservation << " APP:" << appName );
component_description tmp;
tmp.appName = appName;
tmp.pid = pid;
@@ -2745,7 +3030,10 @@ void GPP_i::addProcess(int pid, const std::string &appName, const std::string &i
tmp.core_usage = 0;
tmp.parent = this;
pids.push_front( tmp );
- LOG_DEBUG(GPP_i, "END Adding Process/RES: " << pid << "/" << req_reservation << " APP:" << appName );
+ if (applicationReservations.find(appName) != applicationReservations.end()) {
+ applicationReservations[appName].component_pids.push_back(pid);
+ }
+ RH_DEBUG(this->_baseLog, "END Adding Process/RES: " << pid << "/" << req_reservation << " APP:" << appName );
}
GPP_i::component_description GPP_i::getComponentDescription(int pid)
@@ -2762,7 +3050,7 @@ void GPP_i::markPidTerminated( const int pid)
ReadLock lock(pidLock);
ProcessList:: iterator it = std::find_if( pids.begin(), pids.end(), std::bind2nd( FindPid(), pid ) );
if (it == pids.end()) return;
- LOG_DEBUG(GPP_i, " Mark For Termination: " << it->pid << " APP:" << it->appName );
+ RH_DEBUG(this->_baseLog, " Mark For Termination: " << it->pid << " APP:" << it->appName );
it->app_started= false;
it->terminated = true;
}
@@ -2774,7 +3062,7 @@ void GPP_i::removeProcess(int pid)
WriteLock wlock(pidLock);
ProcessList:: iterator result = std::find_if( pids.begin(), pids.end(), std::bind2nd( FindPid(), pid ) );
if ( result != pids.end() ) {
- LOG_DEBUG(GPP_i, "Monitor Process: REMOVE Process: " << result->pid << " app: " << result->appName );
+ RH_DEBUG(this->_baseLog, "Monitor Process: REMOVE Process: " << result->pid << " app: " << result->appName );
pids.erase(result);
}
}
@@ -2783,9 +3071,11 @@ void GPP_i::removeProcess(int pid)
WriteLock wlock(fdsLock);
ProcessFds::iterator i=std::find_if( redirectedFds.begin(), redirectedFds.end(), std::bind2nd( FindRedirect(), pid ) );
if ( i != redirectedFds.end() ) {
- i->close();
- LOG_DEBUG(GPP_i, "Redirectio IO ..REMOVE Redirected pid:" << pid );
- redirectedFds.erase(i);
+ ProcRedirectPtr rdp=*i;
+ rdp->close();
+ rdp.reset();
+ RH_DEBUG(this->_baseLog, "Redirectio IO ..REMOVE Redirected pid:" << pid );
+ redirectedFds.erase(i);
}
}
@@ -2914,3 +3204,21 @@ int GPP_i::_get_deploy_on_partition() {
if ( psoc > -1 ) { RH_NL_INFO("GPP", " Deploy resource on selected SOCKET PARTITON, socket:" << psoc ); }
return psoc;
}
+
+void GPP_i::_cleanupProcessShm(pid_t pid)
+{
+ const std::string heap_name = redhawk::shm::getProcessHeapName(pid);
+ redhawk::shm::SuperblockFile heap(heap_name);
+ try {
+ heap.open(false);
+ } catch (const std::exception&) {
+ // Ignore error, it probably doesn't exist
+ return;
+ }
+ RH_DEBUG(_baseLog, "Removing shared memory heap '" << heap_name << "'");
+ try {
+ heap.file().unlink();
+ } catch (const std::exception&) {
+ // Someone else removed it in the meantime
+ }
+}
diff --git a/GPP/cpp/GPP.h b/GPP/cpp/GPP.h
index d8de40ad3..6f0d609bf 100644
--- a/GPP/cpp/GPP.h
+++ b/GPP/cpp/GPP.h
@@ -31,8 +31,6 @@
#include "statistics/Statistics.h"
#include "statistics/CpuUsageStats.h"
#include "reports/SystemMonitorReporting.h"
-#include "reports/CpuThresholdMonitor.h"
-#include "reports/NicThroughputThresholdMonitor.h"
#include "NicFacade.h"
#include "ossie/Events.h"
@@ -80,6 +78,8 @@ class GPP_i : public GPP_base
void deallocate_diskCapacity(const double &value);
bool allocate_memCapacity(const CORBA::LongLong &value);
void deallocate_memCapacity(const CORBA::LongLong &value);
+ bool allocate_reservation_request(const redhawk__reservation_request_struct &value);
+ void deallocate_reservation_request(const redhawk__reservation_request_struct &value);
bool allocate_mcastegress_capacity(const CORBA::Long &value);
void deallocate_mcastegress_capacity(const CORBA::Long &value);
bool allocate_mcastingress_capacity(const CORBA::Long &value);
@@ -94,7 +94,8 @@ class GPP_i : public GPP_base
CF::ExecutableDevice::ProcessID_Type do_execute (const char* name, const CF::Properties& options,
const CF::Properties& parameters,
- const std::vector prepend_args)
+ const std::vector prepend_args,
+ const bool use_docker)
throw (CF::ExecutableDevice::ExecuteFail,
CF::InvalidFileName, CF::ExecutableDevice::InvalidOptions,
CF::ExecutableDevice::InvalidParameters,
@@ -108,8 +109,6 @@ class GPP_i : public GPP_base
void sendChildNotification(const std::string &comp_id, const std::string &app_id);
bool allocateCapacity_nic_allocation(const nic_allocation_struct &value);
void deallocateCapacity_nic_allocation(const nic_allocation_struct &value);
- void deallocateCapacity (const CF::Properties& capacities) throw (CF::Device::InvalidState, CF::Device::InvalidCapacity, CORBA::SystemException);
- CORBA::Boolean allocateCapacity (const CF::Properties& capacities) throw (CF::Device::InvalidState, CF::Device::InvalidCapacity, CF::Device::InsufficientCapacity, CORBA::SystemException);
void releaseObject() throw (CORBA::SystemException, CF::LifeCycle::ReleaseError);
@@ -150,7 +149,8 @@ class GPP_i : public GPP_base
void close();
};
-
+ typedef boost::shared_ptr ProcRedirectPtr;
+
struct component_description {
static const int pstat_history_len=5;
int pid;
@@ -174,6 +174,13 @@ class GPP_i : public GPP_base
int64_t get_process_time();
};
+ struct application_reservation {
+ std::vector component_pids;
+ std::map reservation;
+ float usage;
+ };
+
+ void constructor();
protected:
@@ -234,52 +241,47 @@ class GPP_i : public GPP_base
void process_ODM(const CORBA::Any &data);
void updateUsageState();
- void setShadowThresholds(const thresholds_struct &newVals );
- typedef boost::shared_ptr NicMonitorPtr;
typedef boost::shared_ptr ThresholdMonitorPtr;
typedef std::vector< uint32_t > CpuList;
typedef std::vector< boost::shared_ptr > UpdateableSequence;
- typedef std::vector > StateSequence;
- typedef std::vector > StatisticsSequence;
- typedef std::vector > ReportingSequence;
typedef std::vector< ThresholdMonitorPtr > MonitorSequence;
- typedef std::vector< NicMonitorPtr > NicMonitorSequence;
typedef boost::shared_ptr SystemMonitorPtr;
typedef std::map ProcessMap;
typedef std::deque< component_description > ProcessList;
- typedef std::deque< proc_redirect > ProcessFds;
+ typedef std::deque< ProcRedirectPtr > ProcessFds;
+ typedef std::map ApplicationReservationMap;
void addProcess(int pid,
const std::string &appName,
const std::string &identifier,
const float req_reservation );
void removeProcess(int pid );
- void addThresholdMonitor( ThresholdMonitorPtr threshold_monitor );
- void reservedChanged(const float *oldValue, const float *newValue);
- void mcastnicThreshold_changed(const CORBA::Long *oldValue, const CORBA::Long *newValue);
- void thresholds_changed(const thresholds_struct *oldValue, const thresholds_struct *newValue);
+ void reservedChanged(float oldValue, float newValue);
+ void mcastnicThreshold_changed(int oldValue, int newValue);
+ void thresholds_changed(const thresholds_struct& oldValue, const thresholds_struct& newValue);
void update();
+ void updateProcessStats();
ProcessList pids;
size_t n_reservations;
Lock pidLock;
Lock fdsLock;
ProcessFds redirectedFds;
+ int epfd;
bool _handle_io_redirects;
std::string _componentOutputLog;
Lock nicLock;
NicFacadePtr nic_facade;
MonitorSequence threshold_monitors;
- NicMonitorSequence nic_monitors;
SystemMonitorPtr system_monitor;
ProcessLimitsPtr process_limits;
ExecPartitionList execPartitions;
+ ApplicationReservationMap applicationReservations;
Lock monitorLock;
UpdateableSequence data_model;
- thresholds_struct __thresholds;
thresholds_struct modified_thresholds;
uint64_t thresh_mem_free_units;
uint64_t mem_free_units;
@@ -299,17 +301,20 @@ class GPP_i : public GPP_base
redhawk::events::SubscriberPtr odm_consumer; // interface that receives ODM_Channel events
redhawk::events::ManagerPtr mymgr; // interface to manage event channel access
- std::string _busy_reason;
- boost::posix_time::ptime _busy_timestamp; // time when busy reason was initially set
- boost::posix_time::ptime _busy_mark; // track message output
+ // State tracking for busy reason
+ struct {
+ std::string resource;
+ boost::posix_time::ptime timestamp; // time when busy reason was initially set
+ boost::posix_time::ptime mark; // track message output
+ } _busy;
private:
//
// set the busy reason property for the GPP..
//
- void _resetReason();
- void _setReason( const std::string &reason, const std::string &event, const bool enable_timestamp = true );
+ void _resetBusyReason();
+ void _setBusyReason(const std::string& resource, const std::string& message);
bool _component_cleanup( const int pid, const int exit_status );
@@ -350,7 +355,7 @@ class GPP_i : public GPP_base
//
// Callback when componentOutputLog is changed
//
- void _component_output_changed(const std::string *ov, const std::string *nv );
+ void _component_output_changed(const std::string& ov, const std::string& nv);
//
// Set vlan list attribute
@@ -372,20 +377,52 @@ class GPP_i : public GPP_base
//
void _init();
+ ThresholdMonitorPtr _cpuIdleThresholdMonitor;
+ ThresholdMonitorPtr _freeMemThresholdMonitor;
+ ThresholdMonitorPtr _loadAvgThresholdMonitor;
+ ThresholdMonitorPtr _threadThresholdMonitor;
+ ThresholdMonitorPtr _fileThresholdMonitor;
+ ThresholdMonitorPtr _shmThresholdMonitor;
+
+ boost::shared_ptr _allNicsThresholdMonitor;
+
+ template
+ void _sendThresholdMessage(ThresholdMonitor* monitor, const T1& measured, const T2& threshold);
+ bool _shmThresholdCheck(ThresholdMonitor* monitor);
+ void _shmThresholdStateChanged(ThresholdMonitor* monitor);
+
+ bool _cpuIdleThresholdCheck(ThresholdMonitor* monitor);
+ void _cpuIdleThresholdStateChanged(ThresholdMonitor* monitor);
+
+ bool _loadAvgThresholdCheck(ThresholdMonitor* monitor);
+ void _loadAvgThresholdStateChanged(ThresholdMonitor* monitor);
+
+ bool _freeMemThresholdCheck(ThresholdMonitor* monitor);
+ void _freeMemThresholdStateChanged(ThresholdMonitor* monitor);
+
//
// check thread limits for the process and system
//
- bool _check_thread_limits( const thresholds_struct &threshold);
+ bool _threadThresholdCheck(ThresholdMonitor* monitor);
+ void _threadThresholdStateChanged(ThresholdMonitor* monitor);
//
// check file limits for the process and system
//
- bool _check_file_limits( const thresholds_struct &threshold);
+ bool _fileThresholdCheck(ThresholdMonitor* monitor);
+ void _fileThresholdStateChanged(ThresholdMonitor* monitor);
//
// check threshold limits for nic interfaces to determine busy state
//
- bool _check_nic_thresholds();
+ bool _nicThresholdCheck(ThresholdMonitor* monitor);
+ void _nicThresholdStateChanged(ThresholdMonitor* monitor);
+
+ void _cleanupProcessShm(pid_t pid);
+
+ // Processor time counters
+ int64_t _systemTicks;
+ int64_t _userTicks;
std::string user_id;
ossie::ProcessThread _signalThread;
diff --git a/GPP/cpp/GPP_base.cpp b/GPP/cpp/GPP_base.cpp
index e9a3df80c..0545c2a84 100644
--- a/GPP/cpp/GPP_base.cpp
+++ b/GPP/cpp/GPP_base.cpp
@@ -4,15 +4,15 @@
*
* This file is part of REDHAWK GPP.
*
- * REDHAWK GPP is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or (at your
- * option) any later version.
+ * REDHAWK GPP is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
*
* REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
@@ -33,40 +33,36 @@ GPP_base::GPP_base(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl) :
ExecutableDevice_impl(devMgr_ior, id, lbl, sftwrPrfl),
ThreadedComponent()
{
- construct();
+ construct();
}
GPP_base::GPP_base(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, char *compDev) :
ExecutableDevice_impl(devMgr_ior, id, lbl, sftwrPrfl, compDev),
ThreadedComponent()
{
- construct();
+ construct();
}
GPP_base::GPP_base(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, CF::Properties capacities) :
ExecutableDevice_impl(devMgr_ior, id, lbl, sftwrPrfl, capacities),
ThreadedComponent()
{
- construct();
+ construct();
}
GPP_base::GPP_base(char *devMgr_ior, char *id, char *lbl, char *sftwrPrfl, CF::Properties capacities, char *compDev) :
ExecutableDevice_impl(devMgr_ior, id, lbl, sftwrPrfl, capacities, compDev),
ThreadedComponent()
{
- construct();
+ construct();
}
GPP_base::~GPP_base()
{
- if (propEvent) {
- delete propEvent;
+ propEvent->_remove_ref();
propEvent = 0;
- }
- if ( MessageEvent_out ) {
- delete MessageEvent_out;
+ MessageEvent_out->_remove_ref();
MessageEvent_out = 0;
- }
}
void GPP_base::construct()
@@ -76,7 +72,16 @@ void GPP_base::construct()
propEvent = new PropertyEventSupplier("propEvent");
addPort("propEvent", propEvent);
propEvent->registerProperty(this->_identifier, this->naming_service_name, this->getPropertyFromId("DCE:9190eb70-bd1e-4556-87ee-5a259dcfee39"));
+ propEvent->registerProperty(this->_identifier, this->naming_service_name, this->getPropertyFromId("DCE:506102d6-04a9-4532-9420-a323d818ddec"));
+ propEvent->registerProperty(this->_identifier, this->naming_service_name, this->getPropertyFromId("DCE:eb08e43f-11c7-45a0-8750-edff439c8b24"));
+ propEvent->registerProperty(this->_identifier, this->naming_service_name, this->getPropertyFromId("DCE:0b57a27a-8fa2-412b-b0ae-010618b8f40e"));
+ propEvent->registerProperty(this->_identifier, this->naming_service_name, this->getPropertyFromId("DCE:9b5bbdcb-1894-4b95-847c-787f121c05ae"));
+ propEvent->registerProperty(this->_identifier, this->naming_service_name, this->getPropertyFromId("DCE:89be90ae-6a83-4399-a87d-5f4ae30ef7b1"));
+ propEvent->registerProperty(this->_identifier, this->naming_service_name, this->getPropertyFromId("DCE:6565bffd-cb09-4927-9385-2ecac68035c7"));
propEvent->registerProperty(this->_identifier, this->naming_service_name, this->getPropertyFromId("DCE:22a60339-b66e-4309-91ae-e9bfed6f0490"));
+ propEvent->registerProperty(this->_identifier, this->naming_service_name, this->getPropertyFromId("DCE:6c000787-6fea-4765-8686-2e051e6c24b0"));
+ propEvent->registerProperty(this->_identifier, this->naming_service_name, this->getPropertyFromId("DCE:72c1c4a9-2bcf-49c5-bafd-ae2c1d567056"));
+ propEvent->registerProperty(this->_identifier, this->naming_service_name, this->getPropertyFromId("DCE:9da85ebc-6503-48e7-af36-b77c7ad0c2b4"));
this->registerPropertyChangePort(propEvent);
MessageEvent_out = new MessageSupplierPort("MessageEvent_out");
addPort("MessageEvent_out", MessageEvent_out);
@@ -122,15 +127,16 @@ void GPP_base::loadProperties()
"readonly",
"",
"eq",
- "property,allocation,configure");
+ "allocation,configure");
addProperty(device_model,
+ "REDHAWK GPP",
"DCE:0f99b2e4-9903-4631-9846-ff349d18ecfb",
"device_model",
"readonly",
- "REDHAWK GPP",
+ "",
"eq",
- "property,allocation,configure");
+ "allocation,property,configure");
addProperty(processor_name,
"DCE:fefb9c66-d14a-438d-ad59-2cfd1adb272b",
@@ -138,7 +144,7 @@ void GPP_base::loadProperties()
"readonly",
"",
"eq",
- "property,allocation,configure");
+ "allocation,property,configure");
addProperty(os_name,
"DCE:4a23ad60-0b25-4121-a630-68803a498f75",
@@ -146,7 +152,7 @@ void GPP_base::loadProperties()
"readonly",
"",
"eq",
- "property,allocation,configure");
+ "allocation,property,configure");
addProperty(os_version,
"DCE:0f3a9a37-a342-43d8-9b7f-78dc6da74192",
@@ -154,7 +160,7 @@ void GPP_base::loadProperties()
"readonly",
"",
"eq",
- "property,allocation,configure");
+ "allocation,property,configure");
addProperty(hostName,
"DCE:9190eb70-bd1e-4556-87ee-5a259dcfee39",
@@ -174,13 +180,22 @@ void GPP_base::loadProperties()
"execparam");
addProperty(componentOutputLog,
+ "",
"DCE:c80f6c5a-e3ea-4f57-b0aa-46b7efac3176",
"componentOutputLog",
"readwrite",
"",
"external",
"property");
-
+
+ addProperty(docker_omniorb_cfg,
+ "docker_omniorb_cfg",
+ "docker_omniorb_cfg",
+ "readonly",
+ "/etc/omniORB.cfg",
+ "external",
+ "property");
+
addProperty(mcastnicInterface,
"",
"DCE:4e416acc-3144-47eb-9e38-97f1d24f7700",
@@ -209,7 +224,6 @@ void GPP_base::loadProperties()
"execparam");
addProperty(mcastnicIngressCapacity,
- 0,
"DCE:506102d6-04a9-4532-9420-a323d818ddec",
"mcastnicIngressCapacity",
"readwrite",
@@ -218,7 +232,6 @@ void GPP_base::loadProperties()
"allocation,event");
addProperty(mcastnicEgressCapacity,
- 0,
"DCE:eb08e43f-11c7-45a0-8750-edff439c8b24",
"mcastnicEgressCapacity",
"readwrite",
@@ -253,91 +266,185 @@ void GPP_base::loadProperties()
"external",
"configure,event");
- addProperty(mcastnicVLANs,
- "DCE:65544aad-4c73-451f-93de-d4d76984025a",
- "mcastnicVLANs",
+ addProperty(threshold_cycle_time,
+ 500,
+ "threshold_cycle_time",
+ "threshold_cycle_time",
"readwrite",
+ "milliseconds",
+ "external",
+ "property");
+
+ addProperty(busy_reason,
+ "",
+ "busy_reason",
+ "busy_reason",
+ "readonly",
"",
"external",
- "allocation");
+ "property");
- // Set the sequence with its initial values
- nic_interfaces.push_back("e.*");
- addProperty(nic_interfaces,
- nic_interfaces,
- "nic_interfaces",
+ addProperty(cacheDirectory,
"",
- "readwrite",
+ "cacheDirectory",
+ "cacheDirectory",
+ "readonly",
"",
"external",
- "configure,property");
+ "property");
- addProperty(available_nic_interfaces,
- "available_nic_interfaces",
+ addProperty(workingDirectory,
+ "",
+ "workingDirectory",
+ "workingDirectory",
+ "readonly",
"",
+ "external",
+ "property");
+
+ addProperty(memFree,
+ "DCE:6565bffd-cb09-4927-9385-2ecac68035c7",
+ "memFree",
+ "readonly",
+ "MiB",
+ "external",
+ "configure,event");
+
+ addProperty(memCapacity,
+ "DCE:8dcef419-b440-4bcf-b893-cab79b6024fb",
+ "memCapacity",
+ "readwrite",
+ "MiB",
+ "external",
+ "allocation");
+
+ addProperty(shmFree,
+ "shmFree",
+ "shmFree",
+ "readonly",
+ "MB",
+ "external",
+ "property");
+
+ addProperty(shmCapacity,
+ "shmCapacity",
+ "shmCapacity",
+ "readonly",
+ "MB",
+ "external",
+ "property");
+
+ addProperty(loadTotal,
+ "DCE:28b23bc8-e4c0-421b-9c52-415a24715209",
+ "loadTotal",
"readonly",
"",
"external",
"configure");
- addProperty(nic_allocation,
- nic_allocation_struct(),
- "nic_allocation",
- "nic_allocation",
+ addProperty(loadCapacityPerCore,
+ 1.0,
+ "DCE:3bf07b37-0c00-4e2a-8275-52bd4e391f07",
+ "loadCapacityPerCore",
+ "readwrite",
+ "",
+ "gt",
+ "allocation,execparam");
+
+ addProperty(loadThreshold,
+ 80,
+ "DCE:22a60339-b66e-4309-91ae-e9bfed6f0490",
+ "loadThreshold",
"readwrite",
+ "%",
+ "external",
+ "configure,event");
+
+ addProperty(loadFree,
+ "DCE:6c000787-6fea-4765-8686-2e051e6c24b0",
+ "loadFree",
+ "readonly",
"",
"external",
- "allocation");
+ "configure,event");
- addProperty(advanced,
- advanced_struct(),
- "advanced",
+ addProperty(loadCapacity,
+ "DCE:72c1c4a9-2bcf-49c5-bafd-ae2c1d567056",
+ "loadCapacity",
+ "readwrite",
"",
+ "external",
+ "allocation,event");
+
+ addProperty(reserved_capacity_per_component,
+ 0.1,
+ "reserved_capacity_per_component",
+ "reserved_capacity_per_component",
"readwrite",
"",
"external",
"configure");
- addProperty(nic_allocation_status,
- "nic_allocation_status",
+ addProperty(processor_cores,
+ "processor_cores",
"",
"readonly",
"",
"external",
"configure");
- addProperty(nic_metrics,
- "nic_metrics",
+ addProperty(processor_monitor_list,
+ "processor_monitor_list",
"",
"readonly",
"",
"external",
"configure");
- addProperty(networkMonitor,
- "networkMonitor",
+ addProperty(mcastnicVLANs,
+ "DCE:65544aad-4c73-451f-93de-d4d76984025a",
+ "mcastnicVLANs",
+ "readwrite",
"",
- "readonly",
+ "external",
+ "allocation");
+
+ // Set the sequence with its initial values
+ nic_interfaces.push_back("e.*");
+ addProperty(nic_interfaces,
+ nic_interfaces,
+ "nic_interfaces",
+ "",
+ "readwrite",
"",
"external",
- "configure");
+ "property,configure");
- addProperty(component_monitor,
- "component_monitor",
+ addProperty(available_nic_interfaces,
+ "available_nic_interfaces",
"",
"readonly",
"",
"external",
- "property");
+ "configure");
- addProperty(affinity,
- affinity_struct(),
- "affinity",
+ addProperty(nic_allocation,
+ nic_allocation_struct(),
+ "nic_allocation",
+ "nic_allocation",
+ "readwrite",
+ "",
+ "external",
+ "allocation");
+
+ addProperty(advanced,
+ advanced_struct(),
+ "advanced",
"",
"readwrite",
"",
"external",
- "property");
+ "configure");
addProperty(threshold_event,
threshold_event_struct(),
@@ -348,14 +455,6 @@ void GPP_base::loadProperties()
"external",
"message");
- addProperty(busy_reason,
- "busy_reason",
- "",
- "readonly",
- "",
- "external",
- "property");
-
addProperty(thresholds,
thresholds_struct(),
"thresholds",
@@ -365,17 +464,17 @@ void GPP_base::loadProperties()
"external",
"property");
- addProperty(threshold_cycle_time,
- 500,
- "threshold_cycle_time",
- "threshold_cycle_time",
- "readwrite",
- "milliseconds",
+ addProperty(loadAverage,
+ loadAverage_struct(),
+ "DCE:9da85ebc-6503-48e7-af36-b77c7ad0c2b4",
+ "loadAverage",
+ "readonly",
+ "",
"external",
- "property");
-
+ "configure,event");
+
addProperty(gpp_limits,
- ulimit_struct(),
+ gpp_limits_struct(),
"gpp_limits",
"",
"readonly",
@@ -392,107 +491,64 @@ void GPP_base::loadProperties()
"external",
"property");
- addProperty(utilization,
- "utilization",
+ addProperty(redhawk__reservation_request,
+ redhawk__reservation_request_struct(),
+ "redhawk::reservation_request",
"",
- "readonly",
+ "readwrite",
"",
"external",
- "property");
+ "allocation");
- addProperty(processor_cores,
- "processor_cores",
+ addProperty(affinity,
+ affinity_struct(),
+ "affinity",
"",
- "readonly",
+ "readwrite",
"",
"external",
- "configure");
+ "property");
- addProperty(processor_monitor_list,
- "processor_monitor_list",
+ addProperty(nic_allocation_status,
+ "nic_allocation_status",
"",
"readonly",
"",
"external",
"configure");
- addProperty(memFree,
- "DCE:6565bffd-cb09-4927-9385-2ecac68035c7",
- "memFree",
+ addProperty(nic_metrics,
+ "nic_metrics",
+ "",
"readonly",
- "MiB",
- "external",
- "configure,event");
-
- addProperty(memCapacity,
- "DCE:8dcef419-b440-4bcf-b893-cab79b6024fb",
- "memCapacity",
- "readwrite",
- "MiB",
- "external",
- "allocation,event");
-
- addProperty(reserved_capacity_per_component,
- 0.1,
- "reserved_capacity_per_component",
- "reserved_capacity_per_component",
- "readwrite",
"",
"external",
"configure");
- addProperty(loadTotal,
- "DCE:28b23bc8-e4c0-421b-9c52-415a24715209",
- "loadTotal",
+ addProperty(networkMonitor,
+ "networkMonitor",
+ "",
"readonly",
"",
"external",
"configure");
- addProperty(loadThreshold,
- 80,
- "DCE:22a60339-b66e-4309-91ae-e9bfed6f0490",
- "loadThreshold",
- "readwrite",
- "%",
- "external",
- "configure,event");
-
- addProperty(loadCapacityPerCore,
- 1.0,
- "DCE:3bf07b37-0c00-4e2a-8275-52bd4e391f07",
- "loadCapacityPerCore",
- "readwrite",
+ addProperty(utilization,
+ "utilization",
"",
- "gt",
- "allocation,execparam");
-
- addProperty(loadFree,
- "DCE:6c000787-6fea-4765-8686-2e051e6c24b0",
- "loadFree",
"readonly",
"",
"external",
- "configure,event");
+ "property");
- addProperty(loadCapacity,
- "DCE:72c1c4a9-2bcf-49c5-bafd-ae2c1d567056",
- "loadCapacity",
- "readwrite",
+ addProperty(component_monitor,
+ "component_monitor",
"",
- "external",
- "allocation,event");
-
- addProperty(loadAverage,
- loadAverage_struct(),
- "DCE:9da85ebc-6503-48e7-af36-b77c7ad0c2b4",
- "loadAverage",
"readonly",
"",
"external",
"property");
-
}
diff --git a/GPP/cpp/GPP_base.h b/GPP/cpp/GPP_base.h
index 5809f2c19..e46488a65 100644
--- a/GPP/cpp/GPP_base.h
+++ b/GPP/cpp/GPP_base.h
@@ -4,21 +4,21 @@
*
* This file is part of REDHAWK GPP.
*
- * REDHAWK GPP is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or (at your
- * option) any later version.
+ * REDHAWK GPP is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
*
* REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
-#ifndef GPP_IMPL_BASE_H
-#define GPP_IMPL_BASE_H
+#ifndef GPP_BASE_IMPL_BASE_H
+#define GPP_BASE_IMPL_BASE_H
#include
#include
@@ -47,76 +47,114 @@ class GPP_base : public ExecutableDevice_impl, protected ThreadedComponent
protected:
// Member variables exposed as properties
+ /// Property: device_kind
std::string device_kind;
+ /// Property: device_model
std::string device_model;
+ /// Property: processor_name
std::string processor_name;
+ /// Property: os_name
std::string os_name;
+ /// Property: os_version
std::string os_version;
+ /// Property: hostName
std::string hostName;
+ // Property: docker_omniorb_cfg
+ std::string docker_omniorb_cfg;
+ /// Property: useScreen
+ bool useScreen;
+ /// Property: componentOutputLog
std::string componentOutputLog;
- bool useScreen;
- advanced_struct advanced;
-
- std::vector nic_interfaces;
- std::vector available_nic_interfaces;
- nic_allocation_struct nic_allocation;
+ /// Property: mcastnicInterface
std::string mcastnicInterface;
+ /// Property: mcastnicIngressTotal
CORBA::Long mcastnicIngressTotal;
+ /// Property: mcastnicEgressTotal
CORBA::Long mcastnicEgressTotal;
+ /// Property: mcastnicIngressCapacity
CORBA::Long mcastnicIngressCapacity;
+ /// Property: mcastnicEgressCapacity
CORBA::Long mcastnicEgressCapacity;
+ /// Property: mcastnicIngressFree
CORBA::Long mcastnicIngressFree;
+ /// Property: mcastnicEgressFree
CORBA::Long mcastnicEgressFree;
+ /// Property: mcastnicThreshold
CORBA::Long mcastnicThreshold;
- std::vector mcastnicVLANs;
- std::vector nic_allocation_status;
- std::vector nic_metrics;
- std::vector networkMonitor;
- std::vector component_monitor;
-
- // reporting struct when a threshold is broke
- threshold_event_struct threshold_event;
- // threshold items to watch
- thresholds_struct thresholds;
- /// Property to annotate why the system is busy
- std::string busy_reason;
- // time between cycles to refresh threshold metrics
+ /// Property: threshold_cycle_time
CORBA::ULong threshold_cycle_time;
- // ulimits for the GPP process
- ulimit_struct gpp_limits;
- // ulimits for the system as a whole
- sys_limits_struct sys_limits;
+ /// Property: busy_reason
+ std::string busy_reason;
+ /// Property: cacheDirectory
+ std::string cacheDirectory;
+ /// Property: workingDirectory
+ std::string workingDirectory;
/// Property: memFree
CORBA::LongLong memFree;
/// Property: memCapacity
CORBA::LongLong memCapacity;
+ /// Property: shmFree
+ CORBA::LongLong shmFree;
+ /// Property: shmCapacity
+ CORBA::LongLong shmCapacity;
/// Property: loadTotal
double loadTotal;
- /// Property: loadThreshold
- CORBA::Long loadThreshold;
/// Property: loadCapacityPerCore
double loadCapacityPerCore;
+ /// Property: loadThreshold
+ CORBA::Long loadThreshold;
/// Property: loadFree
double loadFree;
/// Property: loadCapacity
double loadCapacity;
+ /// Property: reserved_capacity_per_component
+ float reserved_capacity_per_component;
+ /// Property: processor_cores
+ short processor_cores;
+ /// Property: processor_monitor_list
+ std::string processor_monitor_list;
+ /// Property: mcastnicVLANs
+ std::vector mcastnicVLANs;
+ /// Property: nic_interfaces
+ std::vector nic_interfaces;
+ /// Property: available_nic_interfaces
+ std::vector available_nic_interfaces;
+ /// Property: nic_allocation
+ nic_allocation_struct nic_allocation;
+ /// Property: advanced
+ advanced_struct advanced;
+ /// Message structure definition for threshold_event
+ threshold_event_struct threshold_event;
+ /// Property: thresholds
+ thresholds_struct thresholds;
/// Property: loadAverage
loadAverage_struct loadAverage;
- /// Property: reserved capacity per core for reservation schema
- float reserved_capacity_per_component;
- /// Property processor_cores - number of cores the machine supports
- short processor_cores;
- /// Property processor_monitor_list - list of the cores we are watching..
- std::string processor_monitor_list;
- // Property affinity - controls affinity processing for the GPP
+ /// Property: gpp_limits
+ gpp_limits_struct gpp_limits;
+ /// Property: sys_limits
+ sys_limits_struct sys_limits;
+ /// Property: redhawk__reservation_request
+ redhawk__reservation_request_struct redhawk__reservation_request;
+ /// Property: affinity
affinity_struct affinity;
+ /// Property: nic_allocation_status
+ std::vector nic_allocation_status;
+ /// Property: nic_metrics
+ std::vector nic_metrics;
+ /// Property: networkMonitor
+ std::vector networkMonitor;
+ /// Property: utilization
+ std::vector utilization;
+ /// Property: component_monitor
+ std::vector component_monitor;
// Ports
+ /// Port: propEvent
PropertyEventSupplier *propEvent;
+ /// Port: MessageEvent_out
MessageSupplierPort *MessageEvent_out;
- std::vector utilization;
private:
void construct();
};
-#endif // GPP_IMPL_BASE_H
+#endif // GPP_BASE_IMPL_BASE_H
diff --git a/GPP/cpp/Makefile.am b/GPP/cpp/Makefile.am
index 9db975e8e..e1967954a 100644
--- a/GPP/cpp/Makefile.am
+++ b/GPP/cpp/Makefile.am
@@ -26,6 +26,9 @@ xmldir = $(prefix)/dev/devices/GPP/
dist_xml_DATA = ../GPP.scd.xml ../GPP.prf.xml ../GPP.spd.xml
ACLOCAL_AMFLAGS = -I m4 -I${OSSIEHOME}/share/aclocal/ossie
+screendir = $(bindir)
+screen_DATA = $(srcdir)/gpp.screenrc
+
all-local: GPP
mkdir -p ../tests/sdr/dev/devices/GPP/cpp
cp GPP ../tests/sdr/dev/devices/GPP/cpp/
diff --git a/GPP/cpp/Makefile.am.ide b/GPP/cpp/Makefile.am.ide
index 9404e22f8..24b85f560 100644
--- a/GPP/cpp/Makefile.am.ide
+++ b/GPP/cpp/Makefile.am.ide
@@ -14,16 +14,11 @@ redhawk_SOURCES_auto += NicFacade.h
redhawk_SOURCES_auto += NicInterfaceFilter.cpp
redhawk_SOURCES_auto += NicInterfaceFilter.h
redhawk_SOURCES_auto += main.cpp
-redhawk_SOURCES_auto += reports/NicThroughputThresholdMonitor.cpp
-redhawk_SOURCES_auto += reports/NicThroughputThresholdMonitor.h
-redhawk_SOURCES_auto += reports/FreeMemoryThresholdMonitor.cpp
-redhawk_SOURCES_auto += reports/FreeMemoryThresholdMonitor.h
redhawk_SOURCES_auto += reports/Reporting.h
+redhawk_SOURCES_auto += reports/ThresholdMonitor.cpp
redhawk_SOURCES_auto += reports/ThresholdMonitor.h
redhawk_SOURCES_auto += reports/SystemMonitorReporting.cpp
redhawk_SOURCES_auto += reports/SystemMonitorReporting.h
-redhawk_SOURCES_auto += reports/CpuThresholdMonitor.cpp
-redhawk_SOURCES_auto += reports/CpuThresholdMonitor.h
redhawk_SOURCES_auto += parsers/ProcStatFileParser.cpp
redhawk_SOURCES_auto += parsers/ProcStatFileParser.h
redhawk_SOURCES_auto += parsers/PidProcStatParser.cpp
@@ -59,7 +54,6 @@ redhawk_SOURCES_auto += utils/CmdlineExecutor.cpp
redhawk_SOURCES_auto += utils/CmdlineExecutor.h
redhawk_SOURCES_auto += utils/EnvironmentPathParser.cpp
redhawk_SOURCES_auto += utils/EnvironmentPathParser.h
-redhawk_SOURCES_auto += utils/EventDispatcher.h
redhawk_SOURCES_auto += utils/FileReader.cpp
redhawk_SOURCES_auto += utils/FileReader.h
redhawk_SOURCES_auto += utils/IOError.h
diff --git a/GPP/cpp/NicFacade.cpp b/GPP/cpp/NicFacade.cpp
index e8951a0aa..ec81374b0 100644
--- a/GPP/cpp/NicFacade.cpp
+++ b/GPP/cpp/NicFacade.cpp
@@ -28,6 +28,7 @@
#include
#include
+#include
#if BOOST_FILESYSTEM_VERSION < 3
#define BOOST_PATH_STRING(x) (x)
@@ -97,6 +98,12 @@ NicFacade::poll_nic_interfaces() const
tmp << BOOST_PATH_STRING(iter->path());
boost::filesystem::path test_file( tmp.str() + "/statistics/rx_bytes" );
+ std::string operstate = tmp.str()+"/operstate";
+ std::ifstream fp(operstate.c_str());
+ std::string _state;
+ std::getline(fp, _state);
+ if (_state==std::string("down")) continue;
+
if(boost::filesystem::is_regular_file(test_file))
{
interfaces.push_back( BOOST_PATH_STRING(iter->path().filename()) );
diff --git a/GPP/cpp/affinity_struct.h b/GPP/cpp/affinity_struct.h
deleted file mode 100644
index 8278b0006..000000000
--- a/GPP/cpp/affinity_struct.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * This file is protected by Copyright. Please refer to the COPYRIGHT file
- * distributed with this source distribution.
- *
- * This file is part of REDHAWK GPP.
- *
- * REDHAWK GPP is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or (at your
- * option) any later version.
- *
- * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/.
- */
-#ifndef AFFINITY_STRUCTPROPS_H
-#define AFFINITY_STRUCTPROPS_H
-
-#include
-#include
-#include
-
-struct affinity_struct {
- affinity_struct ()
- {
- force_override = false;
- deploy_per_socket = false;
- disabled = true;
- };
-
- static std::string getId() {
- return std::string("affinity");
- };
-
- std::string exec_directive_value;
- std::string exec_directive_class;
- bool force_override;
- std::string blacklist_cpus;
- bool deploy_per_socket;
- bool disabled;
-};
-
-inline bool operator>>= (const CORBA::Any& a, affinity_struct& s) {
- CF::Properties* temp;
- if (!(a >>= temp)) return false;
- const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp);
- if (props.contains("affinity::exec_directive_value")) {
- if (!(props["affinity::exec_directive_value"] >>= s.exec_directive_value)) return false;
- }
- if (props.contains("affinity::exec_directive_class")) {
- if (!(props["affinity::exec_directive_class"] >>= s.exec_directive_class)) return false;
- }
- if (props.contains("affinity::force_override")) {
- if (!(props["affinity::force_override"] >>= s.force_override)) return false;
- }
- if (props.contains("affinity::blacklist_cpus")) {
- if (!(props["affinity::blacklist_cpus"] >>= s.blacklist_cpus)) return false;
- }
- if (props.contains("affinity::deploy_per_socket")) {
- if (!(props["affinity::deploy_per_socket"] >>= s.deploy_per_socket)) return false;
- }
- if (props.contains("affinity::disabled")) {
- if (!(props["affinity::disabled"] >>= s.disabled)) return false;
- }
- return true;
-}
-
-inline void operator<<= (CORBA::Any& a, const affinity_struct& s) {
- redhawk::PropertyMap props;
-
- props["affinity::exec_directive_value"] = s.exec_directive_value;
-
- props["affinity::exec_directive_class"] = s.exec_directive_class;
-
- props["affinity::force_override"] = s.force_override;
-
- props["affinity::blacklist_cpus"] = s.blacklist_cpus;
-
- props["affinity::deploy_per_socket"] = s.deploy_per_socket;
-
- props["affinity::disabled"] = s.disabled;
- a <<= props;
-}
-
-inline bool operator== (const affinity_struct& s1, const affinity_struct& s2) {
- if (s1.exec_directive_value!=s2.exec_directive_value)
- return false;
- if (s1.exec_directive_class!=s2.exec_directive_class)
- return false;
- if (s1.force_override!=s2.force_override)
- return false;
- if (s1.blacklist_cpus!=s2.blacklist_cpus)
- return false;
- if (s1.deploy_per_socket!=s2.deploy_per_socket)
- return false;
- if (s1.disabled!=s2.disabled)
- return false;
- return true;
-}
-
-inline bool operator!= (const affinity_struct& s1, const affinity_struct& s2) {
- return !(s1==s2);
-}
-
-
-#endif
diff --git a/GPP/cpp/build.sh b/GPP/cpp/build.sh
index 7f75c22f1..a12b32c01 100755
--- a/GPP/cpp/build.sh
+++ b/GPP/cpp/build.sh
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
#
# This file is protected by Copyright. Please refer to the COPYRIGHT file
# distributed with this source distribution.
@@ -25,5 +25,14 @@ if [ ! -e Makefile ]; then
./configure
fi
-make -j $*
+if [ $# == 1 ]; then
+ if [ $1 == 'clean' ]; then
+ make distclean
+ else
+ make -j $*
+ fi
+else
+ make -j $*
+fi
+exit $?
diff --git a/GPP/cpp/configure.ac b/GPP/cpp/configure.ac
index 573485051..4907c0181 100644
--- a/GPP/cpp/configure.ac
+++ b/GPP/cpp/configure.ac
@@ -17,7 +17,7 @@
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
-AC_INIT(GPP, 2.0.9)
+AC_INIT(GPP, 2.2.1)
AM_INIT_AUTOMAKE([foreign nostdinc subdir-objects])
AC_CONFIG_MACRO_DIR([m4])
@@ -33,7 +33,7 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
# Dependencies
export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig"
-PKG_CHECK_MODULES([PROJECTDEPS], [ossie >= 1.10 omniORB4 >= 4.1.0 ])
+PKG_CHECK_MODULES([PROJECTDEPS], [ossie >= 2.2 omniORB4 >= 4.1.0 ])
OSSIE_ENABLE_LOG4CXX
AX_BOOST_BASE([1.41])
AX_BOOST_SYSTEM
diff --git a/GPP/cpp/reconf b/GPP/cpp/reconf
index b6b303be0..22f279656 100755
--- a/GPP/cpp/reconf
+++ b/GPP/cpp/reconf
@@ -1,3 +1,4 @@
+#!/bin/sh
#
# This file is protected by Copyright. Please refer to the COPYRIGHT file
# distributed with this source distribution.
@@ -17,5 +18,8 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this program. If not, see http://www.gnu.org/licenses/.
#
+
+rm -f config.cache
[ -d m4 ] || mkdir m4
autoreconf -i
+
diff --git a/GPP/cpp/reports/CpuThresholdMonitor.cpp b/GPP/cpp/reports/CpuThresholdMonitor.cpp
deleted file mode 100644
index ce71e5940..000000000
--- a/GPP/cpp/reports/CpuThresholdMonitor.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * This file is protected by Copyright. Please refer to the COPYRIGHT file
- * distributed with this source distribution.
- *
- * This file is part of REDHAWK GPP.
- *
- * REDHAWK GPP is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or (at your
- * option) any later version.
- *
- * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/.
- */
-#include "CpuThresholdMonitor.h"
-#include "statistics/Statistics.h"
-#include "utils/ReferenceWrapper.h"
-
-class CpuUsageAccumulatorQueryFunction
-{
-public:
- CpuUsageAccumulatorQueryFunction( const CpuStatistics& cpu_usage_accumulator ):
- cpu_usage_accumulator_(cpu_usage_accumulator)
- {}
-
- float operator()() const { return cpu_usage_accumulator_.get_idle_percent(); }
-
-private:
- const CpuStatistics& cpu_usage_accumulator_;
-};
-
-CpuThresholdMonitor::CpuThresholdMonitor( const std::string& source_id,
- const float* threshold,
- const CpuStatistics & cpu_usage_accumulator,
- const bool enableDispatch ):
- GenericThresholdMonitor(source_id, GetResourceId(), GetMessageClass(), MakeCref(*threshold), CpuUsageAccumulatorQueryFunction(cpu_usage_accumulator), enableDispatch )
-{
-
-}
diff --git a/GPP/cpp/reports/CpuThresholdMonitor.h b/GPP/cpp/reports/CpuThresholdMonitor.h
deleted file mode 100644
index 2821e20de..000000000
--- a/GPP/cpp/reports/CpuThresholdMonitor.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * This file is protected by Copyright. Please refer to the COPYRIGHT file
- * distributed with this source distribution.
- *
- * This file is part of REDHAWK GPP.
- *
- * REDHAWK GPP is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or (at your
- * option) any later version.
- *
- * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/.
- */
-#ifndef CPU_THRESHOLD_MONITOR_H_
-#define CPU_THRESHOLD_MONITOR_H_
-
-#include "ThresholdMonitor.h"
-#include "statistics/Statistics.h"
-
-class CpuThresholdMonitor : public GenericThresholdMonitor
-{
-public:
- CpuThresholdMonitor( const std::string& source_id, const float* threshold, const CpuStatistics & cpu_usage_accumulator,
- const bool enableDispatch=false );
-
- static std::string GetResourceId(){ return "cpu"; }
- static std::string GetMessageClass(){ return "CPU_IDLE"; }
-};
-
-#endif
diff --git a/GPP/cpp/reports/FreeMemoryThresholdMonitor.cpp b/GPP/cpp/reports/FreeMemoryThresholdMonitor.cpp
deleted file mode 100644
index e2cff7770..000000000
--- a/GPP/cpp/reports/FreeMemoryThresholdMonitor.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * This file is protected by Copyright. Please refer to the COPYRIGHT file
- * distributed with this source distribution.
- *
- * This file is part of REDHAWK GPP.
- *
- * REDHAWK GPP is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or (at your
- * option) any later version.
- *
- * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/.
- */
-#include "FreeMemoryThresholdMonitor.h"
-#include "utils/ReferenceWrapper.h"
-
-FreeMemoryThresholdMonitor::FreeMemoryThresholdMonitor( const std::string& source_id, QueryFunction threshold, QueryFunction measured ):
-GenericThresholdMonitor(source_id, GetResourceId(), GetMessageClass(), threshold, measured )
-{
-
-}
diff --git a/GPP/cpp/reports/FreeMemoryThresholdMonitor.h b/GPP/cpp/reports/FreeMemoryThresholdMonitor.h
deleted file mode 100644
index 46498ee9e..000000000
--- a/GPP/cpp/reports/FreeMemoryThresholdMonitor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * This file is protected by Copyright. Please refer to the COPYRIGHT file
- * distributed with this source distribution.
- *
- * This file is part of REDHAWK GPP.
- *
- * REDHAWK GPP is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or (at your
- * option) any later version.
- *
- * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/.
- */
-#ifndef FREE_MEMORY_THRESHOLD_MONITOR_H_
-#define FREE_MEMORY_THRESHOLD_MONITOR_H_
-#include "ThresholdMonitor.h"
-
-class FreeMemoryThresholdMonitor : public GenericThresholdMonitor
-{
-public:
-
- FreeMemoryThresholdMonitor( const std::string& source_id, QueryFunction threshold, QueryFunction measured ) ;
-
- static std::string GetResourceId(){ return "physical_ram"; }
- static std::string GetMessageClass(){ return "MEMORY_FREE"; }
-
-};
-
-#endif
diff --git a/GPP/cpp/reports/NicThroughputThresholdMonitor.cpp b/GPP/cpp/reports/NicThroughputThresholdMonitor.cpp
deleted file mode 100644
index 4b297dc67..000000000
--- a/GPP/cpp/reports/NicThroughputThresholdMonitor.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * This file is protected by Copyright. Please refer to the COPYRIGHT file
- * distributed with this source distribution.
- *
- * This file is part of REDHAWK GPP.
- *
- * REDHAWK GPP is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or (at your
- * option) any later version.
- *
- * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/.
- */
-#include "NicThroughputThresholdMonitor.h"
-#include "../utils/ReferenceWrapper.h"
-
-NicThroughputThresholdMonitor::NicThroughputThresholdMonitor( const std::string& source_id, const std::string& resource_id, NicThroughputThresholdMonitor::QueryFunction threshold, NicThroughputThresholdMonitor::QueryFunction measured ):
-GenericThresholdMonitor >(source_id, resource_id, GetMessageClass(), threshold, measured )
-{
-}
diff --git a/GPP/cpp/reports/NicThroughputThresholdMonitor.h b/GPP/cpp/reports/NicThroughputThresholdMonitor.h
deleted file mode 100644
index 30f92dfb6..000000000
--- a/GPP/cpp/reports/NicThroughputThresholdMonitor.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * This file is protected by Copyright. Please refer to the COPYRIGHT file
- * distributed with this source distribution.
- *
- * This file is part of REDHAWK GPP.
- *
- * REDHAWK GPP is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or (at your
- * option) any later version.
- *
- * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/.
- */
-#ifndef NIC_THROUGHPUT_THRESHOLD_MONITOR_H_
-#define NIC_THROUGHPUT_THRESHOLD_MONITOR_H_
-
-#include "ThresholdMonitor.h"
-
-class NicThroughputThresholdMonitor : public GenericThresholdMonitor >
-{
-public:
- NicThroughputThresholdMonitor( const std::string& source_id, const std::string& resource_id, QueryFunction threshold, QueryFunction measured );
-
- static std::string GetMessageClass(){ return "NIC_THROUGHPUT"; }
-
- bool is_threshold_exceeded() const
- {
- if (get_threshold_value() < 0 ) return false;
- return this->GenericThresholdMonitor< float,std::greater_equal >::is_threshold_exceeded();
- }
-
- void update()
- {
- if (get_threshold_value() < 0 ) return;
- this->GenericThresholdMonitor< float,std::greater_equal >::update();
- }
-};
-
-#endif
diff --git a/GPP/cpp/reports/ThresholdMonitor.cpp b/GPP/cpp/reports/ThresholdMonitor.cpp
new file mode 100644
index 000000000..d815d5869
--- /dev/null
+++ b/GPP/cpp/reports/ThresholdMonitor.cpp
@@ -0,0 +1,128 @@
+/*
+ * This file is protected by Copyright. Please refer to the COPYRIGHT file
+ * distributed with this source distribution.
+ *
+ * This file is part of REDHAWK GPP.
+ *
+ * REDHAWK GPP is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+#include
+
+#include "ThresholdMonitor.h"
+
+ThresholdMonitor::ThresholdMonitor(const std::string& resource_id, const std::string& threshold_class):
+ resource_id_(resource_id),
+ threshold_class_(threshold_class),
+ enabled_(true),
+ prev_threshold_exceeded_(false)
+{
+}
+
+const std::string& ThresholdMonitor::get_resource_id() const
+{
+ return resource_id_;
+}
+
+const std::string& ThresholdMonitor::get_threshold_class() const
+{
+ return threshold_class_;
+}
+
+bool ThresholdMonitor::is_enabled() const
+{
+ return enabled_;
+}
+
+void ThresholdMonitor::enable()
+{
+ enabled_ = true;
+ update();
+}
+
+void ThresholdMonitor::disable()
+{
+ enabled_ = false;
+ update();
+}
+
+void ThresholdMonitor::update()
+{
+ if (enabled_) {
+ update_threshold();
+ }
+ if (prev_threshold_exceeded_ != is_threshold_exceeded()) {
+ notification_(this);
+ }
+ prev_threshold_exceeded_ = is_threshold_exceeded();
+}
+
+bool ThresholdMonitor::is_threshold_exceeded() const
+{
+ if (!enabled_) return false;
+ return check_threshold();
+}
+
+
+void FunctionThresholdMonitor::update_threshold()
+{
+ exceeded_ = callback_(this);
+}
+
+bool FunctionThresholdMonitor::check_threshold() const
+{
+ return exceeded_;
+}
+
+
+ThresholdMonitorSet::ThresholdMonitorSet(const std::string& resource_id, const std::string& threshold_class) :
+ ThresholdMonitor(resource_id, threshold_class)
+{
+}
+
+void ThresholdMonitorSet::add_monitor(const boost::shared_ptr& monitor)
+{
+ monitors_.push_back(monitor);
+}
+
+void ThresholdMonitorSet::enable()
+{
+ std::for_each(monitors_.begin(), monitors_.end(), boost::bind(&ThresholdMonitor::enable, _1));
+ ThresholdMonitor::enable();
+}
+
+void ThresholdMonitorSet::disable()
+{
+ std::for_each(monitors_.begin(), monitors_.end(), boost::bind(&ThresholdMonitor::disable, _1));
+ ThresholdMonitor::disable();
+}
+
+void ThresholdMonitorSet::update_threshold()
+{
+ std::for_each(monitors_.begin(), monitors_.end(), boost::bind(&ThresholdMonitor::update, _1));
+}
+
+bool ThresholdMonitorSet::check_threshold() const
+{
+ if (monitors_.empty()) {
+ return false;
+ }
+
+ for (MonitorList::const_iterator monitor = monitors_.begin(); monitor != monitors_.end(); ++monitor) {
+ if (!((*monitor)->is_threshold_exceeded())) {
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/GPP/cpp/reports/ThresholdMonitor.h b/GPP/cpp/reports/ThresholdMonitor.h
index 422ba8fb9..d1fdc6b94 100644
--- a/GPP/cpp/reports/ThresholdMonitor.h
+++ b/GPP/cpp/reports/ThresholdMonitor.h
@@ -19,149 +19,93 @@
*/
#ifndef THRESHOLD_MONITOR_H_
#define THRESHOLD_MONITOR_H_
+
#include
-#include
-#include
-#include
-#include
+
+#include
+
+#include
#include "utils/Updateable.h"
-#include "utils/EventDispatcher.h"
-#include "Reporting.h"
-#include "utils/ConversionWrapper.h"
-#include "struct_props.h"
-class ThresholdMonitor : public Updateable, public EventDispatcherMixin
+class ThresholdMonitor : public Updateable
{
public:
- ThresholdMonitor( const std::string& message_class, const std::string& resource_id, const bool enableDispatch=true):
- _enable_dispatch( enableDispatch),
- resource_id_(resource_id),
- message_class_(message_class)
- {}
-
- ThresholdMonitor( const std::string& source_id, const std::string& resource_id, const std::string& message_class, const bool enableDispatch=true):
- _enable_dispatch(enableDispatch),
- source_id_(source_id),
- resource_id_(resource_id),
- message_class_(message_class)
- {}
-
- virtual void update() = 0;
- //void report(){ update(); }
-
- virtual std::string get_threshold() const = 0;
- virtual std::string get_measured() const = 0;
- virtual bool is_threshold_exceeded() const = 0;
- void enable_dispatch() { _enable_dispatch=true;}
- void disable_dispatch() { _enable_dispatch=false;}
- std::string get_source_id() const{ return source_id_; }
- std::string get_resource_id() const{ return resource_id_; }
- std::string get_message_class() const{ return message_class_; }
+ ThresholdMonitor(const std::string& resource_id, const std::string& threshold_class);
-protected:
- void dispatch_message() const
- {
- if ( !_enable_dispatch ) return;
-
- threshold_event_struct message;
- message.source_id = get_source_id();
- message.resource_id = get_resource_id();
- message.threshold_class = get_message_class();
- message.type = get_message_type();
- message.threshold_value = get_threshold();
- message.measured_value = get_measured();
- message.message = get_message_string();
- message.timestamp = time(NULL);
-
- dispatch(message);
- }
- std::string get_message_type() const
- {
- return is_threshold_exceeded() ? "THRESHOLD_EXCEEDED" : "THRESHOLD_NOT_EXCEEDED";
- }
- std::string get_message_string() const
- {
- std::stringstream sstr;
- std::string exceeded_or_not( is_threshold_exceeded() ? "" : "not " );
+ const std::string& get_resource_id() const;
+ const std::string& get_threshold_class() const;
+
+ bool is_enabled() const;
+ virtual void enable();
+ virtual void disable();
- sstr << get_message_class() << " threshold " << exceeded_or_not << "exceeded "
- << "(resource_id=" << get_resource_id()
- << " threshold_value=" << get_threshold()
- << " measured_value=" << get_measured() << ")";
+ void update();
- return sstr.str();
+ bool is_threshold_exceeded() const;
+
+ template
+ void add_listener(Target target, Func func)
+ {
+ notification_.add(target, func);
}
- bool _enable_dispatch;
+protected:
+ virtual void update_threshold() = 0;
+ virtual bool check_threshold() const = 0;
-private:
- const std::string source_id_;
const std::string resource_id_;
- const std::string message_class_;
+ const std::string threshold_class_;
+ bool enabled_;
+ bool prev_threshold_exceeded_;
+ ossie::notification notification_;
};
-template >
-class GenericThresholdMonitor : public ThresholdMonitor
+class FunctionThresholdMonitor : public ThresholdMonitor
{
public:
- typedef DATA_TYPE DataType;
- typedef boost::function< DataType() > QueryFunction;
-
-public:
- GenericThresholdMonitor( const std::string& message_class, const std::string& resource_id, QueryFunction threshold, QueryFunction measured, const bool enableDispatch=true ):
-ThresholdMonitor(message_class, resource_id, enableDispatch),
- threshold_(threshold),
- measured_(measured),
- threshold_value_( threshold() ),
- measured_value_( measured() ),
- prev_threshold_exceeded_(false)
+ template
+ FunctionThresholdMonitor(const std::string& resource_id, const std::string& threshold_class, Func func) :
+ ThresholdMonitor(resource_id, threshold_class),
+ callback_(func),
+ exceeded_(false)
{
}
- GenericThresholdMonitor( const std::string& source_id, const std::string& resource_id, const std::string& message_class, QueryFunction threshold, QueryFunction measured, const bool enableDispatch=true ):
-ThresholdMonitor(source_id, resource_id, message_class, enableDispatch ),
- threshold_(threshold),
- measured_(measured),
- threshold_value_( threshold() ),
- measured_value_( measured() ),
- prev_threshold_exceeded_(false)
+ template
+ FunctionThresholdMonitor(const std::string& resource_id, const std::string& threshold_class,
+ Target target, Func func) :
+ ThresholdMonitor(resource_id, threshold_class),
+ callback_(target, func),
+ exceeded_(false)
{
}
- void update()
- {
- threshold_value_ = threshold_();
- measured_value_ = measured_();
- if( prev_threshold_exceeded_ != is_threshold_exceeded() )
- {
- dispatch_message();
- }
-
- prev_threshold_exceeded_ = is_threshold_exceeded();
- }
+private:
+ virtual void update_threshold();
+ virtual bool check_threshold() const;
- std::string get_threshold() const{ return boost::lexical_cast(threshold_value_); }
- std::string get_measured() const{ return boost::lexical_cast(measured_value_); }
+ redhawk::callback callback_;
+ bool exceeded_;
+};
- bool is_threshold_exceeded() const
- {
- return COMPARISON_FUNCTION()( get_measured_value(), get_threshold_value() );
- }
+class ThresholdMonitorSet : public ThresholdMonitor
+{
+public:
+ ThresholdMonitorSet(const std::string& resource_id, const std::string& threshold_class);
+
+ void add_monitor(const boost::shared_ptr& monitor);
- DataType get_threshold_value() const { return threshold_value_; }
- DataType get_measured_value() const { return measured_value_; }
+ virtual void enable();
+ virtual void disable();
private:
- QueryFunction threshold_;
- QueryFunction measured_;
+ virtual void update_threshold();
+ virtual bool check_threshold() const;
- DataType threshold_value_;
- DataType measured_value_;
- bool prev_threshold_exceeded_;
+ typedef std::vector< boost::shared_ptr > MonitorList;
+ MonitorList monitors_;
};
-
-
#endif
diff --git a/GPP/cpp/struct_props.h b/GPP/cpp/struct_props.h
index 75e5f3f37..30ecc02c3 100644
--- a/GPP/cpp/struct_props.h
+++ b/GPP/cpp/struct_props.h
@@ -4,15 +4,15 @@
*
* This file is part of REDHAWK GPP.
*
- * REDHAWK GPP is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or (at your
- * option) any later version.
+ * REDHAWK GPP is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
*
* REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+ * details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
@@ -28,19 +28,26 @@
#include
#include
-#include "affinity_struct.h"
+#include
struct nic_allocation_struct {
nic_allocation_struct ()
{
+ identifier = "";
data_rate = 0.0;
data_size = 1;
multicast_support = "False";
- };
+ ip_addressable = "";
+ interface = "";
+ }
static std::string getId() {
return std::string("nic_allocation");
- };
+ }
+
+ static const char* getFormat() {
+ return "sfhsss";
+ }
std::string identifier;
float data_rate;
@@ -53,77 +60,44 @@ struct nic_allocation_struct {
inline bool operator>>= (const CORBA::Any& a, nic_allocation_struct& s) {
CF::Properties* temp;
if (!(a >>= temp)) return false;
- CF::Properties& props = *temp;
- for (unsigned int idx = 0; idx < props.length(); idx++) {
- if (!strcmp("nic_allocation::identifier", props[idx].id)) {
- if (!(props[idx].value >>= s.identifier)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_allocation::data_rate", props[idx].id)) {
- if (!(props[idx].value >>= s.data_rate)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_allocation::data_size", props[idx].id)) {
- if (!(props[idx].value >>= s.data_size)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_allocation::multicast_support", props[idx].id)) {
- if (!(props[idx].value >>= s.multicast_support)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_allocation::ip_addressable", props[idx].id)) {
- if (!(props[idx].value >>= s.ip_addressable)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_allocation::interface", props[idx].id)) {
- if (!(props[idx].value >>= s.interface)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
+ const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp);
+ if (props.contains("nic_allocation::identifier")) {
+ if (!(props["nic_allocation::identifier"] >>= s.identifier)) return false;
+ }
+ if (props.contains("nic_allocation::data_rate")) {
+ if (!(props["nic_allocation::data_rate"] >>= s.data_rate)) return false;
+ }
+ if (props.contains("nic_allocation::data_size")) {
+ if (!(props["nic_allocation::data_size"] >>= s.data_size)) return false;
+ }
+ if (props.contains("nic_allocation::multicast_support")) {
+ if (!(props["nic_allocation::multicast_support"] >>= s.multicast_support)) return false;
+ }
+ if (props.contains("nic_allocation::ip_addressable")) {
+ if (!(props["nic_allocation::ip_addressable"] >>= s.ip_addressable)) return false;
+ }
+ if (props.contains("nic_allocation::interface")) {
+ if (!(props["nic_allocation::interface"] >>= s.interface)) return false;
}
return true;
-};
+}
inline void operator<<= (CORBA::Any& a, const nic_allocation_struct& s) {
- CF::Properties props;
- props.length(6);
- props[0].id = CORBA::string_dup("nic_allocation::identifier");
- props[0].value <<= s.identifier;
- props[1].id = CORBA::string_dup("nic_allocation::data_rate");
- props[1].value <<= s.data_rate;
- props[2].id = CORBA::string_dup("nic_allocation::data_size");
- props[2].value <<= s.data_size;
- props[3].id = CORBA::string_dup("nic_allocation::multicast_support");
- props[3].value <<= s.multicast_support;
- props[4].id = CORBA::string_dup("nic_allocation::ip_addressable");
- props[4].value <<= s.ip_addressable;
- props[5].id = CORBA::string_dup("nic_allocation::interface");
- props[5].value <<= s.interface;
+ redhawk::PropertyMap props;
+
+ props["nic_allocation::identifier"] = s.identifier;
+
+ props["nic_allocation::data_rate"] = s.data_rate;
+
+ props["nic_allocation::data_size"] = s.data_size;
+
+ props["nic_allocation::multicast_support"] = s.multicast_support;
+
+ props["nic_allocation::ip_addressable"] = s.ip_addressable;
+
+ props["nic_allocation::interface"] = s.interface;
a <<= props;
-};
+}
inline bool operator== (const nic_allocation_struct& s1, const nic_allocation_struct& s2) {
if (s1.identifier!=s2.identifier)
@@ -139,21 +113,25 @@ inline bool operator== (const nic_allocation_struct& s1, const nic_allocation_st
if (s1.interface!=s2.interface)
return false;
return true;
-};
+}
inline bool operator!= (const nic_allocation_struct& s1, const nic_allocation_struct& s2) {
return !(s1==s2);
-};
+}
struct advanced_struct {
advanced_struct ()
{
maximum_throughput_percentage = 80.0;
- };
+ }
static std::string getId() {
return std::string("advanced");
- };
+ }
+
+ static const char* getFormat() {
+ return "d";
+ }
double maximum_throughput_percentage;
};
@@ -161,46 +139,53 @@ struct advanced_struct {
inline bool operator>>= (const CORBA::Any& a, advanced_struct& s) {
CF::Properties* temp;
if (!(a >>= temp)) return false;
- CF::Properties& props = *temp;
- for (unsigned int idx = 0; idx < props.length(); idx++) {
- if (!strcmp("maximum_throughput_percentage", props[idx].id)) {
- if (!(props[idx].value >>= s.maximum_throughput_percentage)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
+ const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp);
+ if (props.contains("maximum_throughput_percentage")) {
+ if (!(props["maximum_throughput_percentage"] >>= s.maximum_throughput_percentage)) return false;
}
return true;
-};
+}
inline void operator<<= (CORBA::Any& a, const advanced_struct& s) {
- CF::Properties props;
- props.length(1);
- props[0].id = CORBA::string_dup("maximum_throughput_percentage");
- props[0].value <<= s.maximum_throughput_percentage;
+ redhawk::PropertyMap props;
+
+ props["maximum_throughput_percentage"] = s.maximum_throughput_percentage;
a <<= props;
-};
+}
inline bool operator== (const advanced_struct& s1, const advanced_struct& s2) {
if (s1.maximum_throughput_percentage!=s2.maximum_throughput_percentage)
return false;
return true;
-};
+}
inline bool operator!= (const advanced_struct& s1, const advanced_struct& s2) {
return !(s1==s2);
-};
+}
+
+namespace enums {
+ // Enumerated values for threshold_event
+ namespace threshold_event {
+ // Enumerated values for threshold_event::type
+ namespace type {
+ static const std::string Threshold_Exceeded = "THRESHOLD_EXCEEDED";
+ static const std::string Threshold_Not_Exceeded = "THRESHOLD_NOT_EXCEEDED";
+ }
+ }
+}
struct threshold_event_struct {
threshold_event_struct ()
{
- };
+ }
static std::string getId() {
return std::string("threshold_event");
- };
+ }
+
+ static const char* getFormat() {
+ return "sssssssd";
+ }
std::string source_id;
std::string resource_id;
@@ -215,97 +200,54 @@ struct threshold_event_struct {
inline bool operator>>= (const CORBA::Any& a, threshold_event_struct& s) {
CF::Properties* temp;
if (!(a >>= temp)) return false;
- CF::Properties& props = *temp;
- for (unsigned int idx = 0; idx < props.length(); idx++) {
- if (!strcmp("threshold_event::source_id", props[idx].id)) {
- if (!(props[idx].value >>= s.source_id)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("threshold_event::resource_id", props[idx].id)) {
- if (!(props[idx].value >>= s.resource_id)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("threshold_event::threshold_class", props[idx].id)) {
- if (!(props[idx].value >>= s.threshold_class)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("threshold_event::type", props[idx].id)) {
- if (!(props[idx].value >>= s.type)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("threshold_event::threshold_value", props[idx].id)) {
- if (!(props[idx].value >>= s.threshold_value)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("threshold_event::measured_value", props[idx].id)) {
- if (!(props[idx].value >>= s.measured_value)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("threshold_event::message", props[idx].id)) {
- if (!(props[idx].value >>= s.message)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("threshold_event::timestamp", props[idx].id)) {
- if (!(props[idx].value >>= s.timestamp)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
+ const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp);
+ if (props.contains("threshold_event::source_id")) {
+ if (!(props["threshold_event::source_id"] >>= s.source_id)) return false;
+ }
+ if (props.contains("threshold_event::resource_id")) {
+ if (!(props["threshold_event::resource_id"] >>= s.resource_id)) return false;
+ }
+ if (props.contains("threshold_event::threshold_class")) {
+ if (!(props["threshold_event::threshold_class"] >>= s.threshold_class)) return false;
+ }
+ if (props.contains("threshold_event::type")) {
+ if (!(props["threshold_event::type"] >>= s.type)) return false;
+ }
+ if (props.contains("threshold_event::threshold_value")) {
+ if (!(props["threshold_event::threshold_value"] >>= s.threshold_value)) return false;
+ }
+ if (props.contains("threshold_event::measured_value")) {
+ if (!(props["threshold_event::measured_value"] >>= s.measured_value)) return false;
+ }
+ if (props.contains("threshold_event::message")) {
+ if (!(props["threshold_event::message"] >>= s.message)) return false;
+ }
+ if (props.contains("threshold_event::timestamp")) {
+ if (!(props["threshold_event::timestamp"] >>= s.timestamp)) return false;
}
return true;
-};
+}
inline void operator<<= (CORBA::Any& a, const threshold_event_struct& s) {
- CF::Properties props;
- props.length(8);
- props[0].id = CORBA::string_dup("threshold_event::source_id");
- props[0].value <<= s.source_id;
- props[1].id = CORBA::string_dup("threshold_event::resource_id");
- props[1].value <<= s.resource_id;
- props[2].id = CORBA::string_dup("threshold_event::threshold_class");
- props[2].value <<= s.threshold_class;
- props[3].id = CORBA::string_dup("threshold_event::type");
- props[3].value <<= s.type;
- props[4].id = CORBA::string_dup("threshold_event::threshold_value");
- props[4].value <<= s.threshold_value;
- props[5].id = CORBA::string_dup("threshold_event::measured_value");
- props[5].value <<= s.measured_value;
- props[6].id = CORBA::string_dup("threshold_event::message");
- props[6].value <<= s.message;
- props[7].id = CORBA::string_dup("threshold_event::timestamp");
- props[7].value <<= s.timestamp;
+ redhawk::PropertyMap props;
+
+ props["threshold_event::source_id"] = s.source_id;
+
+ props["threshold_event::resource_id"] = s.resource_id;
+
+ props["threshold_event::threshold_class"] = s.threshold_class;
+
+ props["threshold_event::type"] = s.type;
+
+ props["threshold_event::threshold_value"] = s.threshold_value;
+
+ props["threshold_event::measured_value"] = s.measured_value;
+
+ props["threshold_event::message"] = s.message;
+
+ props["threshold_event::timestamp"] = s.timestamp;
a <<= props;
-};
+}
inline bool operator== (const threshold_event_struct& s1, const threshold_event_struct& s2) {
if (s1.source_id!=s2.source_id)
@@ -325,40 +267,50 @@ inline bool operator== (const threshold_event_struct& s1, const threshold_event_
if (s1.timestamp!=s2.timestamp)
return false;
return true;
-};
+}
inline bool operator!= (const threshold_event_struct& s1, const threshold_event_struct& s2) {
return !(s1==s2);
-};
-
+}
struct thresholds_struct {
thresholds_struct ()
{
+ ignore = false;
cpu_idle = 10;
load_avg = 80;
- mem_free = 100LL;
+ mem_free = 10LL;
nic_usage = 900;
files_available = 3;
threads = 3;
- };
+ shm_free = 10LL;
+ }
static std::string getId() {
return std::string("thresholds");
- };
+ }
+ static const char* getFormat() {
+ return "bffliffl";
+ }
+
+ bool ignore;
float cpu_idle;
float load_avg;
CORBA::LongLong mem_free;
CORBA::Long nic_usage;
float files_available;
float threads;
+ CORBA::LongLong shm_free;
};
inline bool operator>>= (const CORBA::Any& a, thresholds_struct& s) {
CF::Properties* temp;
if (!(a >>= temp)) return false;
const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp);
+ if (props.contains("ignore")) {
+ if (!(props["ignore"] >>= s.ignore)) return false;
+ }
if (props.contains("cpu_idle")) {
if (!(props["cpu_idle"] >>= s.cpu_idle)) return false;
}
@@ -377,12 +329,17 @@ inline bool operator>>= (const CORBA::Any& a, thresholds_struct& s) {
if (props.contains("threads")) {
if (!(props["threads"] >>= s.threads)) return false;
}
+ if (props.contains("shm_free")) {
+ if (!(props["shm_free"] >>= s.shm_free)) return false;
+ }
return true;
}
inline void operator<<= (CORBA::Any& a, const thresholds_struct& s) {
redhawk::PropertyMap props;
+ props["ignore"] = s.ignore;
+
props["cpu_idle"] = s.cpu_idle;
props["load_avg"] = s.load_avg;
@@ -394,10 +351,14 @@ inline void operator<<= (CORBA::Any& a, const thresholds_struct& s) {
props["files_available"] = s.files_available;
props["threads"] = s.threads;
+
+ props["shm_free"] = s.shm_free;
a <<= props;
}
inline bool operator== (const thresholds_struct& s1, const thresholds_struct& s2) {
+ if (s1.ignore!=s2.ignore)
+ return false;
if (s1.cpu_idle!=s2.cpu_idle)
return false;
if (s1.load_avg!=s2.load_avg)
@@ -410,6 +371,8 @@ inline bool operator== (const thresholds_struct& s1, const thresholds_struct& s2
return false;
if (s1.threads!=s2.threads)
return false;
+ if (s1.shm_free!=s2.shm_free)
+ return false;
return true;
}
@@ -417,14 +380,372 @@ inline bool operator!= (const thresholds_struct& s1, const thresholds_struct& s2
return !(s1==s2);
}
+struct loadAverage_struct {
+ loadAverage_struct ()
+ {
+ }
+
+ static std::string getId() {
+ return std::string("DCE:9da85ebc-6503-48e7-af36-b77c7ad0c2b4");
+ }
+
+ static const char* getFormat() {
+ return "ddd";
+ }
+
+ double onemin;
+ double fivemin;
+ double fifteenmin;
+};
+
+inline bool operator>>= (const CORBA::Any& a, loadAverage_struct& s) {
+ CF::Properties* temp;
+ if (!(a >>= temp)) return false;
+ const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp);
+ if (props.contains("onemin")) {
+ if (!(props["onemin"] >>= s.onemin)) return false;
+ }
+ if (props.contains("fivemin")) {
+ if (!(props["fivemin"] >>= s.fivemin)) return false;
+ }
+ if (props.contains("fifteenmin")) {
+ if (!(props["fifteenmin"] >>= s.fifteenmin)) return false;
+ }
+ return true;
+}
+
+inline void operator<<= (CORBA::Any& a, const loadAverage_struct& s) {
+ redhawk::PropertyMap props;
+
+ props["onemin"] = s.onemin;
+
+ props["fivemin"] = s.fivemin;
+
+ props["fifteenmin"] = s.fifteenmin;
+ a <<= props;
+}
+
+inline bool operator== (const loadAverage_struct& s1, const loadAverage_struct& s2) {
+ if (s1.onemin!=s2.onemin)
+ return false;
+ if (s1.fivemin!=s2.fivemin)
+ return false;
+ if (s1.fifteenmin!=s2.fifteenmin)
+ return false;
+ return true;
+}
+
+inline bool operator!= (const loadAverage_struct& s1, const loadAverage_struct& s2) {
+ return !(s1==s2);
+}
+
+struct gpp_limits_struct {
+ gpp_limits_struct ()
+ {
+ }
+
+ static std::string getId() {
+ return std::string("gpp_limits");
+ }
+
+ static const char* getFormat() {
+ return "iiii";
+ }
+
+ CORBA::Long current_threads;
+ CORBA::Long max_threads;
+ CORBA::Long current_open_files;
+ CORBA::Long max_open_files;
+};
+
+inline bool operator>>= (const CORBA::Any& a, gpp_limits_struct& s) {
+ CF::Properties* temp;
+ if (!(a >>= temp)) return false;
+ const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp);
+ if (props.contains("current_threads")) {
+ if (!(props["current_threads"] >>= s.current_threads)) return false;
+ }
+ if (props.contains("max_threads")) {
+ if (!(props["max_threads"] >>= s.max_threads)) return false;
+ }
+ if (props.contains("current_open_files")) {
+ if (!(props["current_open_files"] >>= s.current_open_files)) return false;
+ }
+ if (props.contains("max_open_files")) {
+ if (!(props["max_open_files"] >>= s.max_open_files)) return false;
+ }
+ return true;
+}
+
+inline void operator<<= (CORBA::Any& a, const gpp_limits_struct& s) {
+ redhawk::PropertyMap props;
+
+ props["current_threads"] = s.current_threads;
+
+ props["max_threads"] = s.max_threads;
+
+ props["current_open_files"] = s.current_open_files;
+
+ props["max_open_files"] = s.max_open_files;
+ a <<= props;
+}
+
+inline bool operator== (const gpp_limits_struct& s1, const gpp_limits_struct& s2) {
+ if (s1.current_threads!=s2.current_threads)
+ return false;
+ if (s1.max_threads!=s2.max_threads)
+ return false;
+ if (s1.current_open_files!=s2.current_open_files)
+ return false;
+ if (s1.max_open_files!=s2.max_open_files)
+ return false;
+ return true;
+}
+
+inline bool operator!= (const gpp_limits_struct& s1, const gpp_limits_struct& s2) {
+ return !(s1==s2);
+}
+
+struct sys_limits_struct {
+ sys_limits_struct ()
+ {
+ }
+
+ static std::string getId() {
+ return std::string("sys_limits");
+ }
+
+ static const char* getFormat() {
+ return "iiii";
+ }
+
+ CORBA::Long current_threads;
+ CORBA::Long max_threads;
+ CORBA::Long current_open_files;
+ CORBA::Long max_open_files;
+};
+
+inline bool operator>>= (const CORBA::Any& a, sys_limits_struct& s) {
+ CF::Properties* temp;
+ if (!(a >>= temp)) return false;
+ const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp);
+ if (props.contains("sys_limits::current_threads")) {
+ if (!(props["sys_limits::current_threads"] >>= s.current_threads)) return false;
+ }
+ if (props.contains("sys_limits::max_threads")) {
+ if (!(props["sys_limits::max_threads"] >>= s.max_threads)) return false;
+ }
+ if (props.contains("sys_limits::current_open_files")) {
+ if (!(props["sys_limits::current_open_files"] >>= s.current_open_files)) return false;
+ }
+ if (props.contains("sys_limits::max_open_files")) {
+ if (!(props["sys_limits::max_open_files"] >>= s.max_open_files)) return false;
+ }
+ return true;
+}
+
+inline void operator<<= (CORBA::Any& a, const sys_limits_struct& s) {
+ redhawk::PropertyMap props;
+
+ props["sys_limits::current_threads"] = s.current_threads;
+
+ props["sys_limits::max_threads"] = s.max_threads;
+
+ props["sys_limits::current_open_files"] = s.current_open_files;
+
+ props["sys_limits::max_open_files"] = s.max_open_files;
+ a <<= props;
+}
+
+inline bool operator== (const sys_limits_struct& s1, const sys_limits_struct& s2) {
+ if (s1.current_threads!=s2.current_threads)
+ return false;
+ if (s1.max_threads!=s2.max_threads)
+ return false;
+ if (s1.current_open_files!=s2.current_open_files)
+ return false;
+ if (s1.max_open_files!=s2.max_open_files)
+ return false;
+ return true;
+}
+
+inline bool operator!= (const sys_limits_struct& s1, const sys_limits_struct& s2) {
+ return !(s1==s2);
+}
+
+struct redhawk__reservation_request_struct {
+ redhawk__reservation_request_struct ()
+ {
+ }
+
+ static std::string getId() {
+ return std::string("redhawk::reservation_request");
+ }
+
+ static const char* getFormat() {
+ return "s[s][s]";
+ }
+
+ std::string obj_id;
+ std::vector kinds;
+ std::vector values;
+};
+
+inline bool operator>>= (const CORBA::Any& a, redhawk__reservation_request_struct& s) {
+ CF::Properties* temp;
+ if (!(a >>= temp)) return false;
+ const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp);
+ if (props.contains("redhawk::reservation_request::obj_id")) {
+ if (!(props["redhawk::reservation_request::obj_id"] >>= s.obj_id)) return false;
+ }
+ if (props.contains("redhawk::reservation_request::kinds")) {
+ if (!(props["redhawk::reservation_request::kinds"] >>= s.kinds)) return false;
+ }
+ if (props.contains("redhawk::reservation_request::values")) {
+ if (!(props["redhawk::reservation_request::values"] >>= s.values)) return false;
+ }
+ return true;
+}
+
+inline void operator<<= (CORBA::Any& a, const redhawk__reservation_request_struct& s) {
+ redhawk::PropertyMap props;
+
+ props["redhawk::reservation_request::obj_id"] = s.obj_id;
+
+ props["redhawk::reservation_request::kinds"] = s.kinds;
+
+ props["redhawk::reservation_request::values"] = s.values;
+ a <<= props;
+}
+
+inline bool operator== (const redhawk__reservation_request_struct& s1, const redhawk__reservation_request_struct& s2) {
+ if (s1.obj_id!=s2.obj_id)
+ return false;
+ if (s1.kinds!=s2.kinds)
+ return false;
+ if (s1.values!=s2.values)
+ return false;
+ return true;
+}
+
+inline bool operator!= (const redhawk__reservation_request_struct& s1, const redhawk__reservation_request_struct& s2) {
+ return !(s1==s2);
+}
+
+namespace enums {
+ // Enumerated values for affinity
+ namespace affinity {
+ // Enumerated values for affinity::exec_directive_class
+ namespace exec_directive_class {
+ static const std::string socket = "socket";
+ static const std::string nic = "nic";
+ static const std::string cpu = "cpu";
+ static const std::string cgroup = "cgroup";
+ }
+ }
+}
+
+struct affinity_struct {
+ affinity_struct ()
+ {
+ exec_directive_value = "0";
+ exec_directive_class = "socket";
+ force_override = false;
+ blacklist_cpus = "";
+ deploy_per_socket = false;
+ disabled = true;
+ }
+
+ static std::string getId() {
+ return std::string("affinity");
+ }
+
+ static const char* getFormat() {
+ return "ssbsbb";
+ }
+
+ std::string exec_directive_value;
+ std::string exec_directive_class;
+ bool force_override;
+ std::string blacklist_cpus;
+ bool deploy_per_socket;
+ bool disabled;
+};
+
+inline bool operator>>= (const CORBA::Any& a, affinity_struct& s) {
+ CF::Properties* temp;
+ if (!(a >>= temp)) return false;
+ const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp);
+ if (props.contains("affinity::exec_directive_value")) {
+ if (!(props["affinity::exec_directive_value"] >>= s.exec_directive_value)) return false;
+ }
+ if (props.contains("affinity::exec_directive_class")) {
+ if (!(props["affinity::exec_directive_class"] >>= s.exec_directive_class)) return false;
+ }
+ if (props.contains("affinity::force_override")) {
+ if (!(props["affinity::force_override"] >>= s.force_override)) return false;
+ }
+ if (props.contains("affinity::blacklist_cpus")) {
+ if (!(props["affinity::blacklist_cpus"] >>= s.blacklist_cpus)) return false;
+ }
+ if (props.contains("affinity::deploy_per_socket")) {
+ if (!(props["affinity::deploy_per_socket"] >>= s.deploy_per_socket)) return false;
+ }
+ if (props.contains("affinity::disabled")) {
+ if (!(props["affinity::disabled"] >>= s.disabled)) return false;
+ }
+ return true;
+}
+
+inline void operator<<= (CORBA::Any& a, const affinity_struct& s) {
+ redhawk::PropertyMap props;
+
+ props["affinity::exec_directive_value"] = s.exec_directive_value;
+
+ props["affinity::exec_directive_class"] = s.exec_directive_class;
+
+ props["affinity::force_override"] = s.force_override;
+
+ props["affinity::blacklist_cpus"] = s.blacklist_cpus;
+
+ props["affinity::deploy_per_socket"] = s.deploy_per_socket;
+
+ props["affinity::disabled"] = s.disabled;
+ a <<= props;
+}
+
+inline bool operator== (const affinity_struct& s1, const affinity_struct& s2) {
+ if (s1.exec_directive_value!=s2.exec_directive_value)
+ return false;
+ if (s1.exec_directive_class!=s2.exec_directive_class)
+ return false;
+ if (s1.force_override!=s2.force_override)
+ return false;
+ if (s1.blacklist_cpus!=s2.blacklist_cpus)
+ return false;
+ if (s1.deploy_per_socket!=s2.deploy_per_socket)
+ return false;
+ if (s1.disabled!=s2.disabled)
+ return false;
+ return true;
+}
+
+inline bool operator!= (const affinity_struct& s1, const affinity_struct& s2) {
+ return !(s1==s2);
+}
+
struct nic_allocation_status_struct_struct {
nic_allocation_status_struct_struct ()
{
- };
+ }
static std::string getId() {
return std::string("nic_allocation_status_struct");
- };
+ }
+
+ static const char* getFormat() {
+ return "sfhsss";
+ }
std::string identifier;
float data_rate;
@@ -437,77 +758,44 @@ struct nic_allocation_status_struct_struct {
inline bool operator>>= (const CORBA::Any& a, nic_allocation_status_struct_struct& s) {
CF::Properties* temp;
if (!(a >>= temp)) return false;
- CF::Properties& props = *temp;
- for (unsigned int idx = 0; idx < props.length(); idx++) {
- if (!strcmp("nic_allocation_status::identifier", props[idx].id)) {
- if (!(props[idx].value >>= s.identifier)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_allocation_status::data_rate", props[idx].id)) {
- if (!(props[idx].value >>= s.data_rate)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_allocation_status::data_size", props[idx].id)) {
- if (!(props[idx].value >>= s.data_size)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_allocation_status::multicast_support", props[idx].id)) {
- if (!(props[idx].value >>= s.multicast_support)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_allocation_status::ip_addressable", props[idx].id)) {
- if (!(props[idx].value >>= s.ip_addressable)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_allocation_status::interface", props[idx].id)) {
- if (!(props[idx].value >>= s.interface)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
+ const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp);
+ if (props.contains("nic_allocation_status::identifier")) {
+ if (!(props["nic_allocation_status::identifier"] >>= s.identifier)) return false;
+ }
+ if (props.contains("nic_allocation_status::data_rate")) {
+ if (!(props["nic_allocation_status::data_rate"] >>= s.data_rate)) return false;
+ }
+ if (props.contains("nic_allocation_status::data_size")) {
+ if (!(props["nic_allocation_status::data_size"] >>= s.data_size)) return false;
+ }
+ if (props.contains("nic_allocation_status::multicast_support")) {
+ if (!(props["nic_allocation_status::multicast_support"] >>= s.multicast_support)) return false;
+ }
+ if (props.contains("nic_allocation_status::ip_addressable")) {
+ if (!(props["nic_allocation_status::ip_addressable"] >>= s.ip_addressable)) return false;
+ }
+ if (props.contains("nic_allocation_status::interface")) {
+ if (!(props["nic_allocation_status::interface"] >>= s.interface)) return false;
}
return true;
-};
+}
inline void operator<<= (CORBA::Any& a, const nic_allocation_status_struct_struct& s) {
- CF::Properties props;
- props.length(6);
- props[0].id = CORBA::string_dup("nic_allocation_status::identifier");
- props[0].value <<= s.identifier;
- props[1].id = CORBA::string_dup("nic_allocation_status::data_rate");
- props[1].value <<= s.data_rate;
- props[2].id = CORBA::string_dup("nic_allocation_status::data_size");
- props[2].value <<= s.data_size;
- props[3].id = CORBA::string_dup("nic_allocation_status::multicast_support");
- props[3].value <<= s.multicast_support;
- props[4].id = CORBA::string_dup("nic_allocation_status::ip_addressable");
- props[4].value <<= s.ip_addressable;
- props[5].id = CORBA::string_dup("nic_allocation_status::interface");
- props[5].value <<= s.interface;
+ redhawk::PropertyMap props;
+
+ props["nic_allocation_status::identifier"] = s.identifier;
+
+ props["nic_allocation_status::data_rate"] = s.data_rate;
+
+ props["nic_allocation_status::data_size"] = s.data_size;
+
+ props["nic_allocation_status::multicast_support"] = s.multicast_support;
+
+ props["nic_allocation_status::ip_addressable"] = s.ip_addressable;
+
+ props["nic_allocation_status::interface"] = s.interface;
a <<= props;
-};
+}
inline bool operator== (const nic_allocation_status_struct_struct& s1, const nic_allocation_status_struct_struct& s2) {
if (s1.identifier!=s2.identifier)
@@ -523,25 +811,55 @@ inline bool operator== (const nic_allocation_status_struct_struct& s1, const nic
if (s1.interface!=s2.interface)
return false;
return true;
-};
+}
inline bool operator!= (const nic_allocation_status_struct_struct& s1, const nic_allocation_status_struct_struct& s2) {
return !(s1==s2);
-};
+}
struct nic_metrics_struct_struct {
nic_metrics_struct_struct ()
{
+ interface = "";
+ mac_address = "";
rate = 0.0;
+ ipv4_address = "";
+ ipv4_netmask = "";
+ ipv4_broadcast = "";
+ ipv6_address = "";
+ ipv6_netmask = "";
+ ipv6_scope = "";
+ flags = "";
+ module = "";
+ mtu = "";
+ state = "";
+ rx_bytes = "";
+ rx_compressed = "";
+ rx_crc_errors = "";
+ rx_dropped = "";
+ rx_errors = "";
+ rx_packets = "";
+ tx_bytes = "";
+ tx_compressed = "";
+ tx_dropped = "";
+ tx_errors = "";
+ tx_packets = "";
+ tx_queue_len = "";
+ vlans = "";
multicast_support = false;
rate_allocated = 0;
+ time_string_utc = "";
time = 0;
current_throughput = 0;
- };
+ }
static std::string getId() {
return std::string("nic_metrics_struct");
- };
+ }
+
+ static const char* getFormat() {
+ return "ssdsssssssssssssssssssssssbdsdd";
+ }
std::string interface;
std::string mac_address;
@@ -579,327 +897,169 @@ struct nic_metrics_struct_struct {
inline bool operator>>= (const CORBA::Any& a, nic_metrics_struct_struct& s) {
CF::Properties* temp;
if (!(a >>= temp)) return false;
- CF::Properties& props = *temp;
- for (unsigned int idx = 0; idx < props.length(); idx++) {
- if (!strcmp("nic_metrics::interface", props[idx].id)) {
- if (!(props[idx].value >>= s.interface)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::mac_address", props[idx].id)) {
- if (!(props[idx].value >>= s.mac_address)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::rate", props[idx].id)) {
- if (!(props[idx].value >>= s.rate)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::ipv4_address", props[idx].id)) {
- if (!(props[idx].value >>= s.ipv4_address)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::ipv4_netmask", props[idx].id)) {
- if (!(props[idx].value >>= s.ipv4_netmask)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::ipv4_broadcast", props[idx].id)) {
- if (!(props[idx].value >>= s.ipv4_broadcast)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::ipv6_address", props[idx].id)) {
- if (!(props[idx].value >>= s.ipv6_address)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::ipv6_netmask", props[idx].id)) {
- if (!(props[idx].value >>= s.ipv6_netmask)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::ipv6_scope", props[idx].id)) {
- if (!(props[idx].value >>= s.ipv6_scope)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::flags", props[idx].id)) {
- if (!(props[idx].value >>= s.flags)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::module", props[idx].id)) {
- if (!(props[idx].value >>= s.module)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::mtu", props[idx].id)) {
- if (!(props[idx].value >>= s.mtu)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::state", props[idx].id)) {
- if (!(props[idx].value >>= s.state)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::rx_bytes", props[idx].id)) {
- if (!(props[idx].value >>= s.rx_bytes)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::rx_compressed", props[idx].id)) {
- if (!(props[idx].value >>= s.rx_compressed)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::rx_crc_errors", props[idx].id)) {
- if (!(props[idx].value >>= s.rx_crc_errors)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::rx_dropped", props[idx].id)) {
- if (!(props[idx].value >>= s.rx_dropped)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::rx_errors", props[idx].id)) {
- if (!(props[idx].value >>= s.rx_errors)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::rx_packets", props[idx].id)) {
- if (!(props[idx].value >>= s.rx_packets)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::tx_bytes", props[idx].id)) {
- if (!(props[idx].value >>= s.tx_bytes)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::tx_compressed", props[idx].id)) {
- if (!(props[idx].value >>= s.tx_compressed)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::tx_dropped", props[idx].id)) {
- if (!(props[idx].value >>= s.tx_dropped)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::tx_errors", props[idx].id)) {
- if (!(props[idx].value >>= s.tx_errors)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::tx_packets", props[idx].id)) {
- if (!(props[idx].value >>= s.tx_packets)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::tx_queue_len", props[idx].id)) {
- if (!(props[idx].value >>= s.tx_queue_len)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::vlans", props[idx].id)) {
- if (!(props[idx].value >>= s.vlans)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::multicast_support", props[idx].id)) {
- if (!(props[idx].value >>= s.multicast_support)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::rate_allocated", props[idx].id)) {
- if (!(props[idx].value >>= s.rate_allocated)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::time_string_utc", props[idx].id)) {
- if (!(props[idx].value >>= s.time_string_utc)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::time", props[idx].id)) {
- if (!(props[idx].value >>= s.time)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("nic_metrics::current_throughput", props[idx].id)) {
- if (!(props[idx].value >>= s.current_throughput)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
+ const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp);
+ if (props.contains("nic_metrics::interface")) {
+ if (!(props["nic_metrics::interface"] >>= s.interface)) return false;
+ }
+ if (props.contains("nic_metrics::mac_address")) {
+ if (!(props["nic_metrics::mac_address"] >>= s.mac_address)) return false;
+ }
+ if (props.contains("nic_metrics::rate")) {
+ if (!(props["nic_metrics::rate"] >>= s.rate)) return false;
+ }
+ if (props.contains("nic_metrics::ipv4_address")) {
+ if (!(props["nic_metrics::ipv4_address"] >>= s.ipv4_address)) return false;
+ }
+ if (props.contains("nic_metrics::ipv4_netmask")) {
+ if (!(props["nic_metrics::ipv4_netmask"] >>= s.ipv4_netmask)) return false;
+ }
+ if (props.contains("nic_metrics::ipv4_broadcast")) {
+ if (!(props["nic_metrics::ipv4_broadcast"] >>= s.ipv4_broadcast)) return false;
+ }
+ if (props.contains("nic_metrics::ipv6_address")) {
+ if (!(props["nic_metrics::ipv6_address"] >>= s.ipv6_address)) return false;
+ }
+ if (props.contains("nic_metrics::ipv6_netmask")) {
+ if (!(props["nic_metrics::ipv6_netmask"] >>= s.ipv6_netmask)) return false;
+ }
+ if (props.contains("nic_metrics::ipv6_scope")) {
+ if (!(props["nic_metrics::ipv6_scope"] >>= s.ipv6_scope)) return false;
+ }
+ if (props.contains("nic_metrics::flags")) {
+ if (!(props["nic_metrics::flags"] >>= s.flags)) return false;
+ }
+ if (props.contains("nic_metrics::module")) {
+ if (!(props["nic_metrics::module"] >>= s.module)) return false;
+ }
+ if (props.contains("nic_metrics::mtu")) {
+ if (!(props["nic_metrics::mtu"] >>= s.mtu)) return false;
+ }
+ if (props.contains("nic_metrics::state")) {
+ if (!(props["nic_metrics::state"] >>= s.state)) return false;
+ }
+ if (props.contains("nic_metrics::rx_bytes")) {
+ if (!(props["nic_metrics::rx_bytes"] >>= s.rx_bytes)) return false;
+ }
+ if (props.contains("nic_metrics::rx_compressed")) {
+ if (!(props["nic_metrics::rx_compressed"] >>= s.rx_compressed)) return false;
+ }
+ if (props.contains("nic_metrics::rx_crc_errors")) {
+ if (!(props["nic_metrics::rx_crc_errors"] >>= s.rx_crc_errors)) return false;
+ }
+ if (props.contains("nic_metrics::rx_dropped")) {
+ if (!(props["nic_metrics::rx_dropped"] >>= s.rx_dropped)) return false;
+ }
+ if (props.contains("nic_metrics::rx_errors")) {
+ if (!(props["nic_metrics::rx_errors"] >>= s.rx_errors)) return false;
+ }
+ if (props.contains("nic_metrics::rx_packets")) {
+ if (!(props["nic_metrics::rx_packets"] >>= s.rx_packets)) return false;
+ }
+ if (props.contains("nic_metrics::tx_bytes")) {
+ if (!(props["nic_metrics::tx_bytes"] >>= s.tx_bytes)) return false;
+ }
+ if (props.contains("nic_metrics::tx_compressed")) {
+ if (!(props["nic_metrics::tx_compressed"] >>= s.tx_compressed)) return false;
+ }
+ if (props.contains("nic_metrics::tx_dropped")) {
+ if (!(props["nic_metrics::tx_dropped"] >>= s.tx_dropped)) return false;
+ }
+ if (props.contains("nic_metrics::tx_errors")) {
+ if (!(props["nic_metrics::tx_errors"] >>= s.tx_errors)) return false;
+ }
+ if (props.contains("nic_metrics::tx_packets")) {
+ if (!(props["nic_metrics::tx_packets"] >>= s.tx_packets)) return false;
+ }
+ if (props.contains("nic_metrics::tx_queue_len")) {
+ if (!(props["nic_metrics::tx_queue_len"] >>= s.tx_queue_len)) return false;
+ }
+ if (props.contains("nic_metrics::vlans")) {
+ if (!(props["nic_metrics::vlans"] >>= s.vlans)) return false;
+ }
+ if (props.contains("nic_metrics::multicast_support")) {
+ if (!(props["nic_metrics::multicast_support"] >>= s.multicast_support)) return false;
+ }
+ if (props.contains("nic_metrics::rate_allocated")) {
+ if (!(props["nic_metrics::rate_allocated"] >>= s.rate_allocated)) return false;
+ }
+ if (props.contains("nic_metrics::time_string_utc")) {
+ if (!(props["nic_metrics::time_string_utc"] >>= s.time_string_utc)) return false;
+ }
+ if (props.contains("nic_metrics::time")) {
+ if (!(props["nic_metrics::time"] >>= s.time)) return false;
+ }
+ if (props.contains("nic_metrics::current_throughput")) {
+ if (!(props["nic_metrics::current_throughput"] >>= s.current_throughput)) return false;
}
return true;
-};
+}
inline void operator<<= (CORBA::Any& a, const nic_metrics_struct_struct& s) {
- CF::Properties props;
- props.length(31);
- props[0].id = CORBA::string_dup("nic_metrics::interface");
- props[0].value <<= s.interface;
- props[1].id = CORBA::string_dup("nic_metrics::mac_address");
- props[1].value <<= s.mac_address;
- props[2].id = CORBA::string_dup("nic_metrics::rate");
- props[2].value <<= s.rate;
- props[3].id = CORBA::string_dup("nic_metrics::ipv4_address");
- props[3].value <<= s.ipv4_address;
- props[4].id = CORBA::string_dup("nic_metrics::ipv4_netmask");
- props[4].value <<= s.ipv4_netmask;
- props[5].id = CORBA::string_dup("nic_metrics::ipv4_broadcast");
- props[5].value <<= s.ipv4_broadcast;
- props[6].id = CORBA::string_dup("nic_metrics::ipv6_address");
- props[6].value <<= s.ipv6_address;
- props[7].id = CORBA::string_dup("nic_metrics::ipv6_netmask");
- props[7].value <<= s.ipv6_netmask;
- props[8].id = CORBA::string_dup("nic_metrics::ipv6_scope");
- props[8].value <<= s.ipv6_scope;
- props[9].id = CORBA::string_dup("nic_metrics::flags");
- props[9].value <<= s.flags;
- props[10].id = CORBA::string_dup("nic_metrics::module");
- props[10].value <<= s.module;
- props[11].id = CORBA::string_dup("nic_metrics::mtu");
- props[11].value <<= s.mtu;
- props[12].id = CORBA::string_dup("nic_metrics::state");
- props[12].value <<= s.state;
- props[13].id = CORBA::string_dup("nic_metrics::rx_bytes");
- props[13].value <<= s.rx_bytes;
- props[14].id = CORBA::string_dup("nic_metrics::rx_compressed");
- props[14].value <<= s.rx_compressed;
- props[15].id = CORBA::string_dup("nic_metrics::rx_crc_errors");
- props[15].value <<= s.rx_crc_errors;
- props[16].id = CORBA::string_dup("nic_metrics::rx_dropped");
- props[16].value <<= s.rx_dropped;
- props[17].id = CORBA::string_dup("nic_metrics::rx_errors");
- props[17].value <<= s.rx_errors;
- props[18].id = CORBA::string_dup("nic_metrics::rx_packets");
- props[18].value <<= s.rx_packets;
- props[19].id = CORBA::string_dup("nic_metrics::tx_bytes");
- props[19].value <<= s.tx_bytes;
- props[20].id = CORBA::string_dup("nic_metrics::tx_compressed");
- props[20].value <<= s.tx_compressed;
- props[21].id = CORBA::string_dup("nic_metrics::tx_dropped");
- props[21].value <<= s.tx_dropped;
- props[22].id = CORBA::string_dup("nic_metrics::tx_errors");
- props[22].value <<= s.tx_errors;
- props[23].id = CORBA::string_dup("nic_metrics::tx_packets");
- props[23].value <<= s.tx_packets;
- props[24].id = CORBA::string_dup("nic_metrics::tx_queue_len");
- props[24].value <<= s.tx_queue_len;
- props[25].id = CORBA::string_dup("nic_metrics::vlans");
- props[25].value <<= s.vlans;
- props[26].id = CORBA::string_dup("nic_metrics::multicast_support");
- props[26].value <<= s.multicast_support;
- props[27].id = CORBA::string_dup("nic_metrics::rate_allocated");
- props[27].value <<= s.rate_allocated;
- props[28].id = CORBA::string_dup("nic_metrics::time_string_utc");
- props[28].value <<= s.time_string_utc;
- props[29].id = CORBA::string_dup("nic_metrics::time");
- props[29].value <<= s.time;
- props[30].id = CORBA::string_dup("nic_metrics::current_throughput");
- props[30].value <<= s.current_throughput;
+ redhawk::PropertyMap props;
+
+ props["nic_metrics::interface"] = s.interface;
+
+ props["nic_metrics::mac_address"] = s.mac_address;
+
+ props["nic_metrics::rate"] = s.rate;
+
+ props["nic_metrics::ipv4_address"] = s.ipv4_address;
+
+ props["nic_metrics::ipv4_netmask"] = s.ipv4_netmask;
+
+ props["nic_metrics::ipv4_broadcast"] = s.ipv4_broadcast;
+
+ props["nic_metrics::ipv6_address"] = s.ipv6_address;
+
+ props["nic_metrics::ipv6_netmask"] = s.ipv6_netmask;
+
+ props["nic_metrics::ipv6_scope"] = s.ipv6_scope;
+
+ props["nic_metrics::flags"] = s.flags;
+
+ props["nic_metrics::module"] = s.module;
+
+ props["nic_metrics::mtu"] = s.mtu;
+
+ props["nic_metrics::state"] = s.state;
+
+ props["nic_metrics::rx_bytes"] = s.rx_bytes;
+
+ props["nic_metrics::rx_compressed"] = s.rx_compressed;
+
+ props["nic_metrics::rx_crc_errors"] = s.rx_crc_errors;
+
+ props["nic_metrics::rx_dropped"] = s.rx_dropped;
+
+ props["nic_metrics::rx_errors"] = s.rx_errors;
+
+ props["nic_metrics::rx_packets"] = s.rx_packets;
+
+ props["nic_metrics::tx_bytes"] = s.tx_bytes;
+
+ props["nic_metrics::tx_compressed"] = s.tx_compressed;
+
+ props["nic_metrics::tx_dropped"] = s.tx_dropped;
+
+ props["nic_metrics::tx_errors"] = s.tx_errors;
+
+ props["nic_metrics::tx_packets"] = s.tx_packets;
+
+ props["nic_metrics::tx_queue_len"] = s.tx_queue_len;
+
+ props["nic_metrics::vlans"] = s.vlans;
+
+ props["nic_metrics::multicast_support"] = s.multicast_support;
+
+ props["nic_metrics::rate_allocated"] = s.rate_allocated;
+
+ props["nic_metrics::time_string_utc"] = s.time_string_utc;
+
+ props["nic_metrics::time"] = s.time;
+
+ props["nic_metrics::current_throughput"] = s.current_throughput;
a <<= props;
-};
+}
inline bool operator== (const nic_metrics_struct_struct& s1, const nic_metrics_struct_struct& s2) {
if (s1.interface!=s2.interface)
@@ -965,20 +1125,24 @@ inline bool operator== (const nic_metrics_struct_struct& s1, const nic_metrics_s
if (s1.current_throughput!=s2.current_throughput)
return false;
return true;
-};
+}
inline bool operator!= (const nic_metrics_struct_struct& s1, const nic_metrics_struct_struct& s2) {
return !(s1==s2);
-};
+}
struct interfaces_struct {
interfaces_struct ()
{
- };
+ }
static std::string getId() {
return std::string("interfaces");
- };
+ }
+
+ static const char* getFormat() {
+ return "sfs";
+ }
std::string interface;
float throughput;
@@ -986,135 +1150,58 @@ struct interfaces_struct {
};
inline bool operator>>= (const CORBA::Any& a, interfaces_struct& s) {
- CF::Properties* temp;
- if (!(a >>= temp)) return false;
- CF::Properties& props = *temp;
- for (unsigned int idx = 0; idx < props.length(); idx++) {
- if (!strcmp("interface", props[idx].id)) {
- if (!(props[idx].value >>= s.interface)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("throughput", props[idx].id)) {
- if (!(props[idx].value >>= s.throughput)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- else if (!strcmp("vlans", props[idx].id)) {
- if (!(props[idx].value >>= s.vlans)) {
- CORBA::TypeCode_var typecode = props[idx].value.type();
- if (typecode->kind() != CORBA::tk_null) {
- return false;
- }
- }
- }
- }
- return true;
-};
-
-inline void operator<<= (CORBA::Any& a, const interfaces_struct& s) {
- CF::Properties props;
- props.length(3);
- props[0].id = CORBA::string_dup("interface");
- props[0].value <<= s.interface;
- props[1].id = CORBA::string_dup("throughput");
- props[1].value <<= s.throughput;
- props[2].id = CORBA::string_dup("vlans");
- props[2].value <<= s.vlans;
- a <<= props;
-};
-
-inline bool operator== (const interfaces_struct& s1, const interfaces_struct& s2) {
- if (s1.interface!=s2.interface)
- return false;
- if (s1.throughput!=s2.throughput)
- return false;
- if (s1.vlans!=s2.vlans)
- return false;
- return true;
-};
-
-inline bool operator!= (const interfaces_struct& s1, const interfaces_struct& s2) {
- return !(s1==s2);
-};
-
-struct ulimit_struct {
- ulimit_struct ()
- {
- };
-
- static std::string getId() {
- return std::string("ulimit");
- };
-
- CORBA::Long current_threads;
- CORBA::Long max_threads;
- CORBA::Long current_open_files;
- CORBA::Long max_open_files;
-};
-
-inline bool operator>>= (const CORBA::Any& a, ulimit_struct& s) {
CF::Properties* temp;
if (!(a >>= temp)) return false;
const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp);
- if (props.contains("current_threads")) {
- if (!(props["current_threads"] >>= s.current_threads)) return false;
- }
- if (props.contains("max_threads")) {
- if (!(props["max_threads"] >>= s.max_threads)) return false;
+ if (props.contains("interface")) {
+ if (!(props["interface"] >>= s.interface)) return false;
}
- if (props.contains("current_open_files")) {
- if (!(props["current_open_files"] >>= s.current_open_files)) return false;
+ if (props.contains("throughput")) {
+ if (!(props["throughput"] >>= s.throughput)) return false;
}
- if (props.contains("max_open_files")) {
- if (!(props["max_open_files"] >>= s.max_open_files)) return false;
+ if (props.contains("vlans")) {
+ if (!(props["vlans"] >>= s.vlans)) return false;
}
return true;
}
-inline void operator<<= (CORBA::Any& a, const ulimit_struct& s) {
+inline void operator<<= (CORBA::Any& a, const interfaces_struct& s) {
redhawk::PropertyMap props;
- props["current_threads"] = s.current_threads;
-
- props["max_threads"] = s.max_threads;
+ props["interface"] = s.interface;
- props["current_open_files"] = s.current_open_files;
+ props["throughput"] = s.throughput;
- props["max_open_files"] = s.max_open_files;
+ props["vlans"] = s.vlans;
a <<= props;
}
-inline bool operator== (const ulimit_struct& s1, const ulimit_struct& s2) {
- if (s1.current_threads!=s2.current_threads)
- return false;
- if (s1.max_threads!=s2.max_threads)
+inline bool operator== (const interfaces_struct& s1, const interfaces_struct& s2) {
+ if (s1.interface!=s2.interface)
return false;
- if (s1.current_open_files!=s2.current_open_files)
+ if (s1.throughput!=s2.throughput)
return false;
- if (s1.max_open_files!=s2.max_open_files)
+ if (s1.vlans!=s2.vlans)
return false;
return true;
}
-inline bool operator!= (const ulimit_struct& s1, const ulimit_struct& s2) {
+inline bool operator!= (const interfaces_struct& s1, const interfaces_struct& s2) {
return !(s1==s2);
}
struct utilization_entry_struct {
utilization_entry_struct ()
{
- };
+ }
static std::string getId() {
return std::string("utilization_entry");
- };
+ }
+
+ static const char* getFormat() {
+ return "sffff";
+ }
std::string description;
float component_load;
@@ -1177,69 +1264,19 @@ inline bool operator== (const utilization_entry_struct& s1, const utilization_en
inline bool operator!= (const utilization_entry_struct& s1, const utilization_entry_struct& s2) {
return !(s1==s2);
}
-struct loadAverage_struct {
- loadAverage_struct ()
- {
- };
-
- static std::string getId() {
- return std::string("DCE:9da85ebc-6503-48e7-af36-b77c7ad0c2b4");
- };
-
- double onemin;
- double fivemin;
- double fifteenmin;
-};
-
-inline bool operator>>= (const CORBA::Any& a, loadAverage_struct& s) {
- CF::Properties* temp;
- if (!(a >>= temp)) return false;
- const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp);
- if (props.contains("onemin")) {
- if (!(props["onemin"] >>= s.onemin)) return false;
- }
- if (props.contains("fivemin")) {
- if (!(props["fivemin"] >>= s.fivemin)) return false;
- }
- if (props.contains("fifteenmin")) {
- if (!(props["fifteenmin"] >>= s.fifteenmin)) return false;
- }
- return true;
-}
-
-inline void operator<<= (CORBA::Any& a, const loadAverage_struct& s) {
- redhawk::PropertyMap props;
-
- props["onemin"] = s.onemin;
-
- props["fivemin"] = s.fivemin;
-
- props["fifteenmin"] = s.fifteenmin;
- a <<= props;
-}
-
-inline bool operator== (const loadAverage_struct& s1, const loadAverage_struct& s2) {
- if (s1.onemin!=s2.onemin)
- return false;
- if (s1.fivemin!=s2.fivemin)
- return false;
- if (s1.fifteenmin!=s2.fifteenmin)
- return false;
- return true;
-}
-
-inline bool operator!= (const loadAverage_struct& s1, const loadAverage_struct& s2) {
- return !(s1==s2);
-}
struct component_monitor_struct {
component_monitor_struct ()
{
- };
+ }
static std::string getId() {
return std::string("component_monitor::component_monitor");
- };
+ }
+
+ static const char* getFormat() {
+ return "ssHfffIII";
+ }
std::string component_id;
std::string waveform_id;
@@ -1334,67 +1371,5 @@ inline bool operator== (const component_monitor_struct& s1, const component_moni
inline bool operator!= (const component_monitor_struct& s1, const component_monitor_struct& s2) {
return !(s1==s2);
}
-struct sys_limits_struct {
- sys_limits_struct ()
- {
- };
-
- static std::string getId() {
- return std::string("sys_limits");
- };
-
- CORBA::Long current_threads;
- CORBA::Long max_threads;
- CORBA::Long current_open_files;
- CORBA::Long max_open_files;
-};
-
-inline bool operator>>= (const CORBA::Any& a, sys_limits_struct& s) {
- CF::Properties* temp;
- if (!(a >>= temp)) return false;
- const redhawk::PropertyMap& props = redhawk::PropertyMap::cast(*temp);
- if (props.contains("sys_limits::current_threads")) {
- if (!(props["sys_limits::current_threads"] >>= s.current_threads)) return false;
- }
- if (props.contains("sys_limits::max_threads")) {
- if (!(props["sys_limits::max_threads"] >>= s.max_threads)) return false;
- }
- if (props.contains("sys_limits::current_open_files")) {
- if (!(props["sys_limits::current_open_files"] >>= s.current_open_files)) return false;
- }
- if (props.contains("sys_limits::max_open_files")) {
- if (!(props["sys_limits::max_open_files"] >>= s.max_open_files)) return false;
- }
- return true;
-}
-
-inline void operator<<= (CORBA::Any& a, const sys_limits_struct& s) {
- redhawk::PropertyMap props;
-
- props["sys_limits::current_threads"] = s.current_threads;
-
- props["sys_limits::max_threads"] = s.max_threads;
-
- props["sys_limits::current_open_files"] = s.current_open_files;
-
- props["sys_limits::max_open_files"] = s.max_open_files;
- a <<= props;
-}
-
-inline bool operator== (const sys_limits_struct& s1, const sys_limits_struct& s2) {
- if (s1.current_threads!=s2.current_threads)
- return false;
- if (s1.max_threads!=s2.max_threads)
- return false;
- if (s1.current_open_files!=s2.current_open_files)
- return false;
- if (s1.max_open_files!=s2.max_open_files)
- return false;
- return true;
-}
-
-inline bool operator!= (const sys_limits_struct& s1, const sys_limits_struct& s2) {
- return !(s1==s2);
-}
#endif // STRUCTPROPS_H
diff --git a/GPP/cpp/utils/EventDispatcher.h b/GPP/cpp/utils/EventDispatcher.h
deleted file mode 100644
index 87eb228b2..000000000
--- a/GPP/cpp/utils/EventDispatcher.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * This file is protected by Copyright. Please refer to the COPYRIGHT file
- * distributed with this source distribution.
- *
- * This file is part of REDHAWK GPP.
- *
- * REDHAWK GPP is free software: you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by the
- * Free Software Foundation, either version 3 of the License, or (at your
- * option) any later version.
- *
- * REDHAWK GPP is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see http://www.gnu.org/licenses/.
- */
-#ifndef EVENT_DISPATCHER_H_
-#define EVENT_DISPATCHER_H_
-
-#include
-#include
-
-#include
-
-/**
- * EventDispatcher uses the Observer pattern to dispatch events to 1 or more
- * attached event listeners. Listeners are registered as callback functions
- * in attach_listener() and called in sequence during dispatch().
- */
-template
-class EventDispatcher
-{
-public:
- typedef MESSAGE_TYPE MessageType;
- typedef boost::function< void (const MessageType&) > EventHandler;
- typedef std::vector EventHandlers;
-
-public:
- void attach_listener( const EventHandler& handler )
- {
- event_handlers_.push_back(handler);
- }
-
- void dispatch( const MessageType& message ) const
- {
- typename EventHandlers::const_iterator iter = event_handlers_.begin();
- typename EventHandlers::const_iterator end = event_handlers_.end();
- for( ; iter!=end; ++iter )
- {
- (*iter)(message);
- }
- }
-
-private:
- EventHandlers event_handlers_;
-};
-
-/**
- * EventDispatcherMixin adds event dispatching semantics to child classes.
- * attach_listener() is exposed as a public method, as this is the client-
- * facing operation for event dispatching classes. dispatch() is
- * exposed as protected, as it is expected for the event dispatching class to
- * call dispatch() itself.
- *
- * Use the EventDispatcher class directly for cases where attach_listener()
- * and dispatch() need to be called by the same object.
- */
-template
-class EventDispatcherMixin
-{
-public:
- typedef typename EventDispatcher::EventHandler EventHandler;
- typedef typename EventDispatcher::MessageType MessageType;
-
-protected:
- virtual ~EventDispatcherMixin(){}
-
-public:
- void attach_listener( const EventHandler& handler )
- {
- event_dispatcher_.attach_listener(handler);
- }
-
-protected:
- void dispatch( const MessageType& message ) const
- {
- event_dispatcher_.dispatch(message);
- }
-
-private:
- EventDispatcher event_dispatcher_;
-};
-
-#endif
diff --git a/GPP/cpp/utils/affinity.cpp b/GPP/cpp/utils/affinity.cpp
index c5709bc31..f2a93f06e 100644
--- a/GPP/cpp/utils/affinity.cpp
+++ b/GPP/cpp/utils/affinity.cpp
@@ -305,7 +305,6 @@ namespace gpp {
os << numa_node_of_cpu( cpuid );
redhawk::affinity::CpuList tlist = get_cpu_list( "socket", os.str() );
RH_INFO(get_affinity_logger(), "Promoting NIC affinity to PID:" << pid << " SOCKET:" << os.str() );
- cpulist.clear();
for( int i=0; i < (int)tlist.size();i++ ) {
if ( tlist[i] == cpuid ) continue;
cpulist.push_back( tlist[i] );
diff --git a/GPP/tests/.gitignore b/GPP/tests/.gitignore
index 65cc76261..0ba21347d 100644
--- a/GPP/tests/.gitignore
+++ b/GPP/tests/.gitignore
@@ -1,4 +1,3 @@
sdr/dev/devices/GPP/
-sdr/dev/mgr/DeviceManager
-sdr/dom/mgr/DomainManager
-
+sdr/dev/mgr
+sdr/dom/mgr
diff --git a/GPP/tests/.md5sums b/GPP/tests/.md5sums
new file mode 100644
index 000000000..6ac7101fd
--- /dev/null
+++ b/GPP/tests/.md5sums
@@ -0,0 +1 @@
+dbaf096c6b94ee57160c4c2e3f5abc26 test_GPP.py
diff --git a/GPP/tests/busy.py b/GPP/tests/bin/busy.py
similarity index 100%
rename from GPP/tests/busy.py
rename to GPP/tests/bin/busy.py
diff --git a/GPP/tests/bin/echo_pid.py b/GPP/tests/bin/echo_pid.py
new file mode 100755
index 000000000..8167279a1
--- /dev/null
+++ b/GPP/tests/bin/echo_pid.py
@@ -0,0 +1,7 @@
+#!/usr/bin/python
+
+import os
+
+print 'CWD:', os.getcwd()
+with open('pid.out', 'w') as fp:
+ print >>fp, os.getpid()
diff --git a/GPP/tests/sdr/dev/mgr/DeviceManager.Linux.armv7l.prf.xml b/GPP/tests/sdr/dev/mgr/DeviceManager.Linux.armv7l.prf.xml
deleted file mode 100644
index 22cb8b01b..000000000
--- a/GPP/tests/sdr/dev/mgr/DeviceManager.Linux.armv7l.prf.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-
-
-
- SCA required property describing the Operating System
-
- Linux
-
-
-
-
-
- SCA required property describing the CPU type
-
- armv7l
-
-
-
-
diff --git a/GPP/tests/sdr/dev/mgr/DeviceManager.Linux.x86.prf.xml b/GPP/tests/sdr/dev/mgr/DeviceManager.Linux.x86.prf.xml
deleted file mode 100644
index 811169cbb..000000000
--- a/GPP/tests/sdr/dev/mgr/DeviceManager.Linux.x86.prf.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-
-
-
- SCA required property describing the Operating System
-
- Linux
-
-
-
-
-
- SCA required property describing the CPU type
-
- x86
-
-
-
-
diff --git a/GPP/tests/sdr/dev/mgr/DeviceManager.Linux.x86_64.prf.xml b/GPP/tests/sdr/dev/mgr/DeviceManager.Linux.x86_64.prf.xml
deleted file mode 100644
index 37070a752..000000000
--- a/GPP/tests/sdr/dev/mgr/DeviceManager.Linux.x86_64.prf.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-
-
-
-
-
-
-
-
- SCA required property describing the Operating System
-
- Linux
-
-
-
-
-
- SCA required property describing the CPU type
-
- x86_64
-
-
-
-
diff --git a/GPP/tests/sdr/dev/mgr/DeviceManager.prf.xml b/GPP/tests/sdr/dev/mgr/DeviceManager.prf.xml
deleted file mode 100644
index 8ff2ea4f7..000000000
--- a/GPP/tests/sdr/dev/mgr/DeviceManager.prf.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-
-
-
- These are the properties to configure the device manager
-
-
-
- A URI that points to a log4j configuration file used
- for the device manager and all devices spawned by this device.
-
-
-
-
-
- Path to the Device Configuration Descriptor (DCD) XML file..
-
-
-
-
-
-
- The name of the domain in which this device manager will operate.
- During startup, the device manager will attempt to connect to the
- domain manager for the given domain.
-
-
-
-
-
-
- The amount of time (in seconds) that the Device Manager will wait for a Device to exit before issuing a kill signal
-
- 0.5
-
-
-
-
- The location where files from remote SCA filesystems will be cached.
-
-
-
-
-
-
- Name of the host where this device manager is running
-
-
-
-
diff --git a/GPP/tests/sdr/dev/mgr/DeviceManager.scd.xml b/GPP/tests/sdr/dev/mgr/DeviceManager.scd.xml
deleted file mode 100644
index 4fdd8ceb1..000000000
--- a/GPP/tests/sdr/dev/mgr/DeviceManager.scd.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
- 2.2
-
- devicemanager
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/GPP/tests/sdr/dev/mgr/DeviceManager.spd.xml b/GPP/tests/sdr/dev/mgr/DeviceManager.spd.xml
deleted file mode 100644
index c5f1b76e0..000000000
--- a/GPP/tests/sdr/dev/mgr/DeviceManager.spd.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- x86 Implementation of a Device Manager
-
-
-
-
-
- DeviceManager
-
-
-
-
-
- x86_64 Implementation of a Device Manager
-
-
-
-
-
- DeviceManager
-
-
-
-
-
diff --git a/GPP/tests/sdr/dev/nodes/test_VarCache_node/DeviceManager.dcd.xml.in b/GPP/tests/sdr/dev/nodes/test_VarCache_node/DeviceManager.dcd.xml.in
new file mode 100644
index 000000000..0b68eb0d9
--- /dev/null
+++ b/GPP/tests/sdr/dev/nodes/test_VarCache_node/DeviceManager.dcd.xml.in
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GPP_1
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/GPP/tests/sdr/dom/components/check_cwd/check_cwd.prf.xml b/GPP/tests/sdr/dom/components/check_cwd/check_cwd.prf.xml
new file mode 100644
index 000000000..38b330346
--- /dev/null
+++ b/GPP/tests/sdr/dom/components/check_cwd/check_cwd.prf.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/redhawk/src/testing/sdr/dom/components/svc_error_cpp/svc_error_cpp.scd.xml b/GPP/tests/sdr/dom/components/check_cwd/check_cwd.scd.xml
similarity index 100%
rename from redhawk/src/testing/sdr/dom/components/svc_error_cpp/svc_error_cpp.scd.xml
rename to GPP/tests/sdr/dom/components/check_cwd/check_cwd.scd.xml
diff --git a/GPP/tests/sdr/dom/components/check_cwd/check_cwd.spd.xml b/GPP/tests/sdr/dom/components/check_cwd/check_cwd.spd.xml
new file mode 100644
index 000000000..b349f8c49
--- /dev/null
+++ b/GPP/tests/sdr/dom/components/check_cwd/check_cwd.spd.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+ null
+
+
+
+
+
+
+
+
+ The implementation contains descriptive information about the template for a software resource.
+
+
+ python/check_cwd.py
+
+
+
+
+
+
+
diff --git a/GPP/tests/sdr/dom/components/check_cwd/python/check_cwd.py b/GPP/tests/sdr/dom/components/check_cwd/python/check_cwd.py
new file mode 100755
index 000000000..0e29d6ee4
--- /dev/null
+++ b/GPP/tests/sdr/dom/components/check_cwd/python/check_cwd.py
@@ -0,0 +1,157 @@
+#!/usr/bin/env python
+#
+#
+# AUTO-GENERATED
+#
+# Source: check_cwd.spd.xml
+from ossie.resource import start_component
+import os
+import logging
+
+from check_cwd_base import *
+
+class check_cwd_i(check_cwd_base):
+ """"""
+ def constructor(self):
+ """
+ This is called by the framework immediately after your component registers with the system.
+
+ In general, you should add customization here and not in the __init__ constructor. If you have
+ a custom port implementation you can override the specific implementation here with a statement
+ similar to the following:
+ self.some_port = MyPortImplementation()
+
+ """
+ self.cwd = os.getcwd()
+
+ def process(self):
+ """
+ Basic functionality:
+
+ The process method should process a single "chunk" of data and then return. This method
+ will be called from the processing thread again, and again, and again until it returns
+ FINISH or stop() is called on the component. If no work is performed, then return NOOP.
+
+ StreamSRI:
+ To create a StreamSRI object, use the following code (this generates a normalized SRI that does not flush the queue when full):
+ sri = bulkio.sri.create("my_stream_id")
+
+ PrecisionUTCTime:
+ To create a PrecisionUTCTime object, use the following code:
+ tstamp = bulkio.timestamp.now()
+
+ Ports:
+
+ Each port instance is accessed through members of the following form: self.port_
+
+ Data is obtained in the process function through the getPacket call (BULKIO only) on a
+ provides port member instance. The optional argument is a timeout value, in seconds.
+ A zero value is non-blocking, while a negative value is blocking. Constants have been
+ defined for these values, bulkio.const.BLOCKING and bulkio.const.NON_BLOCKING. If no
+ timeout is given, it defaults to non-blocking.
+
+ The return value is a named tuple with the following fields:
+ - dataBuffer
+ - T
+ - EOS
+ - streamID
+ - SRI
+ - sriChanged
+ - inputQueueFlushed
+ If no data is available due to a timeout, all fields are None.
+
+ To send data, call the appropriate function in the port directly. In the case of BULKIO,
+ convenience functions have been added in the port classes that aid in output.
+
+ Interactions with non-BULKIO ports are left up to the component developer's discretion.
+
+ Messages:
+
+ To receive a message, you need (1) an input port of type MessageEvent, (2) a message prototype described
+ as a structure property of kind message, (3) a callback to service the message, and (4) to register the callback
+ with the input port.
+
+ Assuming a property of type message is declared called "my_msg", an input port called "msg_input" is declared of
+ type MessageEvent, create the following code:
+
+ def msg_callback(self, msg_id, msg_value):
+ print msg_id, msg_value
+
+ Register the message callback onto the input port with the following form:
+ self.port_input.registerMessage("my_msg", check_cwd_i.MyMsg, self.msg_callback)
+
+ To send a message, you need to (1) create a message structure, and (2) send the message over the port.
+
+ Assuming a property of type message is declared called "my_msg", an output port called "msg_output" is declared of
+ type MessageEvent, create the following code:
+
+ msg_out = check_cwd_i.MyMsg()
+ this.port_msg_output.sendMessage(msg_out)
+
+ Accessing the Device Manager and Domain Manager:
+
+ Both the Device Manager hosting this Device and the Domain Manager hosting
+ the Device Manager are available to the Device.
+
+ To access the Domain Manager:
+ dommgr = self.getDomainManager().getRef();
+ To access the Device Manager:
+ devmgr = self.getDeviceManager().getRef();
+ Properties:
+
+ Properties are accessed directly as member variables. If the property name is baudRate,
+ then accessing it (for reading or writing) is achieved in the following way: self.baudRate.
+
+ To implement a change callback notification for a property, create a callback function with the following form:
+
+ def mycallback(self, id, old_value, new_value):
+ pass
+
+ where id is the property id, old_value is the previous value, and new_value is the updated value.
+
+ The callback is then registered on the component as:
+ self.addPropertyChangeListener('baudRate', self.mycallback)
+
+
+ Example:
+
+ # This example assumes that the component has two ports:
+ # - A provides (input) port of type bulkio.InShortPort called dataShort_in
+ # - A uses (output) port of type bulkio.OutFloatPort called dataFloat_out
+ # The mapping between the port and the class if found in the component
+ # base class.
+ # This example also makes use of the following Properties:
+ # - A float value called amplitude
+ # - A boolean called increaseAmplitude
+
+ packet = self.port_dataShort_in.getPacket()
+
+ if packet.dataBuffer is None:
+ return NOOP
+
+ outData = range(len(packet.dataBuffer))
+ for i in range(len(packet.dataBuffer)):
+ if self.increaseAmplitude:
+ outData[i] = float(packet.dataBuffer[i]) * self.amplitude
+ else:
+ outData[i] = float(packet.dataBuffer[i])
+
+ # NOTE: You must make at least one valid pushSRI call
+ if packet.sriChanged:
+ self.port_dataFloat_out.pushSRI(packet.SRI);
+
+ self.port_dataFloat_out.pushPacket(outData, packet.T, packet.EOS, packet.streamID)
+ return NORMAL
+
+ """
+
+ # TODO fill in your code here
+ self._log.debug("process() example log message")
+ return NOOP
+
+
+if __name__ == '__main__':
+ logging.getLogger().setLevel(logging.INFO)
+ logging.debug("Starting Component")
+ start_component(check_cwd_i)
+
diff --git a/GPP/tests/sdr/dom/components/check_cwd/python/check_cwd_base.py b/GPP/tests/sdr/dom/components/check_cwd/python/check_cwd_base.py
new file mode 100644
index 000000000..be16cd5e6
--- /dev/null
+++ b/GPP/tests/sdr/dom/components/check_cwd/python/check_cwd_base.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+#
+# AUTO-GENERATED CODE. DO NOT MODIFY!
+#
+# Source: check_cwd.spd.xml
+from ossie.cf import CF
+from ossie.cf import CF__POA
+from ossie.utils import uuid
+
+from ossie.component import Component
+from ossie.threadedcomponent import *
+from ossie.properties import simple_property
+
+import Queue, copy, time, threading
+
+class check_cwd_base(CF__POA.Resource, Component, ThreadedComponent):
+ # These values can be altered in the __init__ of your derived class
+
+ PAUSE = 0.0125 # The amount of time to sleep if process return NOOP
+ TIMEOUT = 5.0 # The amount of time to wait for the process thread to die when stop() is called
+ DEFAULT_QUEUE_SIZE = 100 # The number of BulkIO packets that can be in the queue before pushPacket will block
+
+ def __init__(self, identifier, execparams):
+ loggerName = (execparams['NAME_BINDING'].replace('/', '.')).rsplit("_", 1)[0]
+ Component.__init__(self, identifier, execparams, loggerName=loggerName)
+ ThreadedComponent.__init__(self)
+
+ # self.auto_start is deprecated and is only kept for API compatibility
+ # with 1.7.X and 1.8.0 components. This variable may be removed
+ # in future releases
+ self.auto_start = False
+ # Instantiate the default implementations for all ports on this component
+
+ def start(self):
+ Component.start(self)
+ ThreadedComponent.startThread(self, pause=self.PAUSE)
+
+ def stop(self):
+ Component.stop(self)
+ if not ThreadedComponent.stopThread(self, self.TIMEOUT):
+ raise CF.Resource.StopError(CF.CF_NOTSET, "Processing thread did not die")
+
+ def releaseObject(self):
+ try:
+ self.stop()
+ except Exception:
+ self._log.exception("Error stopping")
+ Component.releaseObject(self)
+
+ ######################################################################
+ # PORTS
+ #
+ # DO NOT ADD NEW PORTS HERE. You can add ports in your derived class, in the SCD xml file,
+ # or via the IDE.
+
+ ######################################################################
+ # PROPERTIES
+ #
+ # DO NOT ADD NEW PROPERTIES HERE. You can add properties in your derived class, in the PRF xml file
+ # or by using the IDE.
+ cwd = simple_property(id_="cwd",
+ type_="string",
+ mode="readonly",
+ action="external",
+ kinds=("property",))
+
+
+
+
diff --git a/GPP/tests/sdr/dom/components/load_comp/python/load_comp.py b/GPP/tests/sdr/dom/components/load_comp/python/load_comp.py
index abac9ae08..6fb32d8dc 100755
--- a/GPP/tests/sdr/dom/components/load_comp/python/load_comp.py
+++ b/GPP/tests/sdr/dom/components/load_comp/python/load_comp.py
@@ -25,7 +25,7 @@
# Source: load_comp.spd.xml
from ossie.resource import start_component
import logging
-import subprocess
+import multiprocessing
from load_comp_base import *
@@ -42,7 +42,11 @@ def constructor(self):
"""
# TODO add customization here.
- sp = subprocess.Popen(['../../../../busy.py'], executable='../../../../busy.py')
+ def busy():
+ while True:
+ pass
+ mp = multiprocessing.Process(target=busy)
+ mp.start()
def process(self):
"""
diff --git a/GPP/tests/sdr/dom/mgr/DomainManager.prf.xml b/GPP/tests/sdr/dom/mgr/DomainManager.prf.xml
deleted file mode 100644
index 3c48097d9..000000000
--- a/GPP/tests/sdr/dom/mgr/DomainManager.prf.xml
+++ /dev/null
@@ -1,87 +0,0 @@
-
-
-
-
-
- These are the properties to configure the domain manager
-
-
-
- A URI on the SCA FileManager that points to a log4j configuration file used
- for the domain manager and the entire domain.
-
-
-
-
-
-
- Path to the Domain Manager Descriptor (DMD) XML file..
-
-
-
-
-
-
- The name of the domain to which this domain manager will be bound.
-
-
-
-
-
-
- Enable CORBA persistence for the domain manager.
-
- true
-
-
-
-
-
- The URL to a database for domain persistence information.
-
-
-
-
-
-
- Replace any existing name binding for the domain manager.
-
- false
-
-
-
-
-
- The amount of time, in seconds, to wait for a component to bind to the name service after being launched.
-
- 60
- seconds
-
-
-
-
-
- Current version of REDHAWK that this Domain Manager is running
-
-
-
-
-
diff --git a/GPP/tests/sdr/dom/mgr/DomainManager.scd.xml b/GPP/tests/sdr/dom/mgr/DomainManager.scd.xml
deleted file mode 100644
index 4c1c5b8ff..000000000
--- a/GPP/tests/sdr/dom/mgr/DomainManager.scd.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
- 2.2
-
- domainmanager
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/GPP/tests/sdr/dom/mgr/DomainManager.spd.xml b/GPP/tests/sdr/dom/mgr/DomainManager.spd.xml
deleted file mode 100644
index 1e871939e..000000000
--- a/GPP/tests/sdr/dom/mgr/DomainManager.spd.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
-
-
- REDHAWK test author
-
-
-
-
-
-
-
-
- implementation of a Domain Manager
-
-
- /mgr/DomainManager
-
-
-
-
-
-
diff --git a/GPP/tests/sdr/dom/waveforms/busy_w/busy_w.sad.xml b/GPP/tests/sdr/dom/waveforms/busy_w/busy_w.sad.xml
index 87bc98e46..c1e4d48e8 100644
--- a/GPP/tests/sdr/dom/waveforms/busy_w/busy_w.sad.xml
+++ b/GPP/tests/sdr/dom/waveforms/busy_w/busy_w.sad.xml
@@ -29,7 +29,7 @@ with this program. If not, see http://www.gnu.org/licenses/.
- busy_comp_1
+ busy_cOmp_1
diff --git a/GPP/tests/sdr/dom/waveforms/check_cwd_w/check_cwd_w.sad.xml b/GPP/tests/sdr/dom/waveforms/check_cwd_w/check_cwd_w.sad.xml
new file mode 100644
index 000000000..b926c6a8f
--- /dev/null
+++ b/GPP/tests/sdr/dom/waveforms/check_cwd_w/check_cwd_w.sad.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ check_cwd_1
+
+
+
+
+
+
+
+
+
+
diff --git a/GPP/tests/sdr/dom/waveforms/wav_floor_w/wav_floor_w.sad.xml b/GPP/tests/sdr/dom/waveforms/wav_floor_w/wav_floor_w.sad.xml
new file mode 100644
index 000000000..870949d32
--- /dev/null
+++ b/GPP/tests/sdr/dom/waveforms/wav_floor_w/wav_floor_w.sad.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ busy_comp_1
+
+
+
+
+
+
+
+
+ busy_comp_2
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/GPP/tests/sdr/dom/waveforms/wav_one_floor_w/wav_one_floor_w.sad.xml b/GPP/tests/sdr/dom/waveforms/wav_one_floor_w/wav_one_floor_w.sad.xml
new file mode 100644
index 000000000..b96a91939
--- /dev/null
+++ b/GPP/tests/sdr/dom/waveforms/wav_one_floor_w/wav_one_floor_w.sad.xml
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ busy_comp_1
+
+
+
+
+
+
+
+
+
+
+
+ busy_comp_2
+
+
+
+
+
+
+
+
+
+
+
diff --git a/GPP/tests/sdr/dom/waveforms/wav_two_floor_w/wav_two_floor_w.sad.xml b/GPP/tests/sdr/dom/waveforms/wav_two_floor_w/wav_two_floor_w.sad.xml
new file mode 100644
index 000000000..ae4e537fe
--- /dev/null
+++ b/GPP/tests/sdr/dom/waveforms/wav_two_floor_w/wav_two_floor_w.sad.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ busy_comp_1
+
+
+
+
+
+
+
+
+
+
+
+ busy_comp_2
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/GPP/tests/test_GPP.py b/GPP/tests/test_GPP.py
old mode 100755
new mode 100644
index ba83d798c..317d30b92
--- a/GPP/tests/test_GPP.py
+++ b/GPP/tests/test_GPP.py
@@ -21,99 +21,556 @@
import unittest
import os
+import resource
import socket
import time
-import signal
import commands
import sys
-import threading
import Queue
-from omniORB import any
-from ossie.cf import ExtendedEvent
-from ossie.parsers import DCDParser
-from omniORB import CORBA
-import omniORB
+import shutil
+import subprocess, multiprocessing
+
+from omniORB import any, CORBA
+
import CosEventChannelAdmin, CosEventChannelAdmin__POA
from ossie.utils.sandbox.registrar import ApplicationRegistrarStub
-import subprocess, multiprocessing
+from ossie.utils.sandbox import naming
from ossie.utils import sb, redhawk
from ossie.cf import CF, CF__POA
import ossie.utils.testing
-from shutil import copyfile
-import shutil
-import os
+import ossie.properties
+from redhawk import numa
-# numa layout: node 0 cpus, node 1 cpus, node 0 cpus sans cpuid=0
-
-maxcpus=32
-maxnodes=2
-all_cpus='0-'+str(maxcpus-1)
-all_cpus_sans0='1-'+str(maxcpus-1)
-numa_match={ "all" : "0-31",
- "sock0": "0-7,16-23",
- "sock1": "8-15,24-31",
- "sock0sans0": "1-7,16-23",
- "sock1sans0": "1-7,16-23",
- "5" : "5",
- "8-10" : "8-10" }
-numa_layout=[ "0-7,16-23", "8-15,24-31" ]
-
-affinity_test_src={ "all" : "0-31",
- "sock0": "0",
- "sock1": "1",
- "sock0sans0": "0",
- "5" : "5",
- "8-10" : "8,9,10",
- "eface" : "em1" }
-
-def get_match( key="all" ):
- if key and key in numa_match:
- return numa_match[key]
- return numa_match["all"]
-
-def spawnNodeBooter(dmdFile=None,
- dcdFile=None,
- debug=0,
- domainname=None,
- loggingURI=None,
- endpoint=None,
- dbURI=None,
- execparams="",
- nodeBooterPath=os.getenv('OSSIEHOME')+"/bin/nodeBooter",
- sdrroot = None):
- args = []
- if dmdFile != None:
- args.extend(["-D", dmdFile])
- if dcdFile != None:
- args.extend(["-d", dcdFile])
- if domainname == None:
- # Always use the --domainname argument because
- # we don't want to have to read the DCD files or regnerate them
- args.extend(["--domainname", 'sample_domain'])
- else:
- args.extend(["--domainname", domainname])
-
- if endpoint == None:
- args.append("--nopersist")
- else:
- args.extend(["-ORBendPoint", endpoint])
-
- if dbURI:
- args.extend(["--dburl", dbURI])
-
- if sdrroot == None:
- sdrroot = os.getenv('SDRROOT')
+from _unitTestHelpers import scatest, runtestHelpers
+
+def hasNumaSupport():
+ return runtestHelpers.haveDefine('../cpp/Makefile', 'HAVE_LIBNUMA')
+
+topology = numa.NumaTopology()
+
+skipUnless = scatest._skipUnless
+def requireNuma(obj):
+ return skipUnless(topology.available() and hasNumaSupport(), 'Affinity control is disabled')(obj)
+
+
+def wait_predicate(pred, timeout):
+ end = time.time() + timeout
+ while time.time() < end:
+ if pred():
+ return
+ time.sleep(0.1)
+
+def nolaunch(obj):
+ """
+ Decorator to disable automatic launch of the GPP from the setUp() method.
+ This is for use by tests that must override properties that can only be set
+ via the command line or initializeProperties().
+ """
+ obj.nolaunch = True
+ return obj
+
+# Base unit testing class for new-style GPP tests, based off of the default
+# generated unit test. Adds simplified management and cleanup of programs
+# launched by the GPP.
+class GPPSandboxTest(ossie.utils.testing.RHTestCase):
+ # Path to the SPD file, relative to this file. This must be set in order to
+ # launch the device.
+ SPD_FILE = '../GPP.spd.xml'
+
+ def setUp(self):
+ print "\n-----------------------"
+ print "Running: ", self.id().split('.')[-1]
+ print "-----------------------\n"
+
+ if self._shouldLaunch():
+ self.launchGPP()
+ else:
+ self.comp = None
+
+ self._pids = []
+ self._testDirs = []
+ self._testFiles = []
+ self._busyProcs = []
+
+ def _shouldLaunch(self):
+ method = getattr(self, self._testMethodName, None)
+ if not method:
+ return True
+ # Check for the 'nolaunch' attribute (its value is irrelevant); unless
+ # it's present, launch the GPP
+ return not hasattr(method, 'nolaunch')
+
+ def launchGPP(self, properties={}):
+ # Launch the device, using the selected implementation
+ self.comp = sb.launch(self.spd_file, impl=self.impl, properties=properties)
+ return self.comp
+
+ def tearDown(self):
+ # Clean up any leftover busy subprocesses
+ for proc in self._busyProcs:
+ if proc.poll() is None:
+ proc.kill()
+
+ # Terminate all launched executables, ignoring errors
+ remaining_pids = []
+ for pid in self._pids:
+ try:
+ self.comp.ref.terminate(pid)
+ except:
+ remaining_pids.append(pid)
+
+ # In case the GPP really failed badly, manually kill the processes
+ for pid in remaining_pids:
+ try:
+ os.killpg(pid, 9)
+ except OSError:
+ pass
+
+ # Clean up all sandbox artifacts created during test
+ sb.release()
+
+ for filename in self._testFiles:
+ try:
+ os.unlink(filename)
+ except OSError:
+ pass
+
+ for path in self._testDirs:
+ shutil.rmtree(path)
+
+ def addTestDirectory(self, path):
+ self._testDirs.append(path)
+
+ def addTestFile(self, path):
+ self._testFiles.append(path)
+
+ def removeTestFile(self, path):
+ self._testFiles.remove(path)
+
+ def addBusyTasks(self, count):
+ self._busyProcs += [subprocess.Popen('bin/busy.py') for _ in xrange(count)]
+
+ def clearBusyTasks(self):
+ for proc in self._busyProcs:
+ proc.kill()
+ self._busyProcs = []
+
+ def waitUsageState(self, state, timeout):
+ wait_predicate(lambda: self.comp._get_usageState() == state, timeout)
+ self.assertEqual(self.comp._get_usageState(), state)
+
+ def _execute(self, executable, options, parameters):
+ if isinstance(options, dict):
+ options = [CF.DataType(k, any.to_any(v)) for k, v in options.items()]
+ if isinstance(parameters, dict):
+ parameters = [CF.DataType(k, any.to_any(v)) for k, v in parameters.items()]
+ pid = self.comp.ref.execute(executable, options, parameters)
+ if pid != 0:
+ self._pids.append(pid)
+ return pid
+
+ def _launchComponent(self, executable, name, profile, options={}, parameters={}):
+ # Using the stub from the naming module allows fetching the component
+ # object, which the other version does not support; these should be
+ # consolidated at some point
+ appReg = naming.ApplicationRegistrarStub()
+ appreg_ior = sb.orb.object_to_string(appReg._this())
+
+ params = {}
+ params.update(parameters)
+ params['COMPONENT_IDENTIFIER'] = name
+ params['NAME_BINDING'] = name
+ params['PROFILE_NAME'] = profile
+ params['NAMING_CONTEXT_IOR'] = appreg_ior
+
+ pid = self._execute(executable, options, params)
+ self.assertNotEqual(pid, 0)
+
+ wait_predicate(lambda: appReg.getObject(name) is not None, 2.0)
+ comp = appReg.getObject(name)
+ self.failIf(comp is None, "component '" + name + "' never registered")
+
+ return (pid, comp)
+
+ def _launchComponentStub(self, name, options={}, parameters={}):
+ executable = '/dat/component_stub/python/component_stub.py'
+ profile = '/component_stub/component_stub.spd.xml'
+ return self._launchComponent(executable, name, profile, options, parameters)
+
+
+class GPPTests(GPPSandboxTest):
+ def testPropertyEvents(self):
+ event_queue = Queue.Queue()
+ event_channel = sb.createEventChannel('properties')
+ event_channel.eventReceived.addListener(event_queue.put)
+
+ self.comp.connect(event_channel)
+
+ self.comp.loadThreshold = 81
+
+ # Make sure the background status events are emitted
+ try:
+ event = event_queue.get(timeout=1.0)
+ except Queue.Empty:
+ self.fail('Property change event not received')
+ event = any.from_any(event, keep_structs=True)
+ event_dict = ossie.properties.props_to_dict(event.properties)
+ self.assertEqual(self.comp._id, event.sourceId)
+ self.assertEqual(self.comp.loadThreshold.id, event.properties[0].id)
+ self.assertEqual(81, any.from_any(event.properties[0].value))
+
+ def testLimits(self):
+ limits = resource.getrlimit(resource.RLIMIT_NPROC)
+
+ # Check that the system limits are sane
+ self.assertTrue(self.comp.sys_limits.current_threads > 0)
+ if limits[1] == -1:
+ # system limit is set to unlimited, can only check that the component is reporting a positive value
+ self.assertTrue(self.comp.sys_limits.current_threads > 0)
+ else:
+ self.assertTrue(self.comp.sys_limits.max_threads > self.comp.sys_limits.current_threads)
+ self.assertTrue(self.comp.sys_limits.current_open_files > 0)
+ self.assertTrue(self.comp.sys_limits.max_open_files > self.comp.sys_limits.current_open_files)
+
+ # Check that the GPP's process limits are also sane
+ self.assertTrue(self.comp.gpp_limits.current_threads > 0)
+ if limits[0] == -1:
+ # process limit is set to unlimited, can only check that the component is reporting a positive value
+ self.assertTrue(self.comp.gpp_limits.current_threads > 0)
+ else:
+ self.assertTrue(self.comp.gpp_limits.max_threads > self.comp.gpp_limits.current_threads)
+ self.assertTrue(self.comp.gpp_limits.current_open_files > 0)
+ self.assertTrue(self.comp.gpp_limits.max_open_files > self.comp.gpp_limits.current_open_files)
- args.extend(["-debug", str(debug)])
- args.extend(execparams.split(" "))
- args.insert(0, nodeBooterPath)
+ def testReservation(self):
+ # Set the idle threshold to 30% (i.e., can use up to 70%) and the
+ # reserved capacity per component to 25%; this gives plenty of headroom
+ # with two components (50% utilization leaves a 20% margin), but a
+ # third component unambiguously crosses into the busy threshold
+ self.comp.thresholds.cpu_idle = 30
+ self.comp.reserved_capacity_per_component = 0.25 * self.comp.processor_cores
+ self.assertEquals(self.comp._get_usageState(),CF.Device.IDLE)
+
+ self._launchComponentStub('reservation_1')
+ self._launchComponentStub('reservation_2')
+
+ # Give the GPP a couple of measurement cycles to make sure it doesn't
+ # go busy; the CPU utilization (always the first entry) should report
+ # 50% subscribed
+ time.sleep(2)
+ self.assertEquals(self.comp._get_usageState(), CF.Device.ACTIVE)
+ expected = 0.5 * self.comp.processor_cores
+ self.assertEquals(expected, self.comp.utilization[0].subscribed)
+
+ # Launch the third component and give up to 2 seconds for the GPP to go
+ # busy; CPU utilization should now be 75% subscribed
+ self._launchComponentStub('reservation_3')
+ self.waitUsageState(CF.Device.BUSY, 2.0)
+ expected = 0.75 * self.comp.processor_cores
+ self.assertEquals(expected, self.comp.utilization[0].subscribed)
+
+ # Reduce the reserved capacity such that it consumes less than the idle
+ # threshold (10% x 3 = 30% active = 70% idle)
+ self.comp.reserved_capacity_per_component = 0.1 * self.comp.processor_cores
+ self.waitUsageState(CF.Device.ACTIVE, 2.0)
+ # 30% is an inexact fraction, so allow a little tolerance
+ expected = 0.3 * self.comp.processor_cores
+ self.assertAlmostEquals(expected, self.comp.utilization[0].subscribed, 1)
+
+ def testFloorReservation(self):
+ # Reserve an absurdly large amount of cores, which should drive the GPP
+ # to a busy state immediately
+ self.assertEquals(self.comp._get_usageState(),CF.Device.IDLE)
+ params = {"RH::GPP::MODIFIED_CPU_RESERVATION_VALUE": 1000.0}
+ self._launchComponentStub('floor_reservation_1', parameters=params)
+
+ self.waitUsageState(CF.Device.BUSY, 2.0)
+
+ def _unpackThresholdEvents(self, message):
+ for dt in any.from_any(message, keep_structs=True):
+ if dt.id != 'threshold_event':
+ continue
+ props = any.from_any(dt.value, keep_structs=True)
+ yield ossie.properties.props_to_dict(props)
+
+ def _checkThresholdEvent(self, resourceId, thresholdClass, exceeded):
+ try:
+ event = self.queue.get(timeout=2.0)
+ except Queue.Empty:
+ self.fail('Threshold event not received')
+ self.assertEqual(self.comp._refid, event['threshold_event::source_id'])
+ self.assertEqual(thresholdClass, event['threshold_event::threshold_class'])
+ self.assertEqual(resourceId, event['threshold_event::resource_id'])
+ self._assertThresholdState(event, exceeded)
+
+ def _assertThresholdState(self, event, exceeded):
+ if exceeded:
+ event_type = 'THRESHOLD_EXCEEDED'
+ else:
+ event_type = 'THRESHOLD_NOT_EXCEEDED'
+ self.assertEqual(event_type, event['threshold_event::type'])
+
+ def _testThresholdEventType(self, name, resourceId, thresholdClass, value):
+ # Save the original value and set the test value to trigger an
+ # "exceeded" event
+ orig_value = self.comp.thresholds[name]
+ self.comp.thresholds[name] = value
+ self._checkThresholdEvent(resourceId, thresholdClass, True)
+
+ # Turning off the threshold should trigger a "not exceeded" event
+ self.comp.thresholds.ignore = True
+ self._checkThresholdEvent(resourceId, thresholdClass, False)
+
+ # Turning it on again should trigger another "exceeded" event
+ self.comp.thresholds.ignore = False
+ self._checkThresholdEvent(resourceId, thresholdClass, True)
+
+ # Restore the original value, trigger "not exceeded" event
+ self.comp.thresholds[name] = orig_value
+ self._checkThresholdEvent(resourceId, thresholdClass, False)
+
+ def _checkNicEvents(self, nics, exceeded):
+ expected = set(nics)
+ end = time.time() + 2.0
+ while expected and (time.time() < end):
+ try:
+ event = self.queue.get_nowait()
+ except Queue.Empty:
+ time.sleep(0.1)
+ continue
+
+ # Only 1 device connected to the event channel, the source ID had
+ # better be correct
+ self.assertEqual(self.comp._refid, event['threshold_event::source_id'])
+
+ # Should only be receiving one NIC message from each configured
+ # interface
+ nic_name = event['threshold_event::resource_id']
+ self.failUnless(nic_name in nics, 'Received message from unexpected NIC %s' % nic_name)
+ self.failUnless(nic_name in expected, 'Received too many messages from NIC %s' % nic_name)
+ threshold_class = event['threshold_event::threshold_class']
+ self.assertEqual('NIC_THROUGHPUT', threshold_class, 'Received unexpected threshold class %s' % threshold_class)
+ self._assertThresholdState(event, exceeded)
+ expected.remove(nic_name)
+
+ self.assertEqual(set(), expected, 'Did not receive message from NIC(s): ' + ' '.join(expected))
+
+ def testThresholdEvents(self):
+ # Cut down the threshold cycle time to trigger events faster (we're not
+ # worried about the extra processing time here)
+ self.comp.threshold_cycle_time = 0.1
+
+ # Create a virtual event channel to queue the GPP's messages
+ event_channel = sb.createEventChannel('thresholds')
+ self.queue = Queue.Queue()
+ def queue_message(message):
+ # Unpack and queue up threshold event messages
+ for event in self._unpackThresholdEvents(message):
+ self.queue.put(event)
+
+ event_channel.eventReceived.addListener(queue_message)
+ self.comp.connect(event_channel, usesPortName="MessageEvent_out")
+
+ # Test all thresholds except NIC, which is a little more complex
+ self._testThresholdEventType('cpu_idle', 'cpu', 'CPU_IDLE', 100)
+ self._testThresholdEventType('mem_free', 'physical_ram', 'MEMORY_FREE', self.comp.memFree + 100)
+ self._testThresholdEventType('load_avg', 'cpu', 'LOAD_AVG', 0)
+ self._testThresholdEventType('shm_free', 'shm', 'SHM_FREE', self.comp.shmCapacity)
+ self._testThresholdEventType('files_available', 'ulimit', 'OPEN_FILES', 100.0)
+ self._testThresholdEventType('threads', 'ulimit', 'THREADS', 100.0)
+
+ # If there is more than one NIC (real or virtual), each one will emit
+ # an event; we only really care about the "available" NICs
+ nics = list(self.comp.available_nic_interfaces)
+ nic_usage = int(self.comp.thresholds.nic_usage)
+ self.comp.thresholds.nic_usage = 0
+ self._checkNicEvents(nics, True)
+
+ # Turning off the threshold should trigger "not exceeded" event(s)
+ self.comp.thresholds.ignore = True
+ self._checkNicEvents(nics, False)
+
+ # Turning it on again should trigger "exceeded" event(s)
+ self.comp.thresholds.ignore = False
+ self._checkNicEvents(nics, True)
+
+ # Restore the original value, trigger "not exceeded" event(s)
+ self.comp.thresholds.nic_usage = nic_usage
+ self._checkNicEvents(nics, False)
+
+ def testDefaultDirectories(self):
+ # Test that when cache and working directory are not given, the
+ # properties still have meaningful values
+ cwd = os.getcwd()
+ self.assertEquals(cwd, self.comp.cacheDirectory)
+ self.assertEquals(cwd, self.comp.workingDirectory)
+
+ @nolaunch
+ def testCacheDirectory(self):
+ # Create an alternate directory for the cache
+ cache_dir = os.path.join(os.getcwd(), 'testCacheDirectory')
+ os.mkdir(cache_dir)
+ self.addTestDirectory(cache_dir)
+ self.launchGPP({'cacheDirectory':cache_dir})
+
+ # Make sure the property is correct
+ self.assertEqual(cache_dir, self.comp.cacheDirectory)
+
+ # Load a file and check that it was copied to the right place
+ expected = os.path.join(cache_dir, 'bin/echo_pid.py')
+ self.failIf(os.path.exists(expected))
+ fs_stub = ComponentTests.FileSystemStub()
+ self.comp.ref.load(fs_stub._this(), "/bin/echo_pid.py", CF.LoadableDevice.EXECUTABLE)
+ self.failUnless(os.path.isfile(expected))
+
+ @nolaunch
+ def testWorkingDirectory(self):
+ # Create an alternate directory for the working directory
+ working_dir = os.path.join(os.getcwd(), 'testWorkingDirectory')
+ os.mkdir(working_dir)
+ self.addTestDirectory(working_dir)
+ self.launchGPP({'workingDirectory':working_dir})
+
+ # Make sure the property is correct
+ self.assertEqual(working_dir, self.comp.workingDirectory)
+
+ # Run a test executable that writes to its current directory
+ expected = os.path.join(working_dir, 'pid.out')
+ self.failIf(os.path.exists(expected))
+ pid = self._execute("/bin/echo_pid.py", {}, {})
+ wait_predicate(lambda: os.path.exists(expected), 1.0)
+ self.failUnless(os.path.exists(expected))
+
+ # Read the output file and make sure that the right PID was written
+ with open(expected, 'r') as fp:
+ echo_pid = int(fp.read().strip())
+ self.assertEqual(pid, echo_pid)
+
+ @nolaunch
+ def testCacheAndWorkingDirectory(self):
+ # Test the interaction of the cache and working directories; create an
+ # alternate directory for both
+ base_dir = os.path.join(os.getcwd(), 'testCacheAndWorkingDirectory')
+ os.mkdir(base_dir)
+ self.addTestDirectory(base_dir)
+ cache_dir = os.path.join(base_dir, 'cache')
+ os.mkdir(cache_dir)
+ working_dir = os.path.join(base_dir, 'cwd')
+ os.mkdir(working_dir)
+ self.launchGPP({'cacheDirectory':cache_dir, 'workingDirectory':working_dir})
+
+ # Make sure the properties are correct
+ self.assertEqual(cache_dir, self.comp.cacheDirectory)
+ self.assertEqual(working_dir, self.comp.workingDirectory)
+
+ # Load a file and check that it was copied to the right place
+ expected = os.path.join(cache_dir, 'bin/echo_pid.py')
+ self.failIf(os.path.exists(expected))
+ fs_stub = ComponentTests.FileSystemStub()
+ self.comp.ref.load(fs_stub._this(), "/bin/echo_pid.py", CF.LoadableDevice.EXECUTABLE)
+ self.failUnless(os.path.isfile(expected))
+
+ # Run a test executable that writes to its current directory
+ expected = os.path.join(working_dir, 'pid.out')
+ self.failIf(os.path.exists(expected))
+ pid = self._execute("/bin/echo_pid.py", {}, {})
+ wait_predicate(lambda: os.path.exists(expected), 1.0)
+ self.failUnless(os.path.exists(expected))
+
+ # Read the output file and make sure that the right PID was written
+ with open(expected, 'r') as fp:
+ echo_pid = int(fp.read().strip())
+ self.assertEqual(pid, echo_pid)
+
+ def testSharedMemoryProperties(self):
+ status = os.statvfs('/dev/shm')
+
+ # The total shouldn't change in normal operation, so using the same
+ # expected integer math should give the same value
+ total = (status.f_blocks * status.f_frsize) / 1024 / 1024
+ self.assertEqual(total, self.comp.shmCapacity)
+
+ # Free could vary slightly if something else is happening on the
+ # system, so give it a little bit of slack (1 MB)
+ free = (status.f_bfree * status.f_frsize) / 1024 / 1024
+ self.failIf(abs(free - self.comp.shmFree) > 1)
+
+ def testBusyCpuIdle(self):
+ # Disable load average threshold
+ self.comp.thresholds.load_avg = -1
+
+ self.assertEqual(self.comp._get_usageState(), CF.Device.IDLE)
+
+ # Task all of the CPUs to be busy (more or less) and wait for the idle
+ # threshold to be exceeded
+ self.addBusyTasks(self.comp.processor_cores)
+ self.waitUsageState(CF.Device.BUSY, 5.0)
+ self.failUnless("CPU IDLE" in self.comp.busy_reason.upper())
+
+ # Clear all busy tasks and wait for the device to go back to idle
+ self.clearBusyTasks()
+ self.waitUsageState(CF.Device.IDLE, 5.0)
+ self.assertEqual(self.comp._get_usageState(), CF.Device.IDLE)
+ self.assertEqual(self.comp.busy_reason, "")
+
+ def testBusyLoadAvg(self):
+ # Disable CPU idle threshold and lower the load average threshold so
+ # that it's easier to exceed
+ self.comp.thresholds.cpu_idle = -1
+ self.comp.thresholds.load_avg = 25
+
+ # The load average may exceed the threshold to begin with, depending on
+ # what the system was doing before this test
+ print 'Waiting for load average to fall below threshold, may take a while'
+ self.waitUsageState(CF.Device.IDLE, 30.0)
+
+ # Occupy all of the CPUs with busy tasks and wait for the load average
+ # to exceed the threshold; this may take a while, since it's based on a
+ # 1 minute window
+ self.addBusyTasks(self.comp.processor_cores)
+ print 'Waiting for load average to exceed threshold, may take a while'
+ self.waitUsageState(CF.Device.BUSY, 30.0)
+ self.failUnless("LOAD AVG" in self.comp.busy_reason.upper())
+
+ # Clear all of the busy tasks; again, due to the 1 minute window, it
+ # may take a little while for the load average to drop back below the
+ # threshold
+ self.clearBusyTasks()
+ print 'Waiting for load average to fall below threshold, may take a while'
+ self.waitUsageState(CF.Device.IDLE, 30.0)
+ self.assertEqual(self.comp.busy_reason, "")
+
+ def testBusySharedMemory(self):
+ # Cut down the update time for testing
+ self.comp.threshold_cycle_time = 0.1
- print '\n-------------------------------------------------------------------'
- print 'Launching nodeBooter', " ".join(args)
- print '-------------------------------------------------------------------'
- nb = ossie.utils.Popen(args, cwd=sdrroot, shell=False, preexec_fn=os.setpgrp)
+ self.assertEqual(self.comp._get_usageState(), CF.Device.IDLE)
+
+ # Set the shared memory threshold a little below the current free, so
+ # that a relative small uptick in usage will cross the threshold
+ current_shm = int(self.comp.shmFree)
+ self.comp.thresholds.shm_free = current_shm - 2
+
+ # Create a temporary file that consumes a few MB, enough to cross the
+ # threshold and a little further just to be sure
+ shm_file = '/dev/shm/test-%d' % os.getpid()
+ fill_size = 4*1024*1024
+ self.addTestFile(shm_file)
+ with open(shm_file, 'w') as fp:
+ # Resize the file and write one byte every page to ensure that
+ # shared memory is consumed
+ fp.truncate(fill_size)
+ for pos in xrange(0, fill_size, 4096):
+ fp.seek(pos)
+ fp.write('\x00')
+
+ self.waitUsageState(CF.Device.BUSY, 1.0)
+
+ # Remove the file, which should push the free shared memory back over
+ # the threshold
+ os.unlink(shm_file)
+ self.waitUsageState(CF.Device.IDLE, 1.0)
- return nb
class ComponentTests(ossie.utils.testing.ScaComponentTestCase):
"""Test for all component implementations in test"""
@@ -131,6 +588,7 @@ def tearDown(self):
os.remove(sproc)
except:
pass
+
try:
# kill all busy.py just in case
os.system('pkill -9 -f busy.py')
@@ -158,27 +616,6 @@ def promptUserInput(self, question, default):
else:
return default
- def check_affinity(self, pname, affinity_match="0-31", use_pidof=True, pid_in=None):
- try:
- if pid_in:
- pid=pid_in
- o2=os.popen('cat /proc/'+str(pid)+'/status | grep Cpus_allowed_list')
- else:
- if use_pidof == True:
- o1=os.popen('pidof -x '+pname )
- else:
- o1=os.popen('pgrep -f '+pname )
- pid=o1.read()
- o2=os.popen('cat /proc/'+pid.split('\n')[0]+'/status | grep Cpus_allowed_list')
- cpus_allowed=o2.read().split()
- except:
- cpus_allowed=[]
-
- #print pname, cpus_allowed
- self.assertEqual(cpus_allowed[1],affinity_match)
- return
-
-
def runGPP(self, execparam_overrides={}, initialize=True, configure={}):
#######################################################################
# Launch the component with the default execparams
@@ -254,11 +691,12 @@ def testScaBasicBehavior(self):
# Create a test file system
class FileStub(CF__POA.File):
- def __init__(self):
- self.fobj = open("dat/component_stub.py")
+ def __init__(self, path):
+ self.path = path
+ self.fobj = open(self.path)
def sizeOf(self):
- return os.path.getsize("dat/component_stub.py")
+ return os.path.getsize(self.path)
def read(self, bytes):
return self.fobj.read(bytes)
@@ -267,15 +705,20 @@ def close(self):
return self.fobj.close()
class FileSystemStub(CF__POA.FileSystem):
+ def __init__(self, path='.'):
+ self.path = os.path.abspath(path)
+
def list(self, path):
- return [CF.FileSystem.FileInformationType(path[1:], CF.FileSystem.PLAIN, 100, [])]
+ path = os.path.basename(path)
+ return [CF.FileSystem.FileInformationType(path, CF.FileSystem.PLAIN, 100, [])]
def exists(self, fileName):
- tmp_fileName = './dat/'+fileName
+ tmp_fileName = self.path + fileName
return os.access(tmp_fileName, os.F_OK)
def open(self, path, readonly):
- file = ComponentTests.FileStub()
+ tmp_fileName = self.path + path
+ file = ComponentTests.FileStub(tmp_fileName)
return file._this()
def testExecute(self):
@@ -284,7 +727,7 @@ def testExecute(self):
configureProps = self.getPropertySet(kinds=("configure",), modes=("readwrite", "writeonly"), includeNil=False)
self.comp_obj.configure(configureProps)
- fs_stub = ComponentTests.FileSystemStub()
+ fs_stub = ComponentTests.FileSystemStub('./dat')
fs_stub_var = fs_stub._this()
self.comp_obj.load(fs_stub_var, "/component_stub.py", CF.LoadableDevice.EXECUTABLE)
@@ -322,156 +765,6 @@ def testExecute(self):
pass
else:
self.fail("Process failed to terminate")
-
- def testBusy(self):
- self.runGPP()
-
- self.assertEqual(self.comp_obj._get_usageState(), CF.Device.IDLE)
- cores = multiprocessing.cpu_count()
- sleep_time = 3+cores/10.0
- if sleep_time < 7:
- sleep_time = 7
- procs = []
- for core in range(cores*2):
- procs.append(subprocess.Popen('./busy.py'))
- time.sleep(sleep_time)
- self.assertEqual(self.comp_obj._get_usageState(), CF.Device.BUSY)
- br=self.comp.busy_reason.queryValue()
- br_cpu="CPU IDLE" in br.upper() or "LOAD AVG" in br.upper()
- self.assertEqual(br_cpu, True)
- for proc in procs:
- proc.kill()
- time.sleep(sleep_time)
- self.assertEqual(self.comp_obj._get_usageState(), CF.Device.IDLE)
- self.assertEqual(self.comp.busy_reason, "")
-
- fs_stub = ComponentTests.FileSystemStub()
- fs_stub_var = fs_stub._this()
-
- self.comp_obj.load(fs_stub_var, "/component_stub.py", CF.LoadableDevice.EXECUTABLE)
- self.assertEqual(os.path.isfile("component_stub.py"), True) # Technically this is an internal implementation detail that the file is loaded into the CWD of the device
-
- comp_id = "DCE:00000000-0000-0000-0000-000000000000:waveform_1"
- app_id = "waveform_1"
- appReg = ApplicationRegistrarStub(comp_id, app_id)
- appreg_ior = sb.orb.object_to_string(appReg._this())
- pid = self.comp_obj.execute("/component_stub.py", [], [CF.DataType(id="COMPONENT_IDENTIFIER", value=any.to_any(comp_id)),
- CF.DataType(id="NAME_BINDING", value=any.to_any("component_stub")),CF.DataType(id="PROFILE_NAME", value=any.to_any("/component_stub/component_stub.spd.xml")),
- CF.DataType(id="NAMING_CONTEXT_IOR", value=any.to_any(appreg_ior))])
- self.assertNotEqual(pid, 0)
- time.sleep(1)
- self.assertEqual(self.comp_obj._get_usageState(), CF.Device.ACTIVE)
- cores = multiprocessing.cpu_count()
- procs = []
- for core in range(cores*2):
- procs.append(subprocess.Popen('./busy.py'))
- time.sleep(sleep_time)
- self.assertEqual(self.comp_obj._get_usageState(), CF.Device.BUSY)
- br_cpu="CPU IDLE" in br.upper() or "LOAD AVG" in br.upper()
- for proc in procs:
- proc.kill()
- time.sleep(sleep_time)
- self.assertEqual(self.comp_obj._get_usageState(), CF.Device.ACTIVE)
- self.assertEqual(self.comp.busy_reason.queryValue(), "")
-
- try:
- os.kill(pid, 0)
- except OSError:
- self.fail("Process failed to execute")
- time.sleep(1)
- self.comp_obj.terminate(pid)
- try:
- # kill all busy.py just in case
- os.system('pkill -9 -f busy.py')
- os.kill(pid, 0)
- except OSError:
- pass
- else:
- self.fail("Process failed to terminate")
-
-
-
- def test_busy_allow(self):
- self.runGPP(execparam_overrides={'DEBUG_LEVEL': 3 })
-
- self.assertEqual(self.comp_obj._get_usageState(), CF.Device.IDLE)
- cores = multiprocessing.cpu_count()
- sleep_time = 3+cores/10.0
- if sleep_time < 7:
- sleep_time = 7
- procs = []
- for core in range(cores*2+5):
- procs.append(subprocess.Popen('./busy.py'))
- time.sleep(sleep_time)
- self.assertEqual(self.comp_obj._get_usageState(), CF.Device.BUSY)
- br=self.comp.busy_reason.queryValue()
- br_cpu="CPU IDLE" in br.upper() or "LOAD AVG" in br.upper()
- self.assertEqual(br_cpu, True)
-
- # turn off check for idle
- self.comp.thresholds.cpu_idle = 0.0
- # wait for busy to be reported... should just be load avg .. takes approx 1 minute
- for i in range(42):
- br=self.comp.busy_reason.queryValue()
- br_cpu="LOAD AVG" in br.upper()
- if br_cpu == True:
- break
- time.sleep(1.5)
- self.assertEqual(self.comp_obj._get_usageState(), CF.Device.BUSY)
- self.assertEqual(br_cpu, True)
-
- # turn off check for load_avg
- self.comp.thresholds.load_avg = 100.0
- for i in range(5):
- br=self.comp.busy_reason.queryValue()
- if br == "":
- break
- time.sleep(1.5)
- # wait for busy to be reported... should just be load avg now
- br=self.comp.busy_reason.queryValue()
- self.assertEqual(self.comp_obj._get_usageState(), CF.Device.IDLE)
- self.assertEqual(br, "")
-
- # turn on check for cpu_idle check
- self.comp.thresholds.cpu_idle = 10.0
- # wait for busy to be reported... should just be load avg now
- for i in range(5):
- br=self.comp.busy_reason.queryValue()
- br_cpu="CPU IDLE" in br.upper()
- if br_cpu == True:
- break
- time.sleep(1.5)
- br_cpu="CPU IDLE" in br.upper()
- self.assertEqual(br_cpu, True)
- self.assertEqual(self.comp_obj._get_usageState(), CF.Device.BUSY)
-
- # turn on check for load_avg check
- self.comp.thresholds.load_avg = 80.0
- # wait for busy to be reported... should just be load avg now
- for i in range(5):
- br=self.comp.busy_reason.queryValue()
- br_cpu="CPU IDLE" in br.upper() or "LOAD AVG" in br.upper()
- if br_cpu == True:
- break
- time.sleep(1.5)
-
- self.assertEqual(br_cpu, True)
- self.assertEqual(self.comp_obj._get_usageState(), CF.Device.BUSY)
- for proc in procs:
- proc.kill()
- for i in range(40):
- br=self.comp.busy_reason.queryValue()
- if br == "":
- break
- time.sleep(1.5)
- self.assertEqual(self.comp_obj._get_usageState(), CF.Device.IDLE)
- self.assertEqual(self.comp.busy_reason.queryValue(), "")
- time.sleep(1)
- try:
- # kill all busy.py just in case
- os.system('pkill -9 -f busy.py')
- except OSError:
- pass
def visual_testBusy(self):
@@ -484,7 +777,7 @@ def visual_testBusy(self):
sleep_time = 7
procs = []
for core in range(cores*2):
- procs.append(subprocess.Popen('./busy.py'))
+ procs.append(subprocess.Popen('bin/busy.py'))
end_time = time.time() + sleep_time
while end_time > time.time():
print str(time.time()) + " busy reason: " + str(self.comp.busy_reason)
@@ -499,7 +792,7 @@ def visual_testBusy(self):
self.assertEqual(self.comp_obj._get_usageState(), CF.Device.IDLE)
self.assertEqual(self.comp.busy_reason, "")
- fs_stub = ComponentTests.FileSystemStub()
+ fs_stub = ComponentTests.FileSystemStub('./dat')
fs_stub_var = fs_stub._this()
self.comp_obj.load(fs_stub_var, "/component_stub.py", CF.LoadableDevice.EXECUTABLE)
@@ -518,7 +811,7 @@ def visual_testBusy(self):
cores = multiprocessing.cpu_count()
procs = []
for core in range(cores*2):
- procs.append(subprocess.Popen('./busy.py'))
+ procs.append(subprocess.Popen('bin/busy.py'))
end_time = time.time() + sleep_time
while end_time > time.time():
print str(time.time()) + " busy reason: " + str(self.comp.busy_reason)
@@ -558,7 +851,7 @@ def No_testScreenExecute(self):
useScreen = qr[0].value.value()
self.assertEqual(useScreen, True)
- fs_stub = ComponentTests.FileSystemStub()
+ fs_stub = ComponentTests.FileSystemStub('./dat')
fs_stub_var = fs_stub._this()
self.comp_obj.load(fs_stub_var, "/component_stub.py", CF.LoadableDevice.EXECUTABLE)
@@ -625,7 +918,7 @@ def No_testScreenExecute(self):
def test_scraping_proc(self):
# start up subprocess with spaces in the name...
- proc="./busy.py"
+ proc="bin/busy.py"
sproc="./spacely sprockets"
shutil.copy(proc,sproc)
procs = subprocess.Popen(sproc)
@@ -644,84 +937,7 @@ def test_scraping_proc(self):
except:
pass
-
- def testPropertyEvents(self):
- class Consumer_i(CosEventChannelAdmin__POA.ProxyPushConsumer):
- def __init__(self, parent, instance_id):
- self.supplier = None
- self.parent = parent
- self.instance_id = instance_id
- self.existence_lock = threading.Lock()
-
- def push(self, data):
- self.parent.actionQueue.put(data)
-
- def connect_push_supplier(self, supplier):
- self.supplier = supplier
-
- def disconnect_push_consumer(self):
- self.existence_lock.acquire()
- try:
- self.supplier.disconnect_push_supplier()
- except:
- pass
- self.existence_lock.release()
-
- class SupplierAdmin_i(CosEventChannelAdmin__POA.SupplierAdmin):
- def __init__(self, parent):
- self.parent = parent
- self.instance_counter = 0
-
- def obtain_push_consumer(self):
- self.instance_counter += 1
- self.parent.consumer_lock.acquire()
- self.parent.consumers[self.instance_counter] = Consumer_i(self.parent,self.instance_counter)
- objref = self.parent.consumers[self.instance_counter]._this()
- self.parent.consumer_lock.release()
- return objref
-
- class EventChannelStub(CosEventChannelAdmin__POA.EventChannel):
- def __init__(self):
- self.consumer_lock = threading.RLock()
- self.consumers = {}
- self.actionQueue = Queue.Queue()
- self.supplier_admin = SupplierAdmin_i(self)
-
- def for_suppliers(self):
- return self.supplier_admin._this()
-
- #######################################################################
- # Launch the device
- self.runGPP({"propertyEventRate": 5})
-
- orb = CORBA.ORB_init()
- obj_poa = orb.resolve_initial_references("RootPOA")
- poaManager = obj_poa._get_the_POAManager()
- poaManager.activate()
-
- eventChannel = EventChannelStub()
- eventChannelId = obj_poa.activate_object(eventChannel)
- eventPort = self.comp_obj.getPort("propEvent")
- eventPort = eventPort._narrow(CF.Port)
- eventPort.connectPort(eventChannel._this(), "eventChannel")
-
- #configureProps = self.getPropertySet(kinds=("configure",), modes=("readwrite", "writeonly"), includeNil=False)
- configureProps = [CF.DataType(id='DCE:22a60339-b66e-4309-91ae-e9bfed6f0490',value=any.to_any(81))]
- self.comp_obj.configure(configureProps)
-
- # Make sure the background status events are emitted
- time.sleep(0.5)
-
- self.assert_(eventChannel.actionQueue.qsize() > 0)
-
- event = eventChannel.actionQueue.get()
- event = any.from_any(event, keep_structs=True)
- event_dict = ossie.properties.props_to_dict(event.properties)
- self.assert_(self.comp_obj._get_identifier() == event.sourceId)
- self.assert_('DCE:22a60339-b66e-4309-91ae-e9bfed6f0490' == event.properties[0].id)
- self.assert_(81 == any.from_any(event.properties[0].value))
-
-
+
def test_mcastNicThreshold(self):
# set mcast exec param values for the test
@@ -824,19 +1040,6 @@ def test_loadCapacity(self):
allocProps = [CF.DataType(id='DCE:72c1c4a9-2bcf-49c5-bafd-ae2c1d567056',value=any.to_any(capacity*2))]
self.assertRaises( CF.Device.InsufficientCapacity, self.comp_obj.allocateCapacity, allocProps)
- def test_sys_limits(self):
-
- self.runGPP()
- p=CF.DataType(id='sys_limits',value=any.to_any(None))
- retval = self.comp.query([p])[0].value._v
- ids = []
- for item in retval:
- ids.append(item.id)
- self.assertTrue('sys_limits::current_threads')
- self.assertTrue('sys_limits::max_threads')
- self.assertTrue('sys_limits::current_open_files')
- self.assertTrue('sys_limits::max_open_files')
-
def get_single_nic_interface(self):
import commands
(exitstatus, ifconfig_info) = commands.getstatusoutput('/sbin/ifconfig -a')
@@ -993,458 +1196,287 @@ def test_threshold_usagestate(self):
self.assertEquals(ustate, CF.Device.IDLE)
+ def test_threshold_usagestate_ignored(self):
- def DeployWithAffinityOptions(self, options_list, numa_layout_test, bl_cpus ):
- self.runGPP()
-
- # enable affinity processing..
- props=[ossie.cf.CF.DataType(id='affinity', value=CORBA.Any(CORBA.TypeCode("IDL:CF/Properties:1.0"),
- [ ossie.cf.CF.DataType(id='affinity::exec_directive_value', value=CORBA.Any(CORBA.TC_string, '')),
- ossie.cf.CF.DataType(id='affinity::exec_directive_class', value=CORBA.Any(CORBA.TC_string, 'socket')),
- ossie.cf.CF.DataType(id='affinity::force_override', value=CORBA.Any(CORBA.TC_boolean, False)),
- ossie.cf.CF.DataType(id='affinity::blacklist_cpus', value=CORBA.Any(CORBA.TC_string, bl_cpus)),
- ossie.cf.CF.DataType(id='affinity::deploy_per_socket', value=CORBA.Any(CORBA.TC_boolean, False)),
- ossie.cf.CF.DataType(id='affinity::disabled', value=CORBA.Any(CORBA.TC_boolean, False)) ## enable affinity
- ] ))]
+ self.get_single_nic_interface()
+ if len(self.nic_list)> 1:
+ self.runGPP(configure={'nic_interfaces' : [ self.nic_list[0] ]})
+ else:
+ self.runGPP()
- self.comp_obj.configure(props)
+ self.comp.thresholds.ignore = True
- self.assertEqual(self.comp_obj._get_usageState(), CF.Device.IDLE)
-
- fs_stub = ComponentTests.FileSystemStub()
- fs_stub_var = fs_stub._this()
+ # set cpu to be 100.00 ... the check busy state..
+ orig_thres = self.comp.thresholds.cpu_idle.queryValue()
+ self.comp.thresholds.cpu_idle = 100.00
+ ustate=None
+ for i in xrange(6):
+ ustate= self.comp._get_usageState()
+ if ustate == CF.Device.BUSY: break
+ time.sleep(.5)
- ## Run a component with NIC based affinity
- self.comp_obj.load(fs_stub_var, "/component_stub.py", CF.LoadableDevice.EXECUTABLE)
- self.assertEqual(os.path.isfile("component_stub.py"), True) # Technically this is an internal implementation detail that the file is loaded into the CWD of the device
-
- comp_id = "DCE:00000000-0000-0000-0000-000000000000:waveform_1"
- app_id = "waveform_1"
- appReg = ApplicationRegistrarStub(comp_id, app_id)
- appreg_ior = sb.orb.object_to_string(appReg._this())
- pid = self.comp_obj.execute("/component_stub.py", [
- CF.DataType(id="AFFINITY", value=any.to_any( options_list ) ) ],
- [CF.DataType(id="COMPONENT_IDENTIFIER", value=any.to_any(comp_id)),
- CF.DataType(id="NAME_BINDING", value=any.to_any("component_stub")),CF.DataType(id="PROFILE_NAME", value=any.to_any("/component_stub/component_stub.spd.xml")),
- CF.DataType(id="NAMING_CONTEXT_IOR", value=any.to_any(appreg_ior))])
- self.assertNotEqual(pid, 0)
-
- self.check_affinity( 'component_stub.py', get_match(numa_layout_test), False)
-
- try:
- os.kill(pid, 0)
- except OSError:
- self.fail("Process failed to execute")
- time.sleep(1)
- self.comp_obj.terminate(pid)
- try:
- os.kill(pid, 0)
- except OSError:
- pass
- else:
- self.fail("Process failed to terminate")
+ self.assertNotEquals(ustate, CF.Device.BUSY)
+ # set cpu idle back
+ self.comp.thresholds.cpu_idle = orig_thres
+ ustate=None
+ for i in xrange(6):
+ ustate= self.comp._get_usageState()
+ if ustate == CF.Device.IDLE: break
+ time.sleep(.5)
- def testNicAffinity(self):
- self.DeployWithAffinityOptions( [ CF.DataType(id='nic',value=any.to_any(affinity_test_src['eface'])) ], "sock0", '' )
+ self.assertEquals(ustate, CF.Device.IDLE)
- def testNicAffinityWithBlackList(self):
- self.DeployWithAffinityOptions( [ CF.DataType(id='nic',value=any.to_any(affinity_test_src['eface'])) ], "sock0sans0", '0' )
+ # set mem_free
+ orig_thres = self.comp.thresholds.mem_free.queryValue()
+ mem_free = self.comp.memFree.queryValue()
+ self.comp.thresholds.mem_free = mem_free+2000
+ ustate=None
+ for i in xrange(6):
+ ustate= self.comp._get_usageState()
+ if ustate == CF.Device.BUSY: break
+ time.sleep(.5)
- def testCpuAffinity(self):
- if maxcpus > 6:
- self.DeployWithAffinityOptions( [ CF.DataType(id='affinity::exec_directive_class',value=any.to_any('cpu')),
- CF.DataType(id='affinity::exec_directive_value',value=any.to_any(affinity_test_src['5'])) ], "5", '' )
+ self.assertNotEquals(ustate, CF.Device.BUSY)
- def testSocketAffinity(self):
- self.DeployWithAffinityOptions( [ CF.DataType(id='affinity::exec_directive_class',value=any.to_any('socket')),
- CF.DataType(id='affinity::exec_directive_value',value=any.to_any(affinity_test_src['sock1'])) ],
- "sock1sans0", '0' )
+ # set mem_free back
+ self.comp.thresholds.mem_free = orig_thres
+ ustate=None
+ for i in xrange(6):
+ ustate= self.comp._get_usageState()
+ if ustate == CF.Device.IDLE: break
+ time.sleep(.5)
- def testDeployOnSocket(self):
- self.runGPP()
+ self.assertEquals(ustate, CF.Device.IDLE)
- # enable affinity processing..
- props=[ossie.cf.CF.DataType(id='affinity', value=CORBA.Any(CORBA.TypeCode("IDL:CF/Properties:1.0"),
- [ ossie.cf.CF.DataType(id='affinity::exec_directive_value', value=CORBA.Any(CORBA.TC_string, '')),
- ossie.cf.CF.DataType(id='affinity::exec_directive_class', value=CORBA.Any(CORBA.TC_string, 'socket')),
- ossie.cf.CF.DataType(id='affinity::force_override', value=CORBA.Any(CORBA.TC_boolean, False)),
- ossie.cf.CF.DataType(id='affinity::blacklist_cpus', value=CORBA.Any(CORBA.TC_string, '')),
- ossie.cf.CF.DataType(id='affinity::deploy_per_socket', value=CORBA.Any(CORBA.TC_boolean, True)), ## enable deploy_on
- ossie.cf.CF.DataType(id='affinity::disabled', value=CORBA.Any(CORBA.TC_boolean, False)) ## enable affinity
- ] ))]
- self.comp_obj.configure(props)
+ # set load_avg
+ orig_thres = self.comp.thresholds.load_avg.queryValue()
+ self.comp.thresholds.load_avg=0.0
+ ustate=None
+ for i in xrange(6):
+ ustate= self.comp._get_usageState()
+ if ustate == CF.Device.BUSY: break
+ time.sleep(.5)
- self.assertEqual(self.comp_obj._get_usageState(), CF.Device.IDLE)
-
- fs_stub = ComponentTests.FileSystemStub()
- fs_stub_var = fs_stub._this()
+ self.assertNotEquals(ustate, CF.Device.BUSY)
- ## Run a component with NIC based affinity
- self.comp_obj.load(fs_stub_var, "/component_stub.py", CF.LoadableDevice.EXECUTABLE)
- self.assertEqual(os.path.isfile("component_stub.py"), True) # Technically this is an internal implementation detail that the file is loaded into the CWD of the device
-
- comp_id = "DCE:00000000-0000-0000-0000-000000000000:waveform_1"
- app_id = "waveform_1"
- appReg = ApplicationRegistrarStub(comp_id, app_id)
- appreg_ior = sb.orb.object_to_string(appReg._this())
- pid0 = self.comp_obj.execute("/component_stub.py", [],
- [CF.DataType(id="COMPONENT_IDENTIFIER", value=any.to_any(comp_id)),
- CF.DataType(id="NAME_BINDING", value=any.to_any("component_stub")),CF.DataType(id="PROFILE_NAME", value=any.to_any("/component_stub/component_stub.spd.xml")),
- CF.DataType(id="NAMING_CONTEXT_IOR", value=any.to_any(appreg_ior))])
- self.assertNotEqual(pid0, 0)
+ # set load_avg back
+ self.comp.thresholds.load_avg = orig_thres
+ ustate=None
+ for i in xrange(6):
+ ustate= self.comp._get_usageState()
+ if ustate == CF.Device.IDLE: break
+ time.sleep(.5)
- comp_id = "DCE:00000000-0000-0000-0000-000000000001:waveform_1"
- app_id = "waveform_1"
- appReg = ApplicationRegistrarStub(comp_id, app_id)
- appreg_ior = sb.orb.object_to_string(appReg._this())
- pid1 = self.comp_obj.execute("/component_stub.py", [],
- [CF.DataType(id="COMPONENT_IDENTIFIER", value=any.to_any(comp_id)),
- CF.DataType(id="NAME_BINDING", value=any.to_any("component_stub")),CF.DataType(id="PROFILE_NAME", value=any.to_any("/component_stub/component_stub.spd.xml")),
- CF.DataType(id="NAMING_CONTEXT_IOR", value=any.to_any(appreg_ior))])
+ self.assertEquals(ustate, CF.Device.IDLE)
- self.assertNotEqual(pid1, 0)
- self.check_affinity( 'component_stub.py', get_match("sock0"), False, pid0)
- self.check_affinity( 'component_stub.py', get_match("sock0"), False, pid1)
-
- for pid in [ pid0, pid1 ]:
- try:
- os.kill(pid, 0)
- except OSError:
- self.fail("Process failed to execute")
- time.sleep(1)
- self.comp_obj.terminate(pid)
- try:
- os.kill(pid, 0)
- except OSError:
- pass
+@requireNuma
+class AffinityTests(GPPSandboxTest):
+ def setUp(self):
+ super(AffinityTests,self).setUp()
+
+ # Always enable affinity handling for these tests
+ self.comp.affinity.disabled = False
+
+ def _getAllowedCpuList(self, pid):
+ filename = '/proc/%d/status' % pid
+ with open(filename, 'r') as fp:
+ for line in fp:
+ if not 'Cpus_allowed_list' in line:
+ continue
+ cpu_list = line.split()[1]
+ return numa.parseValues(cpu_list, ",")
+ return []
+
+ def _getNumCpus(self):
+ output=2
+ try:
+ status,output=commands.getstatusoutput("ls -d /sys/devices/system/cpu/cpu[0-9]* | wc -l")
+ if status == 0:
+ return int(output)
else:
- self.fail("Process failed to terminate")
-
- def testForceOverride(self):
- self.runGPP()
+ status,output=commands.getstatusoutput("lscpu | egrep '^CPU\(' | awk '{ print $2 }'")
+ return int(output)
+ except:
+ pass
+ return output
+
+ def _deployWithAffinityOptions(self, name, affinity={}):
+ options = {}
+ if affinity:
+ options['AFFINITY'] = [CF.DataType(k, any.to_any(v)) for k,v in affinity.items()]
+ pid, comp = self._launchComponentStub(name, options=options)
+ return pid
+
+ def _getNicAffinity(self, nic):
+ ncpus=self._getNumCpus()
+ cpu_list = []
+ with open('/proc/interrupts', 'r') as fp:
+ for line in fp:
+ # Remove final newline and make sure the line ends with the NIC
+ # name (in the unlikely event a machine goes up to "em11")
+ line = line.rstrip()
+ if not line.endswith(nic):
+ continue
+ # Discard the first entry (the IRQ number) and the last two
+ # (type and name) to get the CPU IRQ service totals
+ ncpus+=1
+ cpu_irqs = line.split()[1:ncpus]
+ for cpu, count in enumerate(cpu_irqs):
+ if int(count) > 0:
+ cpu_list.append(cpu)
+ break
+ return cpu_list
- # enable affinity processing..
- props=[ossie.cf.CF.DataType(id='affinity', value=CORBA.Any(CORBA.TypeCode("IDL:CF/Properties:1.0"),
- [ ossie.cf.CF.DataType(id='affinity::exec_directive_value', value=CORBA.Any(CORBA.TC_string, '1')),
- ossie.cf.CF.DataType(id='affinity::exec_directive_class', value=CORBA.Any(CORBA.TC_string, 'socket')),
- ossie.cf.CF.DataType(id='affinity::force_override', value=CORBA.Any(CORBA.TC_boolean, True)),
- ossie.cf.CF.DataType(id='affinity::blacklist_cpus', value=CORBA.Any(CORBA.TC_string, '')),
- ossie.cf.CF.DataType(id='affinity::deploy_per_socket', value=CORBA.Any(CORBA.TC_boolean, True)),
- ossie.cf.CF.DataType(id='affinity::disabled', value=CORBA.Any(CORBA.TC_boolean, False)) ## enable affinity
- ] ))]
+ @skipUnless(len(topology.nodes) > 1, 'At least two NUMA nodes required')
+ def testNicAffinity(self):
+ # Pick the first NIC and figure out which CPU(s) service its IRQ, then
+ # build the list of all CPUs on that node
+ self.assertNotEqual(0, len(self.comp.available_nic_interfaces), 'no available NIC interfaces')
+ nic = self.comp.available_nic_interfaces[0]
+ nodes = set(topology.getNodeForCpu(cpu) for cpu in self._getNicAffinity(nic))
+ # Join the CPU lists together
+ nic_cpus = sum((node.cpus for node in nodes), [])
+
+ # Launch the component stub with affinity based on the selected NIC;
+ # with no CPU blacklist, GPP will assign the component to all of the
+ # CPUs on the same socket(s)
+ pid = self._deployWithAffinityOptions('nic_affinity_1', {'nic':nic})
+ allowed_cpus = self._getAllowedCpuList(pid)
+ self.assertEqual(nic_cpus, allowed_cpus)
- self.comp_obj.configure(props)
+ def testNicAffinityWithBlackList(self):
+ # Pick the first NIC
+ self.assertNotEqual(0, len(self.comp.available_nic_interfaces), 'no available NIC interfaces')
+ nic = self.comp.available_nic_interfaces[0]
+ nic_cpus = self._getNicAffinity(nic)
+ # find all the cpus for each node
+ nodes = set(topology.getNodeForCpu(cpu) for cpu in self._getNicAffinity(nic))
+ cpulist = sum((node.cpus for node in nodes), [])
+ if len(nic_cpus) > 1:
+ # There's more than one CPU assigned to service NIC interrupts,
+ # just blacklist the first one
+ blacklist_cpu = nic_cpus.pop(0)
+ else:
+ # Only one CPU for NIC interrupts, figure out its node and
+ # blacklist one of the other CPUs
+ cpu = nic_cpus[0]
+ node = topology.getNodeForCpu(cpu)
+ cpulist = node.cpus[:]
+ # Find the CPU in the list and select the next one (wrapping around
+ # as necessary) to ensure that we don't blacklist the wrong CPU
+ index = node.cpus.index(cpu)
+ index = (index + 1) % len(node.cpus)
+ blacklist_cpu = node.cpus[index]
- self.assertEqual(self.comp_obj._get_usageState(), CF.Device.IDLE)
- fs_stub = ComponentTests.FileSystemStub()
- fs_stub_var = fs_stub._this()
+ # default nic deployment is per socket, use cpulist per
+ # node to check results
+ nic_cpus=[ x for x in cpulist if x not in [blacklist_cpu]]
+
+ # With a CPU blacklist, only the CPUs that are expliclitly allowed to
+ # handle the NIC are in the allowed list, as opposed to all CPUs in the
+ # same socket(s)
+ self.comp.affinity.blacklist_cpus = str(blacklist_cpu)
+ pid = self._deployWithAffinityOptions('nic_affinity_bl_1', {'nic':nic})
+ allowed_cpus = self._getAllowedCpuList(pid)
+ self.assertEqual(nic_cpus, allowed_cpus)
- ## Run a component with NIC based affinity
- self.comp_obj.load(fs_stub_var, "/component_stub.py", CF.LoadableDevice.EXECUTABLE)
- self.assertEqual(os.path.isfile("component_stub.py"), True) # Technically this is an internal implementation detail that the file is loaded into the CWD of the device
-
- comp_id = "DCE:00000000-0000-0000-0000-000000000000:waveform_1"
- app_id = "waveform_1"
- appReg = ApplicationRegistrarStub(comp_id, app_id)
- appreg_ior = sb.orb.object_to_string(appReg._this())
- pid0 = self.comp_obj.execute("/component_stub.py", [],
- [CF.DataType(id="COMPONENT_IDENTIFIER", value=any.to_any(comp_id)),
- CF.DataType(id="NAME_BINDING", value=any.to_any("component_stub")),CF.DataType(id="PROFILE_NAME", value=any.to_any("/component_stub/component_stub.spd.xml")),
- CF.DataType(id="NAMING_CONTEXT_IOR", value=any.to_any(appreg_ior))])
- self.assertNotEqual(pid0, 0)
+ def testCpuAffinity(self):
+ # Pick the last CPU in the last node; the component should only be
+ # allowed to run on that CPU
+ cpu = topology.nodes[-1].cpus[-1]
+ pid = self._deployWithAffinityOptions('cpu_affinity_1', {'affinity::exec_directive_class': 'cpu',
+ 'affinity::exec_directive_value': cpu})
+ allowed_cpus = self._getAllowedCpuList(pid)
+ self.assertEqual([cpu], allowed_cpus)
+
+ @skipUnless(len(topology.nodes) > 1, 'At least two NUMA nodes are required')
+ def testSocketAffinity(self):
+ # Pick the last node and deploy to it; the process should be allowed to
+ # run on all CPUs from that node
+ node = topology.nodes[-1]
+ pid = self._deployWithAffinityOptions('socket_affinity_1', {'affinity::exec_directive_class': 'socket',
+ 'affinity::exec_directive_value': node.node})
+ allowed_cpus = self._getAllowedCpuList(pid)
+ self.assertEqual(node.cpus, allowed_cpus)
+
+ @skipUnless(len(topology.nodes) > 1, 'At least two NUMA nodes are required')
+ def testSocketAffinityWithBlackList(self):
+ # Pick the last node for deployment, but blacklist the first half of
+ # its CPUs
+ node = topology.nodes[-1]
+ cpu_count = len(node.cpus)
+ blacklist_cpus = node.cpus[:cpu_count/2]
+ cpu_list = node.cpus[cpu_count/2:]
+
+ self.comp.affinity.blacklist_cpus = ','.join(str(cpu) for cpu in blacklist_cpus)
+ pid = self._deployWithAffinityOptions('socket_affinity_bl_1', {'affinity::exec_directive_class': 'socket',
+ 'affinity::exec_directive_value': node.node})
+ allowed_cpus = self._getAllowedCpuList(pid)
+ self.assertEqual(cpu_list, allowed_cpus)
- comp_id = "DCE:00000000-0000-0000-0000-000000000001:waveform_1"
- app_id = "waveform_1"
- appReg = ApplicationRegistrarStub(comp_id, app_id)
- appreg_ior = sb.orb.object_to_string(appReg._this())
- pid1 = self.comp_obj.execute("/component_stub.py", [],
- [CF.DataType(id="COMPONENT_IDENTIFIER", value=any.to_any(comp_id)),
- CF.DataType(id="NAME_BINDING", value=any.to_any("component_stub")),CF.DataType(id="PROFILE_NAME", value=any.to_any("/component_stub/component_stub.spd.xml")),
- CF.DataType(id="NAMING_CONTEXT_IOR", value=any.to_any(appreg_ior))])
+ def testForceOverride(self):
+ # Configure the GPP to always deploy to CPU 0
+ self.comp.affinity.exec_directive_value = '0'
+ self.comp.affinity.exec_directive_class = 'cpu'
+ self.comp.affinity.force_override = True
- self.assertNotEqual(pid1, 0)
+ # Set a runtime affinity directive for CPU1; this should be ignored
+ pid = self._deployWithAffinityOptions('force_override_1', {'affinity::exec_directive_class': 'cpu',
+ 'affinity::exec_directive_value': '1'})
+ allowed_cpus = self._getAllowedCpuList(pid)
+ self.assertEqual([0], allowed_cpus)
- self.check_affinity( 'component_stub.py',get_match("sock1"), False, pid0)
- self.check_affinity( 'component_stub.py',get_match("sock1"), False, pid1)
-
- for pid in [ pid0, pid1 ]:
- try:
- os.kill(pid, 0)
- except OSError:
- self.fail("Process failed to execute")
- time.sleep(1)
- self.comp_obj.terminate(pid)
- try:
- os.kill(pid, 0)
- except OSError:
- pass
- else:
- self.fail("Process failed to terminate")
+ def testDeployOnSocket(self):
+ self.comp.affinity.deploy_per_socket = True
- def testReservation(self):
- self.runGPP()
- self.comp.thresholds.cpu_idle = 50
- self.comp.reserved_capacity_per_component = 0.5
- number_reservations = (self.comp.processor_cores / self.comp.reserved_capacity_per_component) * ((100-self.comp.thresholds.cpu_idle)/100.0)
- comp_id = "DCE:00000000-0000-0000-0000-000000000000:waveform_1"
- app_id = "waveform_1"
- appReg = ApplicationRegistrarStub(comp_id, app_id)
- appreg_ior = sb.orb.object_to_string(appReg._this())
- self.assertEquals(self.comp._get_usageState(),CF.Device.IDLE)
- for i in range(int(number_reservations-1)):
- self.child_pids.append(self.comp.ref.execute("/component_stub.py", [], [CF.DataType(id="COMPONENT_IDENTIFIER", value=any.to_any(comp_id+str(i))), CF.DataType(id="NAME_BINDING", value=any.to_any("component_stub_"+str(i))), CF.DataType(id="PROFILE_NAME", value=any.to_any("/component_stub/component_stub.spd.xml")), CF.DataType(id="NAMING_CONTEXT_IOR", value=any.to_any(appreg_ior))]))
- time.sleep(0.1)
- time.sleep(2)
- self.assertEquals(self.comp._get_usageState(),CF.Device.ACTIVE)
- self.child_pids.append(self.comp_obj.execute("/component_stub.py", [], [CF.DataType(id="COMPONENT_IDENTIFIER", value=any.to_any(comp_id)),
- CF.DataType(id="NAME_BINDING", value=any.to_any("component_stub")),CF.DataType(id="PROFILE_NAME", value=any.to_any("/component_stub/component_stub.spd.xml")),
- CF.DataType(id="NAMING_CONTEXT_IOR", value=any.to_any(appreg_ior))]))
- time.sleep(2)
- self.assertEquals(self.comp._get_usageState(),CF.Device.BUSY)
+ pid0 = self._deployWithAffinityOptions('deploy_on_socket_1')
+ allowed_cpus = self._getAllowedCpuList(pid0)
+ self.assertEqual(topology.nodes[0].cpus, allowed_cpus)
- def testFloorReservation(self):
- self.runGPP()
- self.comp.thresholds.cpu_idle = 10
- self.comp.reserved_capacity_per_component = 0.5
- number_reservations = (self.comp.processor_cores / self.comp.reserved_capacity_per_component) * ((100-self.comp.thresholds.cpu_idle)/100.0)
- comp_id = "DCE:00000000-0000-0000-0000-000000000000:waveform_1"
- app_id = "waveform_1"
- appReg = ApplicationRegistrarStub(comp_id, app_id)
- appreg_ior = sb.orb.object_to_string(appReg._this())
- self.assertEquals(self.comp._get_usageState(),CF.Device.IDLE)
- self.child_pids.append(self.comp_obj.execute("/component_stub.py", [], [CF.DataType(id="COMPONENT_IDENTIFIER", value=any.to_any(comp_id+'_1')), CF.DataType(id="NAME_BINDING", value=any.to_any("component_stub_1")), CF.DataType(id="PROFILE_NAME", value=any.to_any("/component_stub/component_stub.spd.xml")), CF.DataType(id="NAMING_CONTEXT_IOR", value=any.to_any(appreg_ior))]))
- time.sleep(2.1)
- self.assertEquals(self.comp._get_usageState(),CF.Device.ACTIVE)
- self.child_pids.append(self.comp_obj.execute("/component_stub.py", [], [CF.DataType(id="COMPONENT_IDENTIFIER", value=any.to_any(comp_id+'_1')), CF.DataType(id="NAME_BINDING", value=any.to_any("component_stub_1")), CF.DataType(id="PROFILE_NAME", value=any.to_any("/component_stub/component_stub.spd.xml")), CF.DataType(id="NAMING_CONTEXT_IOR", value=any.to_any(appreg_ior))]))
- time.sleep(2.1)
- self.assertEquals(self.comp._get_usageState(),CF.Device.ACTIVE)
- pid = self.child_pids.pop()
- self.comp_obj.terminate(pid)
- time.sleep(2.1)
- reservation = CF.DataType(id="RH::GPP::MODIFIED_CPU_RESERVATION_VALUE", value=any.to_any(1000.0))
- self.child_pids.append(self.comp_obj.execute("/component_stub.py", [], [CF.DataType(id="COMPONENT_IDENTIFIER", value=any.to_any(comp_id)),
- CF.DataType(id="NAME_BINDING", value=any.to_any("component_stub")),CF.DataType(id="PROFILE_NAME", value=any.to_any("/component_stub/component_stub.spd.xml")),
- CF.DataType(id="NAMING_CONTEXT_IOR", value=any.to_any(appreg_ior)), reservation]))
- time.sleep(2)
- self.assertEquals(self.comp._get_usageState(),CF.Device.BUSY)
+ pid1 = self._deployWithAffinityOptions('deploy_on_socket_2')
+ allowed_cpus = self._getAllowedCpuList(pid1)
+ self.assertEqual(topology.nodes[0].cpus, allowed_cpus)
-class ComponentTests_SystemReservations(ossie.utils.testing.ScaComponentTestCase):
+class DomainSupport(scatest.CorbaTestCase):
"""Test for all component implementations in test"""
- child_pids = []
- dom = None
- _domainBooter = None
- _domainManager = None
- _deviceBooter = None
- _deviceLock = threading.Lock()
- _deviceBooters = []
- _deviceManagers = []
-
- def _getDeviceManager(self, domMgr, id):
- for devMgr in domMgr._get_deviceManagers():
- try:
- if id == devMgr._get_identifier():
- return devMgr
- except CORBA.Exception:
- # The DeviceManager being checked is unreachable.
- pass
- return None
- def waitTermination(self, child, timeout=5.0, pause=0.1):
- while child.poll() is None and timeout > 0.0:
- timeout -= pause
- time.sleep(pause)
- return child.poll() != None
-
- def terminateChild(self, child, signals=(signal.SIGINT, signal.SIGTERM)):
- if child.poll() != None:
- return
- try:
- for sig in signals:
- os.kill(child.pid, sig)
- if self.waitTermination(child):
- break
- child.wait()
- except OSError, e:
- pass
- finally:
- pass
-
- def launchDomainManager(self, dmdFile="", domain_name = '', *args, **kwargs):
- # Only allow one DomainManager, although this isn't a hard requirement.
- # If it has exited, allow a relaunch.
- if self._domainBooter and self._domainBooter.poll() == None:
- return (self._domainBooter, self._domainManager)
-
- # Launch the nodebooter.
- self._domainBooter = spawnNodeBooter(dmdFile=dmdFile, domainname = domain_name, *args, **kwargs)
- number_attempts = 0
- while self._domainBooter.poll() == None:
- try:
- self.dom = redhawk.attach(domain_name)
- except:
- number_attempts += 1
- if number_attempts >= 20:
- raise
- time.sleep(0.1)
- continue
- self._domainManager = self.dom.ref
- if self._domainManager:
- try:
- self._domainManager._get_identifier()
- break
- except:
- pass
- return (self._domainBooter, self._domainManager)
-
- def _addDeviceBooter(self, devBooter):
- self._deviceLock.acquire()
- try:
- self._deviceBooters.append(devBooter)
- finally:
- self._deviceLock.release()
-
- def _addDeviceManager(self, devMgr):
- self._deviceLock.acquire()
- try:
- self._deviceManagers.append(devMgr)
- finally:
- self._deviceLock.release()
-
- def launchDeviceManager(self, dcdFile, domainManager=None, wait=True, *args, **kwargs):
- if not os.path.isfile(os.getcwd()+'/'+dcdFile):
- print "ERROR: Invalid DCD path provided to launchDeviceManager ", dcdFile
- return (None, None)
-
- # Launch the nodebooter.
- if domainManager == None:
- name = None
- else:
- name = domainManager._get_name()
- devBooter = spawnNodeBooter(dcdFile=os.getcwd()+'/'+dcdFile, domainname=name, *args, **kwargs)
- self._addDeviceBooter(devBooter)
-
- if wait:
- devMgr = self.waitDeviceManager(devBooter, dcdFile, domainManager)
+ def _makeLink(self, src, dest):
+ if os.path.exists(dest):
+ os.unlink(dest)
+ os.symlink(src, dest)
+
+ def launchDomainManager(self, *args, **kwargs):
+ domBooter, domMgr = super(DomainSupport,self).launchDomainManager(*args, loggingURI='', nodeBooterPath='nodeBooter', **kwargs)
+ if domMgr is None:
+ self.dom = None
else:
- devMgr = None
-
- return (devBooter, devMgr)
+ self.dom = redhawk.attach(domMgr._get_name())
+ return domBooter, domMgr
- def waitDeviceManager(self, devBooter, dcdFile, domainManager=None):
- try:
- dcdPath = os.getcwd()+'/'+dcdFile
- except IOError:
- print "ERROR: Invalid DCD path provided to waitDeviceManager", dcdFile
- return None
-
- # Parse the DCD file to get the identifier and number of devices, which can be
- # determined from the number of componentplacement elements.
- dcd = DCDParser.parse(dcdPath)
- if dcd.get_partitioning():
- numDevices = len(dcd.get_partitioning().get_componentplacement())
- else:
- numDevices = 0
-
- # Allow the caller to override the DomainManager (assuming they have a good reason).
- if not domainManager:
- domainManager = self._domainManager
-
- # As long as the nodebooter process is still alive, keep checking for the
- # DeviceManager.
- devMgr = None
- while devBooter.poll() == None:
- devMgrs = self.dom.devMgrs
- for dM in devMgrs:
- if dcd.get_id() == dM._get_identifier():
- devMgr = dM.ref
- #devMgr = self._getDeviceManager(domainManager, dcd.get_id())
- if devMgr:
- break
- time.sleep(0.1)
-
- if devMgr:
- self._waitRegisteredDevices(devMgr, numDevices)
- self._addDeviceManager(devMgr)
- return devMgr
-
- def _waitRegisteredDevices(self, devMgr, numDevices, timeout=5.0, pause=0.1):
- while timeout > 0.0:
- if (len(devMgr._get_registeredDevices())+len(devMgr._get_registeredServices())) == numDevices:
- return True
- else:
- timeout -= pause
- time.sleep(pause)
- return False
+ def launchDeviceManager(self, *args, **kwargs):
+ return super(DomainSupport,self).launchDeviceManager(*args, loggingURI='', nodeBooterPath='nodeBooter', **kwargs)
def setUp(self):
- super(ComponentTests_SystemReservations,self).setUp()
- self.child_pids=[]
- self._domainBooter = None
- self._domainManager = None
- self._deviceBooter = None
- self.orig_sdrroot=os.getenv('SDRROOT')
- os.putenv('SDRROOT', os.getcwd()+'/sdr')
+ super(DomainSupport,self).setUp()
+ self.orig_sdrroot=os.environ['SDRROOT']
+ os.environ['SDRROOT'] = os.getcwd()+'/sdr'
print "\n-----------------------"
print "Running: ", self.id().split('.')[-1]
print "-----------------------\n"
- copyfile(self.orig_sdrroot+'/dom/mgr/DomainManager', 'sdr/dom/mgr/DomainManager')
- os.chmod('sdr/dom/mgr/DomainManager',0777)
- copyfile(self.orig_sdrroot+'/dev/mgr/DeviceManager', 'sdr/dev/mgr/DeviceManager')
- os.chmod('sdr/dev/mgr/DeviceManager',0777)
- if not os.path.exists('sdr/dev/devices/GPP/cpp'):
- os.makedirs('sdr/dev/devices/GPP/cpp')
- copyfile('../cpp/GPP', 'sdr/dev/devices/GPP/cpp/GPP')
- os.chmod('sdr/dev/devices/GPP/cpp/GPP',0777)
-
+ self._makeLink(self.orig_sdrroot+'/dom/mgr', 'sdr/dom/mgr')
+ self._makeLink(self.orig_sdrroot+'/dev/mgr', 'sdr/dev/mgr')
+ print 'done staging DomainManager'
def tearDown(self):
- super(ComponentTests_SystemReservations, self).tearDown()
- try:
- # kill all busy.py just in case
- os.system('pkill -9 -f busy.py')
- except OSError:
- pass
- for child_p in self.child_pids:
- try:
- print "teardown (2)", child_p
- os.system('kill -9 '+str(child_p))
- except OSError:
- pass
- if self.dom != None:
- time.sleep(1)
- self.dom.terminate()
- self.dom = None
- self.terminateChild(self._domainBooter)
- if self._domainBooter:
- self.terminateChild(self._domainBooter)
- if self._deviceBooter:
- self.terminateChild(self._deviceBooter)
- os.putenv('SDRROOT', self.orig_sdrroot)
+ super(DomainSupport, self).tearDown()
+ os.environ['SDRROOT'] = self.orig_sdrroot
-
- def runGPP(self, execparam_overrides={}, initialize=True):
- #######################################################################
- # Launch the component with the default execparams
- execparams = self.getPropertySet(kinds=("execparam",), modes=("readwrite", "writeonly"), includeNil=False)
- execparams = dict([(x.id, any.from_any(x.value)) for x in execparams])
- execparams.update(execparam_overrides)
- #execparams = self.getPropertySet(kinds=("execparam",), modes=("readwrite", "writeonly"), includeNil=False)
- #execparams = dict([(x.id, any.from_any(x.value)) for x in execparams])
- #self.launch(execparams, debugger='valgrind')
- self.launch(execparams, initialize=initialize )
-
- #######################################################################
- # Verify the basic state of the component
- self.assertNotEqual(self.comp_obj, None)
- self.assertEqual(self.comp_obj._non_existent(), False)
- self.assertEqual(self.comp_obj._is_a("IDL:CF/ExecutableDevice:1.0"), True)
- #self.assertEqual(self.spd.get_id(), self.comp_obj._get_identifier())
-
+class ComponentTests_SystemReservations(DomainSupport):
def close(self, value_1, value_2, margin = 0.01):
if (value_2 * (1-margin)) < value_1 and (value_2 * (1+margin)) > value_1:
return True
@@ -1457,9 +1489,9 @@ def float_eq(self, a,b,eps=0.0000001):
def testMonitorComponents(self):
self.assertEquals(os.path.isfile('sdr/dom/mgr/DomainManager'),True)
self.assertEquals(os.path.isfile('sdr/dev/mgr/DeviceManager'),True)
- self._domainBooter, domMgr = self.launchDomainManager(domain_name='REDHAWK_TEST_'+str(os.getpid()))
+ self._domainBooter, domMgr = self.launchDomainManager()
self.assertNotEquals(domMgr,None)
- self._deviceBooter, devMgr = self.launchDeviceManager("sdr/dev/nodes/DevMgr_sample/DeviceManager.dcd.xml", domainManager=self.dom.ref)
+ self._deviceBooter, devMgr = self.launchDeviceManager("/nodes/DevMgr_sample/DeviceManager.dcd.xml")
self.assertNotEquals(devMgr,None)
app_1=self.dom.createApplication('/waveforms/load_comp_w/load_comp_w.sad.xml','load_comp_w',[])
wait_amount = (self.dom.devMgrs[0].devs[0].threshold_cycle_time / 1000.0) * 6
@@ -1484,9 +1516,9 @@ def testMonitorComponents(self):
def testDeadlock(self):
self.assertEquals(os.path.isfile('sdr/dom/mgr/DomainManager'),True)
self.assertEquals(os.path.isfile('sdr/dev/mgr/DeviceManager'),True)
- self._domainBooter, domMgr = self.launchDomainManager(domain_name='REDHAWK_TEST_'+str(os.getpid()))
+ self._domainBooter, domMgr = self.launchDomainManager()
self.assertNotEquals(domMgr,None)
- self._deviceBooter, devMgr = self.launchDeviceManager("sdr/dev/nodes/DevMgr_sample/DeviceManager.dcd.xml", domainManager=self.dom.ref)
+ self._deviceBooter, devMgr = self.launchDeviceManager("/nodes/DevMgr_sample/DeviceManager.dcd.xml")
self.assertNotEquals(devMgr,None)
self.dom.devMgrs[0].devs[0].threshold_cycle_time = 50
count = 0
@@ -1502,9 +1534,9 @@ def testDeadlock(self):
def testSystemReservation(self):
self.assertEquals(os.path.isfile('sdr/dom/mgr/DomainManager'),True)
self.assertEquals(os.path.isfile('sdr/dev/mgr/DeviceManager'),True)
- self._domainBooter, domMgr = self.launchDomainManager(domain_name='REDHAWK_TEST_'+str(os.getpid()))
+ self._domainBooter, domMgr = self.launchDomainManager()
self.assertNotEquals(domMgr,None)
- self._deviceBooter, devMgr = self.launchDeviceManager("sdr/dev/nodes/DevMgr_sample/DeviceManager.dcd.xml", domainManager=self.dom.ref)
+ self._deviceBooter, devMgr = self.launchDeviceManager("/nodes/DevMgr_sample/DeviceManager.dcd.xml")
self.assertNotEquals(devMgr,None)
self.comp= self.dom.devMgrs[0].devs[0]
cpus = self.dom.devMgrs[0].devs[0].processor_cores
@@ -1516,6 +1548,8 @@ def testSystemReservation(self):
time.sleep(wait_amount)
self.assertEquals(self.close(upper_capacity, self.dom.devMgrs[0].devs[0].utilization[0]['maximum']), True)
+ time.sleep(1)
+
base_util = self.dom.devMgrs[0].devs[0].utilization[0]
subscribed = base_util['subscribed']
system_load_base = base_util['system_load']
@@ -1523,7 +1557,7 @@ def testSystemReservation(self):
extra_reservation = 1
_value=any.to_any(extra_reservation)
_value._t=CORBA.TC_double
- app_1=self.dom.createApplication('/waveforms/busy_w/busy_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='busy_comp_1',value=any.to_any(_value))]))])
+ app_1=self.dom.createApplication('/waveforms/busy_w/busy_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='busy_comp_1',value=_value)]))])
time.sleep(wait_amount)
base_util = self.dom.devMgrs[0].devs[0].utilization[0]
@@ -1532,7 +1566,7 @@ def testSystemReservation(self):
comp_load = base_util['component_load']
#print "After App1 Create subnow(sub) " , sub_now, " sys_load", system_load_now, " sys_load_base ", system_load_base, " comp_load ", comp_load, " subscribed(base) ", subscribed, " extra ", extra_reservation, " res per", res_per_comp, " idle cap mod ", idle_cap_mod
self.assertEquals(self.close(sub_now, extra_reservation), True)
-
+
app_2=self.dom.createApplication('/waveforms/busy_w/busy_w.sad.xml','busy_w',[])
time.sleep(wait_amount)
base_util = self.dom.devMgrs[0].devs[0].utilization[0]
@@ -1557,8 +1591,6 @@ def testSystemReservation(self):
else:
self.assertEqual(self.close(sub_now, extra_reservation+res_per_comp), True)
-
-
app_2.start()
time.sleep(wait_amount)
base_util = self.dom.devMgrs[0].devs[0].utilization[0]
@@ -1586,167 +1618,257 @@ def testSystemReservation(self):
self.assertEquals(self.close(sub_now, extra_reservation+res_per_comp ), True)
self.assertEquals(self.float_eq(sub_now_pre, sub_now, eps=.01), True)
+ def _verifyReservations(self, extra, application, wait_amount):
+ base_util = self.dom.devMgrs[0].devs[0].utilization[0]
+ system_load_now = base_util['system_load']
+ sub_now = base_util['subscribed']
+ comp_load = base_util['component_load']
+ self.assertEquals(self.close(sub_now, extra), True)
+ self.assertEquals(comp_load, 0)
+ application.start()
+ time.sleep(wait_amount)
+ base_util = self.dom.devMgrs[0].devs[0].utilization[0]
+ system_load_now = base_util['system_load']
+ sub_now = base_util['subscribed']
+ comp_load = base_util['component_load']
+ self.assertEquals(self.close(sub_now, extra), True)
+ self.assertEquals(self.close(comp_load, 2, margin=0.1), True)
+
+ application.stop()
+ time.sleep(wait_amount)
+ base_util = self.dom.devMgrs[0].devs[0].utilization[0]
+ system_load_now = base_util['system_load']
+ sub_now = base_util['subscribed']
+ comp_load = base_util['component_load']
+ self.assertEquals(self.close(sub_now, extra), True)
+ self.assertEquals(comp_load, 0)
+
+ def testAppReservation(self):
+ self.assertEquals(os.path.isfile('sdr/dom/mgr/DomainManager'),True)
+ self.assertEquals(os.path.isfile('sdr/dev/mgr/DeviceManager'),True)
+ self._domainBooter, domMgr = self.launchDomainManager()
+ self.assertNotEquals(domMgr,None)
+ self._deviceBooter, devMgr = self.launchDeviceManager("/nodes/DevMgr_sample/DeviceManager.dcd.xml")
+ self.assertNotEquals(devMgr,None)
+ self.comp= self.dom.devMgrs[0].devs[0]
+ cpus = self.dom.devMgrs[0].devs[0].processor_cores
+ cpu_thresh = self.dom.devMgrs[0].devs[0].thresholds.cpu_idle
+ res_per_comp = self.dom.devMgrs[0].devs[0].reserved_capacity_per_component
+ idle_cap_mod = 100.0 * res_per_comp / (cpus*1.0)
+ upper_capacity = cpus - (cpus * (cpu_thresh/100))
+ wait_amount = (self.dom.devMgrs[0].devs[0].threshold_cycle_time / 1000.0) * 4
+ time.sleep(wait_amount)
+ self.assertEquals(self.close(upper_capacity, self.dom.devMgrs[0].devs[0].utilization[0]['maximum']), True)
+
+ time.sleep(1)
+
+ base_util = self.dom.devMgrs[0].devs[0].utilization[0]
+ subscribed = base_util['subscribed']
+ system_load_base = base_util['system_load']
+
+ extra_reservation = 3
+ _value=any.to_any(extra_reservation)
+ _value._t=CORBA.TC_double
+ self.assertRaises(CF.ApplicationFactory.CreateApplicationError, self.dom.createApplication, '/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='busy_comp_1',value=_value)]))])
+ app_1=self.dom.createApplication('/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[])
+ time.sleep(wait_amount)
+ self._verifyReservations(extra_reservation, app_1, wait_amount)
+
+ app_1.releaseObject()
+ time.sleep(wait_amount)
+ base_util = self.dom.devMgrs[0].devs[0].utilization[0]
+ sub_now = base_util['subscribed']
+ comp_load = base_util['component_load']
+ self.assertEquals(sub_now, 0)
+
+ def testAppOverloadGenericReservation(self):
+ self.assertEquals(os.path.isfile('sdr/dom/mgr/DomainManager'),True)
+ self.assertEquals(os.path.isfile('sdr/dev/mgr/DeviceManager'),True)
+ self._domainBooter, domMgr = self.launchDomainManager()
+ self.assertNotEquals(domMgr,None)
+ self._deviceBooter, devMgr = self.launchDeviceManager("/nodes/DevMgr_sample/DeviceManager.dcd.xml")
+ self.assertNotEquals(devMgr,None)
+ self.comp= self.dom.devMgrs[0].devs[0]
+ cpus = self.dom.devMgrs[0].devs[0].processor_cores
+ cpu_thresh = self.dom.devMgrs[0].devs[0].thresholds.cpu_idle
+ res_per_comp = self.dom.devMgrs[0].devs[0].reserved_capacity_per_component
+ idle_cap_mod = 100.0 * res_per_comp / (cpus*1.0)
+ upper_capacity = cpus - (cpus * (cpu_thresh/100))
+ wait_amount = (self.dom.devMgrs[0].devs[0].threshold_cycle_time / 1000.0) * 4
+ time.sleep(wait_amount)
+ self.assertEquals(self.close(upper_capacity, self.dom.devMgrs[0].devs[0].utilization[0]['maximum']), True)
+
+ time.sleep(1)
+
+ base_util = self.dom.devMgrs[0].devs[0].utilization[0]
+ subscribed = base_util['subscribed']
+ system_load_base = base_util['system_load']
+
+ extra_reservation = 4
+ _value=any.to_any(extra_reservation)
+ _value._t=CORBA.TC_double
+ app_1=self.dom.createApplication('/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='',value=_value)]))])
+ time.sleep(wait_amount)
+ self._verifyReservations(extra_reservation, app_1, wait_amount)
+
+ def testAppOverloadSpecificReservation(self):
+ self.assertEquals(os.path.isfile('sdr/dom/mgr/DomainManager'),True)
+ self.assertEquals(os.path.isfile('sdr/dev/mgr/DeviceManager'),True)
+ self._domainBooter, domMgr = self.launchDomainManager()
+ self.assertNotEquals(domMgr,None)
+ self._deviceBooter, devMgr = self.launchDeviceManager("/nodes/DevMgr_sample/DeviceManager.dcd.xml")
+ self.assertNotEquals(devMgr,None)
+ self.comp= self.dom.devMgrs[0].devs[0]
+ cpus = self.dom.devMgrs[0].devs[0].processor_cores
+ cpu_thresh = self.dom.devMgrs[0].devs[0].thresholds.cpu_idle
+ res_per_comp = self.dom.devMgrs[0].devs[0].reserved_capacity_per_component
+ idle_cap_mod = 100.0 * res_per_comp / (cpus*1.0)
+ upper_capacity = cpus - (cpus * (cpu_thresh/100))
+ wait_amount = (self.dom.devMgrs[0].devs[0].threshold_cycle_time / 1000.0) * 4
+ time.sleep(wait_amount)
+ self.assertEquals(self.close(upper_capacity, self.dom.devMgrs[0].devs[0].utilization[0]['maximum']), True)
+
+ time.sleep(1)
+
+ base_util = self.dom.devMgrs[0].devs[0].utilization[0]
+ subscribed = base_util['subscribed']
+ system_load_base = base_util['system_load']
+
+ extra_reservation = 4
+ _value=any.to_any(extra_reservation)
+ _value._t=CORBA.TC_double
+ self.assertRaises(CF.ApplicationFactory.CreateApplicationError, self.dom.createApplication, '/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='COLLOC_SET1',value=_value)]))])
+ app_1=self.dom.createApplication('/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='ID_TEST_SET1',value=_value)]))])
+ time.sleep(wait_amount)
+ self._verifyReservations(extra_reservation, app_1, wait_amount)
+
+ def testAppOverloadTwoSpecificReservation(self):
+ self.assertEquals(os.path.isfile('sdr/dom/mgr/DomainManager'),True)
+ self.assertEquals(os.path.isfile('sdr/dev/mgr/DeviceManager'),True)
+ self._domainBooter, domMgr = self.launchDomainManager()
+ self.assertNotEquals(domMgr,None)
+ self._deviceBooter, devMgr = self.launchDeviceManager("/nodes/DevMgr_sample/DeviceManager.dcd.xml")
+ self.assertNotEquals(devMgr,None)
+ self.comp= self.dom.devMgrs[0].devs[0]
+ cpus = self.dom.devMgrs[0].devs[0].processor_cores
+ cpu_thresh = self.dom.devMgrs[0].devs[0].thresholds.cpu_idle
+ res_per_comp = self.dom.devMgrs[0].devs[0].reserved_capacity_per_component
+ idle_cap_mod = 100.0 * res_per_comp / (cpus*1.0)
+ upper_capacity = cpus - (cpus * (cpu_thresh/100))
+ wait_amount = (self.dom.devMgrs[0].devs[0].threshold_cycle_time / 1000.0) * 4
+ time.sleep(wait_amount)
+ self.assertEquals(self.close(upper_capacity, self.dom.devMgrs[0].devs[0].utilization[0]['maximum']), True)
+
+ time.sleep(1)
+
+ base_util = self.dom.devMgrs[0].devs[0].utilization[0]
+ subscribed = base_util['subscribed']
+ system_load_base = base_util['system_load']
+
+ extra_reservation = 4
+ _value=any.to_any(extra_reservation/2)
+ _value._t=CORBA.TC_double
+ self.assertRaises(CF.ApplicationFactory.CreateApplicationError, self.dom.createApplication, '/waveforms/wav_floor_w/wav_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='COLLOC_SET1',value=any.to_any(_value)),CF.DataType(id='ID_TEST_SET2',value=_value)]))])
+ app_1=self.dom.createApplication('/waveforms/wav_two_floor_w/wav_two_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='ID_TEST_SET1',value=any.to_any(_value)),CF.DataType(id='ID_TEST_SET2',value=_value)]))])
+ time.sleep(wait_amount)
+ self._verifyReservations(extra_reservation, app_1, wait_amount)
+
+ def testAppOverloadOneSpecificReservation(self):
+ self.assertEquals(os.path.isfile('sdr/dom/mgr/DomainManager'),True)
+ self.assertEquals(os.path.isfile('sdr/dev/mgr/DeviceManager'),True)
+ self._domainBooter, domMgr = self.launchDomainManager()
+ self.assertNotEquals(domMgr,None)
+ self._deviceBooter, devMgr = self.launchDeviceManager("/nodes/DevMgr_sample/DeviceManager.dcd.xml")
+ self.assertNotEquals(devMgr,None)
+ self.comp= self.dom.devMgrs[0].devs[0]
+ cpus = self.dom.devMgrs[0].devs[0].processor_cores
+ cpu_thresh = self.dom.devMgrs[0].devs[0].thresholds.cpu_idle
+ res_per_comp = self.dom.devMgrs[0].devs[0].reserved_capacity_per_component
+ idle_cap_mod = 100.0 * res_per_comp / (cpus*1.0)
+ upper_capacity = cpus - (cpus * (cpu_thresh/100))
+ wait_amount = (self.dom.devMgrs[0].devs[0].threshold_cycle_time / 1000.0) * 4
+ time.sleep(wait_amount)
+ self.assertEquals(self.close(upper_capacity, self.dom.devMgrs[0].devs[0].utilization[0]['maximum']), True)
+
+ time.sleep(1)
+
+ base_util = self.dom.devMgrs[0].devs[0].utilization[0]
+ subscribed = base_util['subscribed']
+ system_load_base = base_util['system_load']
+
+ extra_reservation = 4
+ _value=any.to_any(extra_reservation/2)
+ _value._t=CORBA.TC_double
+ app_1=self.dom.createApplication('/waveforms/wav_one_floor_w/wav_one_floor_w.sad.xml','busy_w',[CF.DataType(id='SPECIALIZED_CPU_RESERVATION',value=any.to_any([CF.DataType(id='ID_TEST_SET1',value=any.to_any(_value)),CF.DataType(id='ID_TEST_SET2',value=_value)]))])
+ time.sleep(wait_amount)
+ self._verifyReservations(extra_reservation, app_1, wait_amount)
+
+
+class LoadableDeviceVariableDirectoriesTest(DomainSupport):
+ def setUp(self):
+ super(LoadableDeviceVariableDirectoriesTest,self).setUp()
+ self.launchDomainManager()
+ self._testFiles = []
+
+ dcd_file = 'sdr/dev/nodes/test_VarCache_node/DeviceManager.dcd.xml'
+ with open(dcd_file + '.in', 'r') as fp:
+ original = fp.read()
+
+ cwd = os.getcwd()
+ self.base_dir = cwd + '/LoadableDeviceVariableDirectoriesTest'
+ self.cache_dir = self.base_dir+'/cache'
+ self.cwd_dir = self.base_dir+'/cwd'
+ modified = original.replace('@@@CACHE_DIRECTORY@@@', self.cache_dir)
+ modified = modified.replace('@@@CURRENT_WORKING_DIRECTORY@@@', self.cwd_dir)
+
+ with open(dcd_file, 'w') as fp:
+ fp.write(modified)
+ self._testFiles.append(dcd_file)
+
+ def tearDown(self):
+ super(LoadableDeviceVariableDirectoriesTest, self).tearDown()
+ for file in self._testFiles:
+ os.unlink(file)
+
+ shutil.rmtree(self.base_dir)
+
+ def test_CheckDEPLOYMENTROOT(self):
+ self.assertNotEqual(self.dom, None)
+ nodebooter, devMgr = self.launchDeviceManager("/nodes/test_VarCache_node/DeviceManager.dcd.xml")
+ self.assertNotEqual(devMgr, None)
+ app = self.dom.createApplication('/waveforms/check_cwd_w/check_cwd_w.sad.xml')
+ self.assertNotEqual(app, None)
+ self.assertEquals(app.comps[0].cwd, self.cwd_dir)
+ pid = str(app._get_componentProcessIds()[0].processId)
+ fp=open('/proc/'+pid+'/cmdline','r')
+ cmdline = fp.read()
+ fp.close()
+ _args = cmdline.split('\x00')
+ idx = _args.index('RH::DEPLOYMENT_ROOT')
+ deployment_root=_args[idx+1]
+ self.assertEquals(deployment_root, self.dom.devices[0].cacheDirectory)
+
+ def test_CompConfigCacheCWD(self):
+ self.assertNotEqual(self.dom, None)
+ nodebooter, devMgr = self.launchDeviceManager("/nodes/test_VarCache_node/DeviceManager.dcd.xml")
+ self.assertNotEqual(devMgr, None)
+ app = self.dom.createApplication('/waveforms/check_cwd_w/check_cwd_w.sad.xml')
+ self.assertNotEqual(app, None)
+ self.assertEquals(app.comps[0].cwd, self.cwd_dir)
+ found_dir = False
+ for root, dirs, files in os.walk(self.base_dir):
+ if 'check_cwd.py' in files:
+ if 'cache/components/check_cwd/python' in root:
+ found_dir = True
+ break
+ self.assertTrue(found_dir)
- # TODO Add additional tests here
- #
- # See:
- # ossie.utils.testing.bulkio_helpers,
- # ossie.utils.testing.bluefile_helpers
- # for modules that will assist with testing components with BULKIO ports
-
-def get_nonnuma_affinity_ctx( affinity_ctx ):
- # test should run but affinity will be ignored
- import multiprocessing
- maxcpus=multiprocessing.cpu_count()
- maxnodes=1
- all_cpus='0-'+str(maxcpus-1)
- all_cpus_sans0='0-'+str(maxcpus-1)
- if maxcpus == 2:
- all_cpus_sans0='0-1'
- elif maxcpus == 1 :
- all_cpus='0'
- all_cpus_sans0=''
-
- numa_layout=[ all_cpus ]
- affinity_match={ "all" : all_cpus,
- "sock0": all_cpus,
- "sock1": all_cpus,
- "sock0sans0": all_cpus_sans0,
- "sock1sans0": all_cpus_sans0,
- "5" : all_cpus,
- "8-10" : all_cpus }
-
- affinity_ctx['maxcpus']=maxcpus
- affinity_ctx['maxnodes']=maxnodes
- affinity_ctx['all_cpus']=all_cpus
- affinity_ctx['all_cpus_sans0']=all_cpus_sans0
- affinity_ctx['numa_layout']=numa_layout
- affinity_ctx['affinity_match']=affinity_match
-
-def get_numa_affinity_ctx( affinity_ctx ):
- # test numaclt --show .. look for cpu bind of 0,1 and cpu id atleast 31
- maxnode=0
- maxcpu=0
- lines = [line.rstrip() for line in os.popen('numactl --show')]
- for l in lines:
- if l.startswith('nodebind'):
- maxnode=int(l.split()[-1])
- if l.startswith('physcpubind'):
- maxcpu=int(l.split()[-1])
-
- maxcpus=maxcpu+1
- maxnodes=maxnode+1
- numa_layout=[]
- try:
- for i in range(maxnodes):
- xx = [line.rstrip() for line in open('/sys/devices/system/node/node'+str(i)+'/cpulist')]
- numa_layout.append(xx[0])
- except:
- pass
-
- all_cpus='0-'+str(maxcpus-1)
- all_cpus_sans0='1-'+str(maxcpus-1)
- if maxcpus == 2:
- all_cpus_sans0='1'
- elif maxcpus == 1 :
- all_cpus="0"
- all_cpus_sans0=''
-
- affinity_match = { "all":all_cpus,
- "sock0": all_cpus,
- "sock1": all_cpus,
- "sock0sans0": all_cpus_sans0,
- "sock1sans0": all_cpus_sans0,
- "5" : all_cpus,
- "8-10" : all_cpus }
-
- if len(numa_layout) > 0:
- affinity_match["sock0"]=numa_layout[0]
- aa=numa_layout[0]
- if maxcpus > 2:
- affinity_match["sock0sans0"] = str(int(aa[0])+1)+aa[1:]
-
- if len(numa_layout) > 1:
- affinity_match["sock1"]=numa_layout[1]
- affinity_match["sock1sans0"]=numa_layout[1]
-
- if maxcpus > 5:
- affinity_match["5"]="5"
-
- if maxcpus > 11:
- affinity_match["8-10"]="8-10"
-
- if maxcpus == 2:
- affinity_match["5"] = all_cpus_sans0
- affinity_match["8-10"]= all_cpus_sans0
-
- affinity_ctx['maxcpus']=maxcpus
- affinity_ctx['maxnodes']=maxnodes
- affinity_ctx['all_cpus']=all_cpus
- affinity_ctx['all_cpus_sans0']=all_cpus_sans0
- affinity_ctx['numa_layout']=numa_layout
- affinity_ctx['affinity_match']=affinity_match
-
if __name__ == "__main__":
- # figure out numa layout, test numaclt --show ..
- all_cpus="0"
- maxnode=1
- maxcpu=1
- eface="em1"
- #
- # Figure out ethernet interface to use
- #
- lines = [line.rstrip() for line in os.popen('cat /proc/net/dev')]
- import re
- for l in lines[2:]:
- t1=l.split(':')[0].lstrip()
- if re.match('e.*', t1 ) :
- eface=t1
- break
-
- affinity_test_src['eface']=eface
-
- nonnuma_affinity_ctx={}
- get_nonnuma_affinity_ctx(nonnuma_affinity_ctx)
- numa_affinity_ctx={}
- get_numa_affinity_ctx(numa_affinity_ctx)
-
- # figure out if GPP has numa library dependency
- lines = [ line.rstrip() for line in os.popen('ldd ../cpp/GPP') ]
- numa=False
- for l in lines:
- if "libnuma" in l:
- numa=True
-
- if numa:
- print "NumaSupport ", numa_affinity_ctx
- maxcpus = numa_affinity_ctx['maxcpus']
- maxnodes = numa_affinity_ctx['maxnodes']
- all_cpus = numa_affinity_ctx['all_cpus']
- all_cpus_sans0 = numa_affinity_ctx['all_cpus_sans0']
- numa_layout=numa_affinity_ctx['numa_layout']
- numa_match=numa_affinity_ctx['affinity_match']
- else:
- print "NonNumaSupport ", nonnuma_affinity_ctx
- maxcpus = nonnuma_affinity_ctx['maxcpus']
- maxnodes = nonnuma_affinity_ctx['maxnodes']
- all_cpus = nonnuma_affinity_ctx['all_cpus']
- all_cpus_sans0 = nonnuma_affinity_ctx['all_cpus_sans0']
- numa_layout=nonnuma_affinity_ctx['numa_layout']
- numa_match=nonnuma_affinity_ctx['affinity_match']
-
- if maxnodes < 2 :
- affinity_test_src["sock1"] = "0"
-
- if maxcpus == 2:
- affinity_test_src["8-10"] = all_cpus_sans0
- affinity_test_src["5"] = all_cpus_sans0
- else:
- if maxcpus < 9 or maxcpus < 11 :
- affinity_test_src["8-10"] = all_cpus
- affinity_test_src["5"] = all_cpus
-
- print "numa findings maxnodes:", maxnodes, " maxcpus:", maxcpus, " numa_match:", numa_match, " numa_layout", numa_layout, " map:", affinity_test_src
+ if False:
+ # Debugging support: enable this conditional to dump NUMA topology
+ print "NumaSupport %d nodes %d CPUs" % (len(topology.nodes), len(topology.cpus))
+ for node in topology.nodes:
+ print 'Node', node.node, 'CPUs:', node.cpus
ossie.utils.testing.main("../GPP.spd.xml") # By default tests all implementations
diff --git a/README.md b/README.md
index 0d7132531..cced87ee2 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +3,8 @@
## Description
REDHAWK is a software-defined radio (SDR) framework designed to support the development, deployment, and management of real-time software radio applications. To support the design and development of software applications, REDHAWK provides tools that allow development and testing of software modules called "Components" and composition of Components into "Waveform Applications" that can be seamlessly deployed on a single computer or multiple network-enabled computers.
+REDHAWK 2.1.0 added support for new C++ Components to be created as shared libraries, which allow multiple Components to be deployed into the same process and enable faster, lower-cost I/O. For documentation on this beta feature, refer to docs/shared-address.
+
## Subdirectories
* redhawk - Contains the REDHAWK Core Framework base libraries and system software.
diff --git a/bulkioInterfaces/.gitignore b/bulkioInterfaces/.gitignore
index 9d2191a1b..fb5be4be1 100644
--- a/bulkioInterfaces/.gitignore
+++ b/bulkioInterfaces/.gitignore
@@ -1,4 +1,5 @@
.deps
+.dirstamp
.idlj/
.idljni/
.jars/
@@ -28,7 +29,6 @@ build
/setup.py
/jni/ossie/
/libsrc/java/bin/
-/libsrc/cpp/.dirstamp
/libsrc/java/META-INF/MANIFEST.MF
/libsrc/java/META-INF/MANIFEST.MF.src
/src/
diff --git a/bulkioInterfaces/Makefile.am b/bulkioInterfaces/Makefile.am
index 77f55ae8a..fb7f19efc 100644
--- a/bulkioInterfaces/Makefile.am
+++ b/bulkioInterfaces/Makefile.am
@@ -18,6 +18,8 @@
# along with this program. If not, see http://www.gnu.org/licenses/.
#
+ACLOCAL_AMFLAGS = -I m4 -I ${OSSIEHOME}/share/aclocal/ossie
+
###############################################################################
# CONFIGURE YOUR INTERFACES LIBRARY HERE
#
@@ -53,19 +55,21 @@ bio_dataUshort.idl \
bio_dataLong.idl \
bio_dataLongLong.idl \
bio_dataUlongLong.idl \
+bio_dataBit.idl \
bio_dataSDDS.idl \
bio_dataVITA49.idl
+# IDL files that are marked as "internal" are installed to a separate directory
+# to discourage external use
+IDL_INTERNAL_FILES := internal/bio_dataExt.idl
+
# External IDL namespaces that your IDLs reference, comment this line
# out if your IDL has no external references
IDL_EXTERNS := CF
# In some cases, you may need to define python externs
# f:p Assume Python stub file for file f is in package p.
-PYTHON_EXTERNS := PortTypes:ossie.cf DataType:ossie.cf Port:ossie.cf QueryablePort:ossie.cf bulkioDataTypes:bulkio.bulkioInterfaces
-
-# Relative path to the location of the IDL files
-IDL_SOURCE_PATH := .
+PYTHON_EXTERNS := PortTypes:ossie.cf DataType:ossie.cf Port:ossie.cf QueryablePort:ossie.cf NegotiablePort:ossie.cf bulkioDataTypes:bulkio.bulkioInterfaces
# A Qualifier to append to the version, by default this is a timestamp of the build
BUNDLE_QUALIFIER := v$(shell date +%Y%m%d%H%M%S)
@@ -95,25 +99,73 @@ lib_LTLIBRARIES = libbulkioInterfaces.la
libbulkioInterfaces_la_LDFLAGS = -version-info $(LIBBULKIOINTERFACES_VERSION_INFO)
libbulkioInterfaces_la_LIBADD = $(OSSIE_LIBS)
-# Again, we don't use the auto variable because order is important to us
libbulkioInterfaces_la_SOURCES = \
- src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bulkioDataTypesSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bulkioDataTypesDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bulkioDataTypes.h \
- src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_runtimeStatsSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_runtimeStatsDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_runtimeStats.h \
- src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_updateSRISK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_updateSRIDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_updateSRI.h \
- src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataFloatSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataFloatDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataFloat.h \
- src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataFileSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataFileDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataFile.h \
- src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataXMLSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataXMLDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataXML.h \
- src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataShortSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataShortDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataShort.h \
- src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataDoubleSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataDoubleDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataDouble.h \
- src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataCharSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataCharDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataChar.h \
- src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataOctetSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataOctetDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataOctet.h \
- src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataUlongSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataUlongDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataUlong.h \
- src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataUshortSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataUshortDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataUshort.h \
- src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataLongSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataLongDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataLong.h \
- src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataLongLongSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataLongLongDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataLongLong.h \
- src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataUlongLongSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataUlongLongDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataUlongLong.h \
- src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataSDDSSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataSDDSDynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataSDDS.h \
- src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataVITA49SK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataVITA49DynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/bio_dataVITA49.h
+ src/cpp/ossie/BULKIO/bulkioDataTypesSK.cpp \
+ src/cpp/ossie/BULKIO/bulkioDataTypesDynSK.cpp \
+ src/cpp/ossie/BULKIO/bio_runtimeStatsSK.cpp \
+ src/cpp/ossie/BULKIO/bio_runtimeStatsDynSK.cpp \
+ src/cpp/ossie/BULKIO/bio_updateSRISK.cpp \
+ src/cpp/ossie/BULKIO/bio_updateSRIDynSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataFloatSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataFloatDynSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataFileSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataFileDynSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataXMLSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataXMLDynSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataShortSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataShortDynSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataDoubleSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataDoubleDynSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataCharSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataCharDynSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataOctetSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataOctetDynSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataUlongSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataUlongDynSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataUshortSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataUshortDynSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataLongSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataLongDynSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataLongLongSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataLongLongDynSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataUlongLongSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataUlongLongDynSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataBitSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataBitDynSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataSDDSSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataSDDSDynSK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataVITA49SK.cpp \
+ src/cpp/ossie/BULKIO/bio_dataVITA49DynSK.cpp \
+ src/cpp/ossie/BULKIO/internal/bio_dataExtSK.cpp \
+ src/cpp/ossie/BULKIO/internal/bio_dataExtDynSK.cpp
+
+pkgincludedir = $(includedir)/$(LIBRARY_NAME)/$(IDL_MODULE)
+pkginclude_HEADERS = \
+ src/cpp/ossie/BULKIO/bulkioDataTypes.h \
+ src/cpp/ossie/BULKIO/bio_runtimeStats.h \
+ src/cpp/ossie/BULKIO/bio_updateSRI.h \
+ src/cpp/ossie/BULKIO/bio_dataFloat.h \
+ src/cpp/ossie/BULKIO/bio_dataFile.h \
+ src/cpp/ossie/BULKIO/bio_dataXML.h \
+ src/cpp/ossie/BULKIO/bio_dataShort.h \
+ src/cpp/ossie/BULKIO/bio_dataDouble.h \
+ src/cpp/ossie/BULKIO/bio_dataChar.h \
+ src/cpp/ossie/BULKIO/bio_dataOctet.h \
+ src/cpp/ossie/BULKIO/bio_dataUlong.h \
+ src/cpp/ossie/BULKIO/bio_dataUshort.h \
+ src/cpp/ossie/BULKIO/bio_dataLong.h \
+ src/cpp/ossie/BULKIO/bio_dataLongLong.h \
+ src/cpp/ossie/BULKIO/bio_dataUlongLong.h \
+ src/cpp/ossie/BULKIO/bio_dataBit.h \
+ src/cpp/ossie/BULKIO/bio_dataSDDS.h \
+ src/cpp/ossie/BULKIO/bio_dataVITA49.h
+
+pkginternalincludedir = $(pkgincludedir)/internal
+pkginternalinclude_HEADERS = \
+ src/cpp/ossie/BULKIO/internal/bio_dataExt.h
+
+BUILT_SOURCES = $(libbulkioInterfaces_la_SOURCES) $(pkginclude_HEADERS)
+CLEANFILES = $(BUILT_SOURCES)
###############################################################################
# DO NOT MODIFY ANY LINES BELOW HERE
@@ -124,38 +176,36 @@ LOWER_CASE_IDL_MODULE :=$(shell echo $(IDL_MODULE) | tr A-Z a-z)
idldir = $(datadir)/idl/$(LIBRARY_NAME)/$(IDL_MODULE)
dist_idl_DATA = $(addprefix idl/$(LIBRARY_NAME)/$(IDL_MODULE)/, $(IDL_FILES))
+idlinternaldir = $(idldir)/internal
+dist_idlinternal_DATA = $(addprefix idl/$(LIBRARY_NAME)/$(IDL_MODULE)/, $(IDL_INTERNAL_FILES))
+
all-local: all-python
install-exec-hook: install-python
-clean-local: clean-python clean-java clean-cpp
+clean-local: clean-python clean-java
rm -rf build
+distclean-local:
+ rm -rf src
+
# Always build the current directory first (this is hack-ish, but the
# alternative is to combine the Makefile.am's)
-SUBDIRS = .
-
-if BUILD_BASE_CLASSES
-SUBDIRS += libsrc
-endif
+SUBDIRS = . libsrc
###############################################################################
# C++ (via automake and libtool)
pkgconfigdir = $(libdir)/pkgconfig
dist_pkgconfig_DATA = $(PACKAGE_NAME).pc
-pkgincludedir = $(includedir)/$(LIBRARY_NAME)/$(IDL_MODULE)
-pkginclude_HEADERS = $(filter %.h, $(lib$(LOWER_CASE_IDL_MODULE)Interfaces_la_SOURCES))
-
-AM_CXXFLAGS = -Wall -I src/cpp -g $(OMNIORB_CFLAGS) $(OSSIE_CFLAGS)
-AM_LIBS = $(OSSIE_LIBS)
+bulkio_builddir = src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)
-src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/%DynSK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/%SK.cpp src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)/%.h: idl/$(LIBRARY_NAME)/$(IDL_MODULE)/%.idl
- $(AM_V_at)mkdir -p "src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE)"
- $(AM_V_GEN)$(IDL) -I idl $(OSSIE_CFLAGS) $(OSSIE_IDLFLAGS) -I$(OMNICOS_IDLDIR) -I$(OMNIORB_IDLDIR) -C src/cpp/$(LIBRARY_NAME)/$(IDL_MODULE) -bcxx -Wba -Wbd=DynSK.cpp -Wbh=.h -Wbs=SK.cpp -Wbkeep_inc_path $<
+libbulkioInterfaces_la_CXXFLAGS = -Wall -I src/cpp -g $(OMNIORB_CFLAGS) $(OSSIE_CFLAGS)
+libbulkioInterfaces_la_LIBS = $(OSSIE_LIBS)
-clean-cpp:
- rm -rf src/cpp
+$(bulkio_builddir)/%DynSK.cpp $(bulkio_builddir)/%SK.cpp $(bulkio_builddir)/%.h: idl/ossie/BULKIO/%.idl
+ $(AM_V_at)mkdir -p $(dir $@)
+ $(AM_V_GEN)$(IDL) -I idl $(OSSIE_CFLAGS) $(OSSIE_IDLFLAGS) -I$(OMNICOS_IDLDIR) -I$(OMNIORB_IDLDIR) -C $(dir $@) -bcxx -Wba -Wbd=DynSK.cpp -Wbh=.h -Wbs=SK.cpp -Wbkeep_inc_path $<
###############################################################################
# Python
@@ -169,9 +219,7 @@ PYTHON_MODULE_NAME := $(LOWER_CASE_IDL_MODULE)Interfaces
PYTHON_PACKAGE := $(LOWER_CASE_IDL_MODULE).$(PYTHON_MODULE_NAME)
PYTHON_BASE := $(subst .,/,$(PYTHON_PACKAGE))
PY_SRC_OUT_DIR := $(addprefix src/python/, $(subst .,/, $(PYTHON_PACKAGE)))
-PY_IDL_SRCS := $(addprefix idl/$(LIBRARY_NAME)/$(IDL_MODULE)/, $(IDL_FILES))
-PY_BUILD_OUT_DIR := $(addprefix build/lib/, $(subst .,/, $(PYTHON_PACKAGE)))
-PY_BUILT_SRCS := $(addprefix $(PY_BUILD_OUT_DIR)/, $(subst .idl,_idl.py, $(IDL_FILES)))
+PY_IDL_SRCS := $(addprefix idl/$(LIBRARY_NAME)/$(IDL_MODULE)/, $(IDL_FILES) $(IDL_INTERNAL_FILES))
PY_IDL_EXTERNS := $(addprefix -Wbextern=, $(subst ,, $(PYTHON_EXTERNS)))
PY_IDL_INCLUDES := -I idl
@@ -179,6 +227,7 @@ PY_IDL_INCLUDES := -I idl
$(PY_SRC_OUT_DIR)/__init__.py: $(PY_IDL_SRCS)
$(AM_V_at)mkdir -p $(PY_SRC_OUT_DIR)
$(AM_V_GEN)$(IDL) $(PY_IDL_INCLUDES) $(OSSIE_CFLAGS) $(OSSIE_IDLFLAGS) -I$(OMNICOS_IDLDIR) -I$(OMNIORB_IDLDIR) -C src/python -bpython -Wbpackage=$(PYTHON_PACKAGE) $(PY_IDL_EXTERNS) $^
+ $(AM_V_at)touch $@
# Mimic automake silent rules
OSSIE_V_pysetup = $(ossie__v_pysetup_$(V))
@@ -186,13 +235,9 @@ ossie__v_pysetup_ = $(ossie__v_pysetup__$(AM_DEFAULT_VERBOSITY))
ossie__v_pysetup_0 = --quiet
ossie__v_pysetup__0 = $(ossie__v_pysetup_0)
-$(PY_BUILD_OUT_DIR): $(PY_SRC_OUT_DIR)/__init__.py
- python setup.py $(OSSIE_V_pysetup) build --build-lib build/lib
- $(AM_V_at)touch $(PY_BUILD_OUT_DIR)
-
-all-python: $(PY_BUILD_OUT_DIR)
+all-python: $(PY_SRC_OUT_DIR)/__init__.py
-install-python: $(PY_BUILT_SRCS)
+install-python: $(PY_SRC_OUT_DIR)/__init__.py setup.py
python setup.py install -f --$(PYTHON_INSTALL_SCHEME)=$(DESTDIR)$(prefix)
clean-python:
@@ -240,7 +285,6 @@ build/java/META-INF/MANIFEST.MF: Makefile.am BULKIOInterfaces.filelist
@find $(IDLJ_SRC_DEST) -mindepth 1 -type d | sed 's/src\/java\///' | sed 's/\//./g' | sed 's/^/ /' | sed -e '$$ ! s/$$/,/' >> $@
java_JARFILES = BULKIOInterfaces.jar
-java_DATA = BULKIOInterfaces.src.jar
IDLJFLAGS = -i idl -i $(OSSIE_IDLDIR) -I $(OMNICOS_IDLDIR) -I $(OMNIORB_IDLDIR)
IDLJNIFLAGS = -I idl -I $(OSSIE_IDLDIR) -I $(OMNICOS_IDLDIR) -I $(OMNIORB_IDLDIR) -Wblibname=bulkiojni
@@ -250,27 +294,18 @@ IDLJNI_BUILDDIR = $(IDLJ_BUILDDIR)
# For IDLJ/IDLJNI rules, set VPATH for .idl files so that pattern rules can
# find them.
vpath %.idl idl/ossie/BULKIO
-idlj_IDLSRC = $(IDL_FILES)
+# Only include internal interfaces in pure Java; do not build them for Java-
+# side JNI, because we will not be generating the C++-side
+idlj_IDLSRC = $(IDL_FILES) $(IDL_INTERNAL_FILES)
idljni_IDLSRC = $(IDL_FILES)
BULKIOInterfaces_jar_SOURCE = $(idlj_SOURCE) $(idljni_SOURCE)
BULKIOInterfaces_jar_CLASSPATH = $(OSSIE_CLASSPATH)
BULKIOInterfaces_jar_MANIFEST = build/java/META-INF/MANIFEST.MF
+BULKIOInterfaces_jar_JAVACFLAGS = -g
+BULKIOInterfaces_jar_JARADD = -C $(IDLJ_SRC_DEST) .
-src/java/META-INF/MANIFEST.MF: Makefile
- @mkdir -p src/java/META-INF
- @rm -f $@
- @echo "Bundle-ManifestVersion: 2" >> $@
- @echo "Bundle-Name: $(BUNDLE_NAME) Source" >> $@
- @echo "Bundle-SymbolicName: $(BUNDLE_SYMBOLIC_NAME).src" >> $@
- @echo "Bundle-Version: $(BUNDLE_VERSION).$(BUNDLE_QUALIFIER)" >> $@
- @echo "Bundle-Vendor: $(BUNDLE_VENDOR)" >> $@
- @echo "Eclipse-SourceBundle: $(BUNDLE_SYMBOLIC_NAME);version=$(BUNDLE_VERSION).$(BUNDLE_QUALIFIER)" >> $@
-
-CLEANFILES = BULKIOInterfaces.src.jar src/java/META-INF/MANIFEST.MF $(BULKIOInterfaces_jar_MANIFEST)
-
-BULKIOInterfaces.src.jar: src/java/META-INF/MANIFEST.MF $(BULKIOInterfaces_jar_SOURCE)
- $(RH_V_JAR)$(JAR) cMf $@ -C $(IDLJ_SRC_DEST) .
+CLEANFILES += $(BULKIOInterfaces_jar_MANIFEST)
# JNI library must be built after the current directory (see SUBDIRS above)
SUBDIRS += jni
diff --git a/bulkioInterfaces/build.sh b/bulkioInterfaces/build.sh
index a3f0a89d1..bda27c026 100755
--- a/bulkioInterfaces/build.sh
+++ b/bulkioInterfaces/build.sh
@@ -25,9 +25,9 @@ elif [ "$1" = "rpm" ]; then
# A very simplistic RPM build scenario
mydir=`dirname $0`
tmpdir=`mktemp -d`
- cp -r ${mydir} ${tmpdir}/bulkioInterfaces-2.0.9
- tar czf ${tmpdir}/bulkioInterfaces-2.0.9.tar.gz --exclude=".git" -C ${tmpdir} bulkioInterfaces-2.0.9
- rpmbuild -ta ${tmpdir}/bulkioInterfaces-2.0.9.tar.gz
+ cp -r ${mydir} ${tmpdir}/bulkioInterfaces-2.2.1
+ tar czf ${tmpdir}/bulkioInterfaces-2.2.1.tar.gz --exclude=".git" -C ${tmpdir} bulkioInterfaces-2.2.1
+ rpmbuild -ta ${tmpdir}/bulkioInterfaces-2.2.1.tar.gz
rm -rf $tmpdir
else
# Checks if build is newer than makefile (based on modification time)
diff --git a/bulkioInterfaces/bulkio-1.0.0 b/bulkioInterfaces/bulkio-1.0.0
deleted file mode 120000
index e09e0bba5..000000000
--- a/bulkioInterfaces/bulkio-1.0.0
+++ /dev/null
@@ -1 +0,0 @@
-libsrc
\ No newline at end of file
diff --git a/bulkioInterfaces/bulkioInterfaces.spec b/bulkioInterfaces/bulkioInterfaces.spec
index e78a30d74..ae2b4af04 100644
--- a/bulkioInterfaces/bulkioInterfaces.spec
+++ b/bulkioInterfaces/bulkioInterfaces.spec
@@ -28,8 +28,8 @@ Prefix: %{_prefix}
%bcond_without java
Name: bulkioInterfaces
-Version: 2.0.9
-Release: 1%{?dist}
+Version: 2.2.1
+Release: 2%{?dist}
Summary: The bulkio library for REDHAWK
Group: Applications/Engineering
@@ -38,10 +38,9 @@ URL: http://redhawksdr.org/
Source: %{name}-%{version}.tar.gz
Vendor: REDHAWK
-BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
-
-Requires: redhawk >= 2.0
-BuildRequires: redhawk-devel >= 2.0
+Requires: redhawk = %{version}
+BuildRequires: redhawk-devel = %{version}
+BuildRequires: cppunit-devel
%description
Libraries and interface definitions for bulkio interfaces.
@@ -83,9 +82,7 @@ rm -rf --preserve-root $RPM_BUILD_ROOT
%endif
%if %{with java}
%{_prefix}/lib/BULKIOInterfaces.jar
-%{_prefix}/lib/BULKIOInterfaces.src.jar
%{_prefix}/lib/bulkio.jar
-%{_prefix}/lib/bulkio.src.jar
%{_prefix}/%{_lib}/libbulkiojni.*
%endif
@@ -98,6 +95,12 @@ rm -rf --preserve-root $RPM_BUILD_ROOT
%changelog
+* Wed Jun 28 2017 Ryan Bauman - 2.1.2-1
+- Bump for 2.1.2-rc2
+
+* Wed Jun 28 2017 Ryan Bauman - 2.1.1-2
+- Bump for 2.1.1-rc2
+
* Fri Mar 21 2014 1.10.0-1
- Improve OS version detection for RHEL/CentOS/Fedora
diff --git a/bulkioInterfaces/configure.ac b/bulkioInterfaces/configure.ac
index 3c971e3d1..c4fec2fe3 100644
--- a/bulkioInterfaces/configure.ac
+++ b/bulkioInterfaces/configure.ac
@@ -18,11 +18,11 @@
# along with this program. If not, see http://www.gnu.org/licenses/.
#
-AC_INIT(bulkioInterfaces, 2.0.9)
+AC_INIT(bulkioInterfaces, 2.2.1)
+AC_CONFIG_MACRO_DIR([m4])
AC_SUBST([LIBBULKIOINTERFACES_VERSION_INFO], [3:0:1])
-#AM_INIT_AUTOMAKE([nostdinc subdir-objects])
-AM_INIT_AUTOMAKE([nostdinc])
+AM_INIT_AUTOMAKE([foreign nostdinc subdir-objects])
AC_PROG_CC
AC_PROG_CXX
AC_PROG_INSTALL
@@ -44,29 +44,22 @@ fi
PKG_CHECK_MODULES([OMNIORB], [omniORB4 >= 4.1.0])
RH_PKG_IDLDIR([OMNIORB], [omniORB4])
-PKG_CHECK_MODULES([OSSIE], [ossie >= 2.0.9])
+PKG_CHECK_MODULES([OSSIE], [ossie >= 2.2.1])
RH_PKG_IDLDIR([OSSIE], [ossie])
PKG_CHECK_MODULES([OMNICOS], [omniCOS4 >= 4.0.0])
RH_PKG_IDLDIR([OMNICOS], [omniCOS4])
-# Optionally include BULKIO base class libraries
-AC_ARG_ENABLE([base-classes], AS_HELP_STRING([--disable-base-classes], [Disable BULKIO base class libraries]))
-AM_CONDITIONAL([BUILD_BASE_CLASSES], [test "$enable_base_classes" != "no"])
+AC_SUBST([BULKIO_SO_VERSION], [0:0:0])
+AC_SUBST([BULKIO_API_VERSION], [2.2])
-if test "$enable_base_classes" != "no"; then
- AC_SUBST([BULKIO_SO_VERSION], [0:0:0])
- AC_SUBST([BULKIO_API_VERSION], [2.0])
+AX_BOOST_BASE([1.41])
+AX_BOOST_THREAD
+AX_BOOST_SYSTEM
+OSSIE_ENABLE_LOG4CXX
+CHECK_VECTOR_IMPL
- AX_BOOST_BASE([1.41])
- AX_BOOST_THREAD
- AX_BOOST_SYSTEM
- OSSIE_ENABLE_LOG4CXX
- CHECK_VECTOR_IMPL
-
- AC_SUBST(BULKIO_INF_INCLUDES, "-I../src/cpp -I../src/cpp/ossie")
- AC_SUBST(BULKIO_INF_CFLAGS, )
- AC_SUBST(BULKIO_INF_LIBS, )
-fi
+AC_SUBST(BULKIOINTERFACES_CFLAGS, "-I \$(top_srcdir)/src/cpp -I \$(top_srcdir)/src/cpp/ossie")
+AC_SUBST(BULKIOINTERFACES_LIBS, "-L\$(top_srcdir) -lbulkioInterfaces")
# Optionally include java support
AC_ARG_ENABLE([java], AS_HELP_STRING([--disable-java], [Disable framework java support]))
@@ -75,7 +68,7 @@ HAVE_JAVASUPPORT=no
if test "x$enable_java" != "xno"; then
# configure was run with java enabled
- java_source_version=1.6
+ java_source_version=1.8
RH_JAVA_HOME
RH_PROG_JAVAC([$java_source_version])
@@ -136,12 +129,49 @@ AC_MSG_RESULT($HAVE_JAVASUPPORT)
AM_CONDITIONAL(HAVE_JAVASUPPORT, test $HAVE_JAVASUPPORT = yes)
# End optional java support
+# C++ unit testing support. May want to conditionally enable/disable this.
+AM_PATH_CPPUNIT(1.12.1)
+AS_IF([test "x$HAVE_JAVASUPPORT" == "xyes"], [
+ dnl Use RPM location hard-coded for now
+ AC_SUBST([JUNIT_CLASSPATH], "/usr/share/java/junit4.jar")
+])
+
+# For C++ test components, provide BULKIO_CFLAGS and BULKIO_LIBS so they build
+# without modifying their Makefile.am to change the paths. In order to pick up
+# the uninstalled headers, we need to provide the path to the BULKIO headers,
+# the top-level include directory ("bulkio/bulkio.h") and the bulkio
+# directory inside of include ("bulkio.h").
+bulkio_includedir="\$(top_srcdir)/libsrc/cpp/include"
+AC_SUBST(BULKIO_CFLAGS, "-I ${bulkio_includedir} -I ${bulkio_includedir}/bulkio ${BULKIOINTERFACES_CFLAGS}")
+AC_SUBST(BULKIO_LIBS, "-L\$(top_srcdir)/libsrc -lbulkio-${BULKIO_API_VERSION} ${BULKIOINTERFACES_LIBS}")
+
AC_CONFIG_FILES([bulkioInterfaces.pc setup.py Makefile jni/Makefile])
-if test "$enable_base_classes" != "no"; then
- if test "$HAVE_JAVASUPPORT = yes"; then
- AC_CONFIG_FILES([libsrc/java/META-INF/MANIFEST.MF libsrc/java/META-INF/MANIFEST.MF.src])
- fi
- AC_CONFIG_FILES([libsrc/Makefile libsrc/bulkio.pc])
+if test "$HAVE_JAVASUPPORT = yes"; then
+ AC_CONFIG_FILES([libsrc/java/META-INF/MANIFEST.MF])
fi
+AC_SUBST(PROJECTDEPS_CFLAGS, "\$(OSSIE_CFLAGS)")
+AC_SUBST(PROJECTDEPS_LIBS, "\$(OSSIE_LIBS)")
+AC_SUBST(INTERFACEDEPS_CFLAGS, "\$(BULKIO_CFLAGS)")
+AC_SUBST(INTERFACEDEPS_LIBS, "\$(BULKIO_LIBS)")
+AC_SUBST(REDHAWK_CLASSPATH, "\$(OSSIE_CLASSPATH)")
+AC_SUBST(BULKIO_CLASSPATH, "\$(top_srcdir)/libsrc/bulkio.jar:\$(top_srcdir)/BULKIOInterfaces.jar")
+AC_CONFIG_FILES([libsrc/Makefile \
+ libsrc/bulkio.pc \
+ libsrc/testing/Makefile \
+ libsrc/testing/tests/cpp/Makefile \
+ libsrc/testing/tests/java/Makefile \
+ libsrc/testing/components/CPP_Ports/cpp/Makefile \
+ libsrc/testing/components/Java_Ports/java/Makefile \
+ libsrc/testing/components/Oversized_framedata/cpp/Makefile \
+ libsrc/testing/components/src/cpp/Makefile \
+ libsrc/testing/components/snk_slow/cpp/Makefile \
+ libsrc/testing/components/Oversized_framedata/java/Makefile \
+ libsrc/testing/components/TestLargePush/cpp/Makefile \
+ libsrc/testing/components/TestLargePush/java/Makefile \
+ libsrc/testing/components/multiout_attachable/cpp/Makefile \
+ libsrc/testing/components/multiout_attachable/java/Makefile \
+ libsrc/testing/components/sri_changed_cpp/cpp/Makefile \
+ libsrc/testing/devices/dev_snk/java/Makefile \
+ libsrc/testing/devices/dev_src/java/Makefile])
AC_OUTPUT
diff --git a/bulkioInterfaces/idl/ossie/BULKIO/bio_dataBit.idl b/bulkioInterfaces/idl/ossie/BULKIO/bio_dataBit.idl
new file mode 100644
index 000000000..ddbe7f901
--- /dev/null
+++ b/bulkioInterfaces/idl/ossie/BULKIO/bio_dataBit.idl
@@ -0,0 +1,39 @@
+/*
+ * This file is protected by Copyright. Please refer to the COPYRIGHT file
+ * distributed with this source distribution.
+ *
+ * This file is part of REDHAWK core.
+ *
+ * REDHAWK core is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+#ifndef _DATABIT_IDL_
+#define _DATABIT_IDL_
+
+#include "ossie/BULKIO/bio_runtimeStats.idl"
+#include "ossie/BULKIO/bio_updateSRI.idl"
+
+module BULKIO {
+
+ struct BitSequence {
+ CF::OctetSequence data;
+ unsigned long bits;
+ };
+
+ interface dataBit : ProvidesPortStatisticsProvider, updateSRI {
+ void pushPacket(in BitSequence data, in PrecisionUTCTime T, in boolean EOS, in string streamID);
+ };
+};
+
+#endif
diff --git a/bulkioInterfaces/idl/ossie/BULKIO/bio_dataLong.idl b/bulkioInterfaces/idl/ossie/BULKIO/bio_dataLong.idl
index a5d663590..352932b68 100644
--- a/bulkioInterfaces/idl/ossie/BULKIO/bio_dataLong.idl
+++ b/bulkioInterfaces/idl/ossie/BULKIO/bio_dataLong.idl
@@ -18,8 +18,8 @@
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
-#ifndef _DATASHORT_IDL_
-#define _DATASHORT_IDL_
+#ifndef _DATALONG_IDL_
+#define _DATALONG_IDL_
#include "ossie/BULKIO/bio_runtimeStats.idl"
#include "ossie/BULKIO/bio_updateSRI.idl"
diff --git a/bulkioInterfaces/idl/ossie/BULKIO/bio_dataLongLong.idl b/bulkioInterfaces/idl/ossie/BULKIO/bio_dataLongLong.idl
index 585676101..f340da416 100644
--- a/bulkioInterfaces/idl/ossie/BULKIO/bio_dataLongLong.idl
+++ b/bulkioInterfaces/idl/ossie/BULKIO/bio_dataLongLong.idl
@@ -18,8 +18,8 @@
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
-#ifndef _DATASHORT_IDL_
-#define _DATASHORT_IDL_
+#ifndef _DATALONGLONG_IDL_
+#define _DATALONGLONG_IDL_
#include "ossie/BULKIO/bio_runtimeStats.idl"
#include "ossie/BULKIO/bio_updateSRI.idl"
diff --git a/bulkioInterfaces/idl/ossie/BULKIO/bio_dataUlongLong.idl b/bulkioInterfaces/idl/ossie/BULKIO/bio_dataUlongLong.idl
index f45444180..12fb81d14 100644
--- a/bulkioInterfaces/idl/ossie/BULKIO/bio_dataUlongLong.idl
+++ b/bulkioInterfaces/idl/ossie/BULKIO/bio_dataUlongLong.idl
@@ -18,8 +18,8 @@
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
-#ifndef _DATASHORT_IDL_
-#define _DATASHORT_IDL_
+#ifndef _DATAULONGLONG_IDL_
+#define _DATAULONGLONG_IDL_
#include "ossie/BULKIO/bio_runtimeStats.idl"
#include "ossie/BULKIO/bio_updateSRI.idl"
diff --git a/bulkioInterfaces/idl/ossie/BULKIO/bio_dataUshort.idl b/bulkioInterfaces/idl/ossie/BULKIO/bio_dataUshort.idl
index a41cea5f3..2ea115b5e 100644
--- a/bulkioInterfaces/idl/ossie/BULKIO/bio_dataUshort.idl
+++ b/bulkioInterfaces/idl/ossie/BULKIO/bio_dataUshort.idl
@@ -18,8 +18,8 @@
* along with this program. If not, see http://www.gnu.org/licenses/.
*/
-#ifndef _DATASHORT_IDL_
-#define _DATASHORT_IDL_
+#ifndef _DATAUSHORT_IDL_
+#define _DATAUSHORT_IDL_
#include "ossie/BULKIO/bio_runtimeStats.idl"
#include "ossie/BULKIO/bio_updateSRI.idl"
diff --git a/bulkioInterfaces/idl/ossie/BULKIO/internal/bio_dataExt.idl b/bulkioInterfaces/idl/ossie/BULKIO/internal/bio_dataExt.idl
new file mode 100644
index 000000000..f1d9f2d59
--- /dev/null
+++ b/bulkioInterfaces/idl/ossie/BULKIO/internal/bio_dataExt.idl
@@ -0,0 +1,88 @@
+/*
+ * This file is protected by Copyright. Please refer to the COPYRIGHT file
+ * distributed with this source distribution.
+ *
+ * This file is part of REDHAWK core.
+ *
+ * REDHAWK core is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * REDHAWK core is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+#ifndef _DATAEXT_IDL_
+#define _DATAEXT_IDL_
+
+#include "ossie/CF/NegotiablePort.idl"
+#include "ossie/BULKIO/bio_dataChar.idl"
+#include "ossie/BULKIO/bio_dataDouble.idl"
+#include "ossie/BULKIO/bio_dataFloat.idl"
+#include "ossie/BULKIO/bio_dataLong.idl"
+#include "ossie/BULKIO/bio_dataLongLong.idl"
+#include "ossie/BULKIO/bio_dataOctet.idl"
+#include "ossie/BULKIO/bio_dataShort.idl"
+#include "ossie/BULKIO/bio_dataUlong.idl"
+#include "ossie/BULKIO/bio_dataUlongLong.idl"
+#include "ossie/BULKIO/bio_dataUshort.idl"
+#include "ossie/BULKIO/bio_dataBit.idl"
+#include "ossie/BULKIO/bio_dataXML.idl"
+#include "ossie/BULKIO/bio_dataFile.idl"
+
+module BULKIO {
+
+ module internal {
+
+ interface UsesPortStatisticsProviderExt : UsesPortStatisticsProvider, ExtendedCF::NegotiableUsesPort {
+ };
+
+ interface dataCharExt : dataChar, ExtendedCF::NegotiableProvidesPort {
+ };
+
+ interface dataDoubleExt : dataDouble, ExtendedCF::NegotiableProvidesPort {
+ };
+
+ interface dataFloatExt : dataFloat, ExtendedCF::NegotiableProvidesPort {
+ };
+
+ interface dataLongExt : dataLong, ExtendedCF::NegotiableProvidesPort {
+ };
+
+ interface dataLongLongExt : dataLongLong, ExtendedCF::NegotiableProvidesPort {
+ };
+
+ interface dataOctetExt : dataOctet, ExtendedCF::NegotiableProvidesPort {
+ };
+
+ interface dataShortExt : dataShort, ExtendedCF::NegotiableProvidesPort {
+ };
+
+ interface dataUlongExt : dataUlong, ExtendedCF::NegotiableProvidesPort {
+ };
+
+ interface dataUlongLongExt : dataUlongLong, ExtendedCF::NegotiableProvidesPort {
+ };
+
+ interface dataUshortExt : dataUshort, ExtendedCF::NegotiableProvidesPort {
+ };
+
+ interface dataBitExt : dataBit, ExtendedCF::NegotiableProvidesPort {
+ };
+
+ interface dataXMLExt : dataXML, ExtendedCF::NegotiableProvidesPort {
+ };
+
+ interface dataFileExt : dataFile, ExtendedCF::NegotiableProvidesPort {
+ };
+
+ };
+};
+
+#endif
diff --git a/bulkioInterfaces/jni/Makefile.am b/bulkioInterfaces/jni/Makefile.am
index 480381d84..7d9a537f7 100644
--- a/bulkioInterfaces/jni/Makefile.am
+++ b/bulkioInterfaces/jni/Makefile.am
@@ -43,6 +43,7 @@ nodist_libbulkiojni_la_SOURCES = \
ossie/BULKIO/jni_bio_dataXML.cpp \
ossie/BULKIO/jni_bio_dataShort.cpp \
ossie/BULKIO/jni_bio_dataDouble.cpp \
+ ossie/BULKIO/jni_bio_dataBit.cpp \
ossie/BULKIO/jni_bio_dataChar.cpp \
ossie/BULKIO/jni_bio_dataOctet.cpp \
ossie/BULKIO/jni_bio_dataUlong.cpp \
@@ -61,6 +62,7 @@ nobase_nodist_include_HEADERS = \
ossie/BULKIO/jni_bio_dataXML.h \
ossie/BULKIO/jni_bio_dataShort.h \
ossie/BULKIO/jni_bio_dataDouble.h \
+ ossie/BULKIO/jni_bio_dataBit.h \
ossie/BULKIO/jni_bio_dataChar.h \
ossie/BULKIO/jni_bio_dataOctet.h \
ossie/BULKIO/jni_bio_dataUlong.h \
diff --git a/bulkioInterfaces/libsrc/.gitignore b/bulkioInterfaces/libsrc/.gitignore
index a90129f13..4b652d27c 100644
--- a/bulkioInterfaces/libsrc/.gitignore
+++ b/bulkioInterfaces/libsrc/.gitignore
@@ -1 +1,2 @@
.jars
+python/bulkio.egg-info/
diff --git a/bulkioInterfaces/libsrc/Makefile.am b/bulkioInterfaces/libsrc/Makefile.am
index d0c0876f9..87de784cd 100644
--- a/bulkioInterfaces/libsrc/Makefile.am
+++ b/bulkioInterfaces/libsrc/Makefile.am
@@ -40,28 +40,46 @@ libbulkio_@BULKIO_API_VERSION@_la_SOURCES = \
cpp/bulkio_in_stream.cpp \
cpp/bulkio_out_port.cpp \
cpp/bulkio_out_stream.cpp \
- cpp/bulkio_attachable_port.cpp \
+ cpp/bulkio_attachable_port.cpp \
cpp/bulkio_sri_helpers.cpp \
+ cpp/bulkio_stream.cpp \
cpp/bulkio_time_helpers.cpp \
cpp/bulkio_time_operators.cpp \
cpp/bulkio_datablock.cpp \
- cpp/bulkio_p.h
+ cpp/bulkio_p.h \
+ cpp/BulkioTransport.cpp \
+ cpp/CorbaTransport.h \
+ cpp/CorbaTransport.cpp \
+ cpp/LocalTransport.h \
+ cpp/LocalTransport.cpp \
+ cpp/shm/FifoIPC.h \
+ cpp/shm/FifoIPC.cpp \
+ cpp/shm/MessageBuffer.h \
+ cpp/shm/ShmInputTransport.h \
+ cpp/shm/ShmInputTransport.cpp \
+ cpp/shm/ShmOutputTransport.h \
+ cpp/shm/ShmOutputTransport.cpp \
+ cpp/shm/ShmTransportFactory.cpp
## Define the list of public header files and their install location.
library_includedir = $(includedir)/bulkio
-library_include_HEADERS = cpp/bulkio.h \
- cpp/BULKIO_Interfaces.h \
- cpp/bulkio_base.h \
- cpp/bulkio_callbacks.h \
- cpp/bulkio_traits.h \
- cpp/bulkio_in_port.h \
- cpp/bulkio_in_stream.h \
- cpp/bulkio_out_port.h \
- cpp/bulkio_out_stream.h \
- cpp/bulkio_attachable_base.h \
- cpp/bulkio_time_operators.h \
- cpp/bulkio_datablock.h \
- cpp/bulkio_compat.h
+library_include_HEADERS = cpp/include/bulkio/bulkio.h \
+ cpp/include/bulkio/BULKIO_Interfaces.h \
+ cpp/include/bulkio/BulkioTransport.h \
+ cpp/include/bulkio/bulkio_base.h \
+ cpp/include/bulkio/bulkio_callbacks.h \
+ cpp/include/bulkio/bulkio_traits.h \
+ cpp/include/bulkio/bulkio_in_port.h \
+ cpp/include/bulkio/bulkio_in_stream.h \
+ cpp/include/bulkio/bulkio_out_port.h \
+ cpp/include/bulkio/bulkio_out_stream.h \
+ cpp/include/bulkio/bulkio_attachable_base.h \
+ cpp/include/bulkio/bulkio_stream.h \
+ cpp/include/bulkio/bulkio_time_operators.h \
+ cpp/include/bulkio/bulkio_datablock.h \
+ cpp/include/bulkio/bulkio_datatransfer.h \
+ cpp/include/bulkio/bulkio_typetraits.h \
+ cpp/include/bulkio/bulkio_compat.h
## The generated configuration header is installed in its own subdirectory of
## $(libdir). The reason for this is that the configuration information put
@@ -76,7 +94,9 @@ library_include_HEADERS = cpp/bulkio.h \
## shipped with the source tarball.
#bulkio_libincludedir = $(libdir)/bulkio-$(BULKIO_API_VERSION)/include
-libbulkio_@BULKIO_API_VERSION@_la_CXXFLAGS = -Wall -I./cpp -DLOGGING $(BULKIO_INF_INCLUDES) $(BOOST_CPPFLAGS) $(OMNIORB_CFLAGS) $(OSSIE_CFLAGS)
+libbulkio_@BULKIO_API_VERSION@_la_CXXFLAGS = -Wall -I $(srcdir)/cpp -I $(srcdir)/cpp/include/bulkio -DLOGGING $(BULKIOINTERFACES_CFLAGS) $(BOOST_CPPFLAGS) $(OMNIORB_CFLAGS) $(OSSIE_CFLAGS)
+
+libbulkio_@BULKIO_API_VERSION@_la_LIBADD = $(top_builddir)/libbulkioInterfaces.la
###############################################################################
# Python
@@ -87,14 +107,9 @@ ossie__v_pysetup_ = $(ossie__v_pysetup__$(AM_DEFAULT_VERBOSITY))
ossie__v_pysetup_0 = --quiet
ossie__v_pysetup__0 = $(ossie__v_pysetup_0)
-all-python: build-python
-
-build-python:
- python setup.py $(OSSIE_V_pysetup) build
-
+rootflag = $(if $(DESTDIR),--root=$(DESTDIR))
install-python:
- test -n "$(DESTDIR)" && buildroot="--root=$(DESTDIR)"; \
- python setup.py install $$buildroot --prefix=$(prefix) --install-purelib=$(prefix)/lib/python --force
+ $(PYTHON) setup.py install -f $(rootflag) --home=$(prefix) --old-and-unmanageable
clean-python:
python setup.py clean --all
@@ -110,62 +125,34 @@ JAVA_DIR := java
JAVA_SRCDIR := $(JAVA_DIR)/src
JAVA_SRCS := Const.java \
+DataHelper.java \
DataTransfer.java \
-InCharPort.java \
-InDoublePort.java \
+ChunkingOutPort.java \
+InBitPort.java \
InFilePort.java \
-InFloatPort.java \
-InInt16Port.java \
-InInt32Port.java \
-InInt64Port.java \
-InInt8Port.java \
-InLongLongPort.java \
-InLongPort.java \
-InOctetPort.java \
InSDDSPort.java \
InVITA49Port.java \
-InShortPort.java \
-InUInt16Port.java \
-InUInt32Port.java \
-InUInt64Port.java \
-InUInt8Port.java \
-InULongLongPort.java \
-InULongPort.java \
-InUShortPort.java \
InXMLPort.java \
+InDataPort.java \
+InPortImpl.java \
linkStatistics.java \
-OutCharPort.java \
+OutBitPort.java \
OutDataPort.java \
-OutDoublePort.java \
OutFilePort.java \
-OutFloatPort.java \
-OutInt16Port.java \
-OutInt32Port.java \
-OutInt64Port.java \
-OutInt8Port.java \
-OutLongLongPort.java \
-OutLongPort.java \
-OutOctetPort.java \
OutPortBase.java \
OutSDDSPort.java \
OutVITA49Port.java \
-OutShortPort.java \
-OutUInt16Port.java \
-OutUInt32Port.java \
-OutUInt64Port.java \
-OutUInt8Port.java \
-OutULongLongPort.java \
-OutULongPort.java \
-OutUShortPort.java \
OutXMLPort.java \
connection_descriptor_struct.java \
SriMapStruct.java \
-queueSemaphore.java \
SizeOf.java \
SriListener.java \
ConnectionEventListener.java \
sriState.java \
utils.java \
+BitDataHelper.java \
+FileDataHelper.java \
+XMLDataHelper.java \
sdds/SDDSStream.java \
sdds/SDDSStreamAttachment.java \
sdds/SDDSStreamContainer.java \
@@ -179,19 +166,83 @@ time/Comparator.java \
time/DefaultComparator.java \
time/utils.java
+# Numeric ports are generated via sed for ease of maintenance
+$(JAVA_SRCDIR)/bulkio/In%Port.java : $(JAVA_DIR)/sed/%.sed $(JAVA_SRCDIR)/bulkio/InPort.java.template
+ $(AM_V_GEN)sed -f $< $(JAVA_SRCDIR)/bulkio/InPort.java.template > $@
+
+$(JAVA_SRCDIR)/bulkio/%DataHelper.java : $(JAVA_DIR)/sed/%.sed $(JAVA_SRCDIR)/bulkio/NumericDataHelper.java.template
+ $(AM_V_GEN)sed -f $< $(JAVA_SRCDIR)/bulkio/NumericDataHelper.java.template > $@
+
+$(JAVA_SRCDIR)/bulkio/Out%Port.java : $(JAVA_DIR)/sed/%.sed $(JAVA_SRCDIR)/bulkio/OutPort.java.template
+ $(AM_V_GEN)sed -f $< $(JAVA_SRCDIR)/bulkio/OutPort.java.template > $@
+
+JAVA_BUILT_SOURCE = $(JAVA_SRCDIR)/bulkio/InDoublePort.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InFloatPort.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InShortPort.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InLongPort.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InLongLongPort.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InCharPort.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InUShortPort.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InULongPort.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InULongLongPort.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InOctetPort.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/DoubleDataHelper.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/FloatDataHelper.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/ShortDataHelper.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/LongDataHelper.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/LongLongDataHelper.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/CharDataHelper.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/UShortDataHelper.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/ULongDataHelper.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/ULongLongDataHelper.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OctetDataHelper.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutDoublePort.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutFloatPort.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutShortPort.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutLongPort.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutLongLongPort.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutCharPort.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutUShortPort.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutULongPort.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutULongLongPort.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutOctetPort.java
+
+# Deprecated port alias classes (e.g., InInt16Port aliases InShortPort)
+$(JAVA_SRCDIR)/bulkio/In%Port.java : $(JAVA_DIR)/sed/deprecated/%.sed $(JAVA_SRCDIR)/bulkio/DeprecatedInPort.java.template
+ $(AM_V_GEN)sed -f $< $(JAVA_SRCDIR)/bulkio/DeprecatedInPort.java.template > $@
+
+$(JAVA_SRCDIR)/bulkio/Out%Port.java : $(JAVA_DIR)/sed/deprecated/%.sed $(JAVA_SRCDIR)/bulkio/DeprecatedOutPort.java.template
+ $(AM_V_GEN)sed -f $< $(JAVA_SRCDIR)/bulkio/DeprecatedOutPort.java.template > $@
+
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InInt16Port.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InInt32Port.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InInt64Port.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InInt8Port.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InUInt16Port.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InUInt32Port.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InUInt64Port.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/InUInt8Port.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutInt16Port.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutInt32Port.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutInt64Port.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutInt8Port.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutUInt16Port.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutUInt32Port.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutUInt64Port.java
+JAVA_BUILT_SOURCE += $(JAVA_SRCDIR)/bulkio/OutUInt8Port.java
+
java_JARFILES = bulkio.jar
-java_DATA = bulkio.src.jar
-bulkio_jar_SOURCE = $(addprefix $(JAVA_SRCDIR)/bulkio/,$(JAVA_SRCS))
+bulkio_jar_SOURCE = $(addprefix $(JAVA_SRCDIR)/bulkio/,$(JAVA_SRCS)) $(JAVA_BUILT_SOURCE)
bulkio_jar_CLASSPATH = $(OSSIE_CLASSPATH):$(top_builddir)/BULKIOInterfaces.jar
bulkio_jar_MANIFEST = $(JAVA_DIR)/META-INF/MANIFEST.MF
+bulkio_jar_JARADD = -C $(JAVA_SRCDIR) bulkio
+bulkio_jar_JAVACFLAGS = -g -Xlint
bulkio.jar: $(top_builddir)/BULKIOInterfaces.jar
-bulkio.src.jar: $(JAVA_DIR)/META-INF/MANIFEST.MF.src $(bulkio_jar_SOURCE)
- $(RH_V_JAR)$(JAR) cmf $< $@ -C $(JAVA_SRCDIR) .
-
-CLEANFILES = bulkio.src.jar
+BUILT_SOURCES = $(JAVA_BUILT_SOURCE)
+CLEANFILES = $(BUILT_SOURCES)
endif
@@ -199,9 +250,7 @@ endif
# General
#
-.PHONY: all-local all-python build-python install-python clean-python reallyclean
-
-all-local: all-python
+.PHONY: install-python clean-python reallyclean
install-exec-hook: install-python
diff --git a/bulkioInterfaces/libsrc/cpp/BulkioTransport.cpp b/bulkioInterfaces/libsrc/cpp/BulkioTransport.cpp
new file mode 100644
index 000000000..2aada3e86
--- /dev/null
+++ b/bulkioInterfaces/libsrc/cpp/BulkioTransport.cpp
@@ -0,0 +1,232 @@
+/*
+ * This file is protected by Copyright. Please refer to the COPYRIGHT file
+ * distributed with this source distribution.
+ *
+ * This file is part of REDHAWK bulkioInterfaces.
+ *
+ * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+#include
+#include "bulkio_typetraits.h"
+#include "bulkio_in_port.h"
+#include "bulkio_out_port.h"
+#include "bulkio_p.h"
+
+namespace bulkio {
+
+ template
+ OutputTransport::OutputTransport(OutPortType* port, PtrType objref) :
+ redhawk::UsesTransport(port),
+ _port(port),
+ _objref(PortType::_duplicate(objref)),
+ _stats(port->getName())
+ {
+ // Manually set the bit size because the statistics ctor only takes a
+ // byte count
+ _stats.setBitSize(NativeTraits::bits);
+ }
+
+ template
+ OutputTransport::~OutputTransport()
+ {
+ }
+
+ template
+ void OutputTransport::disconnect()
+ {
+ // Send an end-of-stream for all active streams
+ for (VersionMap::iterator stream = _sriVersions.begin(); stream != _sriVersions.end(); ++stream) {
+ try {
+ this->_pushPacket(BufferType(), bulkio::time::utils::notSet(), true, stream->first);
+ } catch (redhawk::TransportTimeoutError& e) {
+ // Ignore the timeout. The destination is in a bad state
+ }
+ }
+ _sriVersions.clear();
+ }
+
+ template
+ void OutputTransport::pushSRI(const std::string& streamID, const BULKIO::StreamSRI& sri, int version)
+ {
+ VersionMap::iterator existing = _sriVersions.find(streamID);
+ if (existing != _sriVersions.end()) {
+ if (version == existing->second) {
+ return;
+ }
+ existing->second = version;
+ } else {
+ _sriVersions[streamID] = version;
+ }
+ this->_pushSRI(sri);
+ }
+
+ template
+ void OutputTransport::pushPacket(const BufferType& data,
+ const BULKIO::PrecisionUTCTime& T,
+ bool EOS,
+ const std::string& streamID,
+ const BULKIO::StreamSRI& sri)
+ {
+ this->_sendPacket(data, T, EOS, streamID, sri);
+ if (EOS) {
+ _sriVersions.erase(streamID);
+ }
+ }
+
+ template
+ BULKIO::PortStatistics OutputTransport::getStatistics()
+ {
+ BULKIO::PortStatistics statistics = _stats.retrieve();
+
+ // Use our own stream tracking to fill in the statistics stream IDs
+ statistics.streamIDs.length(0);
+ for (VersionMap::iterator stream = _sriVersions.begin(); stream != _sriVersions.end(); ++stream) {
+ ossie::corba::push_back(statistics.streamIDs, stream->first.c_str());
+ }
+
+ // Add extended statistics from subclasses to the keywords
+ ossie::corba::extend(statistics.keywords, _getExtendedStatistics());
+
+ return statistics;
+ }
+
+ template
+ void OutputTransport::_sendPacket(const BufferType& data,
+ const BULKIO::PrecisionUTCTime& T,
+ bool EOS,
+ const std::string& streamID,
+ const BULKIO::StreamSRI& sri)
+ {
+ this->_pushPacket(data, T, EOS, streamID);
+ this->_recordPush(streamID, this->_dataLength(data), EOS);
+ }
+
+ template
+ void OutputTransport::_recordPush(const std::string& streamID, size_t elements, bool endOfStream)
+ {
+ _stats.update(elements, 0.0, endOfStream, streamID);
+ }
+
+ template
+ redhawk::PropertyMap OutputTransport::_getExtendedStatistics()
+ {
+ return redhawk::PropertyMap();
+ }
+
+ template
+ size_t OutputTransport::_dataLength(const BufferType& data)
+ {
+ return data.size();
+ }
+
+ template <>
+ size_t OutputTransport::_dataLength(const std::string& /*unused*/)
+ {
+ return 1;
+ }
+
+ //
+ // InputTransport
+ //
+ template
+ InputTransport::InputTransport(InPortType* port, const std::string& transportId) :
+ redhawk::ProvidesTransport(port, transportId),
+ _port(port)
+ {
+ }
+
+ //
+ // OutputManager
+ //
+ template
+ OutputManager::OutputManager(OutPortType* port) :
+ _port(port)
+ {
+ }
+
+ template
+ redhawk::UsesTransport*
+ OutputManager::createUsesTransport(CORBA::Object_ptr object,
+ const std::string& connectionId,
+ const redhawk::PropertyMap& properties)
+ {
+ typename PortType::_var_type port;
+ try {
+ port = PortType::_narrow(object);
+ } catch (const CORBA::Exception&) {
+ // If this narrow fails something has gone horribly wrong, but just
+ // let the negotiation layer handle it
+ return 0;
+ }
+ return createOutputTransport(port, connectionId, properties);
+ }
+
+ //
+ // InputManager
+ //
+ template
+ InputManager::InputManager(InPortType* port) :
+ _port(port)
+ {
+ }
+
+ template
+ redhawk::ProvidesTransport*
+ InputManager::createProvidesTransport(const std::string& transportId,
+ const redhawk::PropertyMap& properties)
+ {
+ return createInputTransport(transportId, properties);
+ }
+
+ //
+ // TransportFactory
+ //
+ template
+ std::string BulkioTransportFactory::repoId()
+ {
+ return PortType::_PD_repoId;
+ }
+
+ template
+ redhawk::ProvidesTransportManager*
+ BulkioTransportFactory::createProvidesManager(redhawk::NegotiableProvidesPortBase* port)
+ {
+ InPortType* bulkio_port = dynamic_cast(port);
+ if (!bulkio_port) {
+ throw std::logic_error("incorrect input port type for BulkIO transport factory " + repoId());
+ }
+ return this->createInputManager(bulkio_port);
+ }
+
+ template
+ redhawk::UsesTransportManager*
+ BulkioTransportFactory::createUsesManager(redhawk::NegotiableUsesPort* port)
+ {
+ OutPortType* bulkio_port = dynamic_cast(port);
+ if (!bulkio_port) {
+ throw std::logic_error("incorrect output port type for BulkIO transport factory " + repoId());
+ }
+ return this->createOutputManager(bulkio_port);
+ }
+
+#define INSTANTIATE_TEMPLATE(x) \
+ template class OutputTransport; \
+ template class OutputManager; \
+ template class InputTransport; \
+ template class InputManager; \
+ template class BulkioTransportFactory;
+
+ FOREACH_PORT_TYPE(INSTANTIATE_TEMPLATE);
+}
diff --git a/bulkioInterfaces/libsrc/cpp/CorbaTransport.cpp b/bulkioInterfaces/libsrc/cpp/CorbaTransport.cpp
new file mode 100644
index 000000000..d771215ab
--- /dev/null
+++ b/bulkioInterfaces/libsrc/cpp/CorbaTransport.cpp
@@ -0,0 +1,261 @@
+/*
+ * This file is protected by Copyright. Please refer to the COPYRIGHT file
+ * distributed with this source distribution.
+ *
+ * This file is part of REDHAWK bulkioInterfaces.
+ *
+ * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+#include "CorbaTransport.h"
+
+#include
+
+#include "bulkio_time_operators.h"
+#include "bulkio_p.h"
+
+namespace bulkio {
+
+ template
+ class CorbaTransport : public OutputTransport
+ {
+ public:
+ typedef typename PortType::_ptr_type PtrType;
+ typedef typename PortType::_var_type VarType;
+ typedef typename OutputTransport::BufferType BufferType;
+ typedef typename CorbaTraits::SequenceType SequenceType;
+ typedef typename CorbaTraits::TransportType TransportType;
+
+ CorbaTransport(OutPort* parent, PtrType port) :
+ OutputTransport(parent, port)
+ {
+ }
+
+ virtual std::string transportType() const
+ {
+ return "CORBA";
+ }
+
+ virtual CF::Properties transportInfo() const
+ {
+ return CF::Properties();
+ }
+
+ void disconnect()
+ {
+ // Set a timeout for the duration of this call, in case the remote
+ // side is in a bad state.
+ omniORB::setClientCallTimeout(this->_objref, 1000);
+ OutputTransport::disconnect();
+ omniORB::setClientCallTimeout(this->_objref, 0);
+ }
+
+ protected:
+ virtual void _pushSRI(const BULKIO::StreamSRI& sri)
+ {
+ try {
+ this->_objref->pushSRI(sri);
+ } catch (const CORBA::SystemException& exc) {
+ throw redhawk::FatalTransportError(ossie::corba::describeException(exc));
+ }
+ }
+
+ virtual void _pushPacket(const BufferType& data,
+ const BULKIO::PrecisionUTCTime& T,
+ bool EOS,
+ const std::string& streamID)
+ {
+ try {
+ _pushPacketImpl(data, T, EOS, streamID.c_str());
+ } catch (const CORBA::TIMEOUT& exc) {
+ throw redhawk::TransportTimeoutError("Push timed out");
+ } catch (const CORBA::SystemException& exc) {
+ throw redhawk::FatalTransportError(ossie::corba::describeException(exc));
+ }
+ }
+
+ private:
+ void _pushPacketImpl(const BufferType& data,
+ const BULKIO::PrecisionUTCTime& T,
+ bool EOS,
+ const char* streamID)
+ {
+ const TransportType* ptr = reinterpret_cast(data.data());
+ const SequenceType buffer(data.size(), data.size(), const_cast(ptr), false);
+ this->_objref->pushPacket(buffer, T, EOS, streamID);
+ }
+ };
+
+ template <>
+ void CorbaTransport::_pushPacketImpl(const redhawk::shared_bitbuffer& data,
+ const BULKIO::PrecisionUTCTime& T,
+ bool EOS,
+ const char* streamID)
+ {
+ BULKIO::BitSequence buffer;
+ size_t bytes = (data.size() + 7) / 8;
+ const CORBA::Octet* ptr;
+ redhawk::bitbuffer temp;
+ if (data.offset() == 0) {
+ // Bit buffer is byte-aligned, so it can be directly wrapped with a
+ // non-owning CORBA sequence
+ ptr = reinterpret_cast(data.data());
+ } else {
+ // Not byte-aligned, copy bits into a temporary buffer and use that
+ // as the data for the CORBA sequence
+ temp = data.copy();
+ ptr = reinterpret_cast(temp.data());
+ }
+ buffer.data.replace(bytes, bytes, const_cast(ptr), false);
+ buffer.bits = data.size();
+ _objref->pushPacket(buffer, T, EOS, streamID);
+ }
+
+ template <>
+ void CorbaTransport::_pushPacketImpl(const std::string& data,
+ const BULKIO::PrecisionUTCTime& T,
+ bool EOS,
+ const char* streamID)
+ {
+ _objref->pushPacket(data.c_str(), T, EOS, streamID);
+ }
+
+ template <>
+ void CorbaTransport::_pushPacketImpl(const std::string& data,
+ const BULKIO::PrecisionUTCTime& /* unused */,
+ bool EOS,
+ const char* streamID)
+ {
+ _objref->pushPacket(data.c_str(), EOS, streamID);
+ }
+
+ template
+ class ChunkingTransport : public CorbaTransport
+ {
+ public:
+ typedef typename PortType::_ptr_type PtrType;
+ typedef typename OutputTransport::BufferType BufferType;
+ typedef typename CorbaTraits::TransportType TransportType;
+
+ ChunkingTransport(OutPort* parent, PtrType port) :
+ CorbaTransport(parent, port),
+ maxSamplesPerPush(_getMaxSamplesPerPush())
+ {
+ }
+
+ /*
+ * Push a packet whose payload may not fit within the CORBA limit. The
+ * packet is broken down into sub-packets and sent via multiple pushPacket
+ * calls. The EOS is set to false for all of the sub-packets, except for
+ * the last sub-packet, which uses the input EOS argument.
+ */
+ virtual void _sendPacket(const BufferType& data,
+ const BULKIO::PrecisionUTCTime& T,
+ bool EOS,
+ const std::string& streamID,
+ const BULKIO::StreamSRI& sri)
+ {
+ double xdelta = sri.xdelta;
+ size_t itemSize = sri.mode?2:1;
+ size_t frameSize = itemSize;
+ if (sri.subsize > 0) {
+ frameSize *= sri.subsize;
+ }
+ // Quantize the push size (in terms of scalars) to the nearest frame,
+ // which takes both the complex mode and subsize into account
+ const size_t maxPushSize = (maxSamplesPerPush/frameSize) * frameSize;
+
+ // Always do at least one push (may be empty), ensuring that all samples
+ // are pushed
+ size_t first = 0;
+ size_t samplesRemaining = data.size();
+
+ // Initialize time of first subpacket
+ BULKIO::PrecisionUTCTime packetTime = T;
+
+ do {
+ // Don't send more samples than are remaining
+ const size_t pushSize = std::min(samplesRemaining, maxPushSize);
+ samplesRemaining -= pushSize;
+
+ // Send end-of-stream as false for all sub-packets except for the
+ // last one (when there are no samples remaining after this push),
+ // which gets the input EOS.
+ bool packetEOS = false;
+ if (samplesRemaining == 0) {
+ packetEOS = EOS;
+ }
+
+ // Take the next slice of the input buffer.
+ BufferType subPacket = data.slice(first, first + pushSize);
+ CorbaTransport::_sendPacket(subPacket, packetTime, packetEOS, streamID, sri);
+
+ // Synthesize the next packet timestamp
+ if (packetTime.tcstatus == BULKIO::TCS_VALID) {
+ packetTime += (pushSize/itemSize)* xdelta;
+ }
+
+ // Advance buffer to next sub-packet boundary
+ first += pushSize;
+ } while (samplesRemaining > 0);
+ }
+
+ private:
+ static inline size_t _getMaxSamplesPerPush()
+ {
+ // Take the maximum transfer size in bytes, multiply by some number
+ // < 1 to leave some margin for the CORBA header, then determine
+ // the maximum number of elements via bits, to support numeric data
+ // data types (e.g., float) and packed bits.
+ const size_t max_bits = (size_t) (bulkio::Const::MaxTransferBytes() * .9) * 8;
+ return max_bits / NativeTraits::bits;
+ }
+
+ const size_t maxSamplesPerPush;
+ };
+
+ template
+ OutputTransport* CorbaTransportFactory::Create(OutPort* parent,
+ PtrType port)
+ {
+ return new ChunkingTransport(parent, port);
+ }
+
+ template <>
+ OutputTransport*
+ CorbaTransportFactory::Create(OutPort* parent,
+ PtrType port)
+ {
+ return new CorbaTransport(parent, port);
+ }
+
+ template <>
+ OutputTransport*
+ CorbaTransportFactory::Create(OutPort* parent,
+ PtrType port)
+ {
+ return new CorbaTransport(parent, port);
+ }
+
+#define INSTANTIATE_TEMPLATE(x) \
+ template class CorbaTransport; \
+ template class CorbaTransportFactory;
+
+#define INSTANTIATE_NUMERIC_TEMPLATE(x) \
+ template class ChunkingTransport;
+
+ FOREACH_PORT_TYPE(INSTANTIATE_TEMPLATE);
+ FOREACH_NUMERIC_PORT_TYPE(INSTANTIATE_NUMERIC_TEMPLATE);
+ INSTANTIATE_NUMERIC_TEMPLATE(BULKIO::dataBit);
+}
diff --git a/bulkioInterfaces/libsrc/cpp/CorbaTransport.h b/bulkioInterfaces/libsrc/cpp/CorbaTransport.h
new file mode 100644
index 000000000..2f62dce66
--- /dev/null
+++ b/bulkioInterfaces/libsrc/cpp/CorbaTransport.h
@@ -0,0 +1,37 @@
+/*
+ * This file is protected by Copyright. Please refer to the COPYRIGHT file
+ * distributed with this source distribution.
+ *
+ * This file is part of REDHAWK bulkioInterfaces.
+ *
+ * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+#ifndef __bulkio_corbatransport_h
+#define __bulkio_corbatransport_h
+
+#include
+
+namespace bulkio {
+
+ template
+ class CorbaTransportFactory {
+ public:
+ typedef typename PortType::_ptr_type PtrType;
+
+ static OutputTransport* Create(OutPort* parent, PtrType port);
+ };
+
+}
+
+#endif // __bulkio_corbatransport_h
diff --git a/bulkioInterfaces/libsrc/cpp/LocalTransport.cpp b/bulkioInterfaces/libsrc/cpp/LocalTransport.cpp
new file mode 100644
index 000000000..c1e7b07ee
--- /dev/null
+++ b/bulkioInterfaces/libsrc/cpp/LocalTransport.cpp
@@ -0,0 +1,86 @@
+/*
+ * This file is protected by Copyright. Please refer to the COPYRIGHT file
+ * distributed with this source distribution.
+ *
+ * This file is part of REDHAWK bulkioInterfaces.
+ *
+ * REDHAWK bulkioInterfaces is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * REDHAWK bulkioInterfaces is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+#include "LocalTransport.h"
+
+#include
+
+#include "bulkio_p.h"
+
+namespace bulkio {
+
+ template
+ LocalTransport* LocalTransport::Factory(OutPort* parent,
+ PortBase* port)
+ {
+ LocalPortType* local_port = dynamic_cast(port);
+ if (local_port) {
+ typename PortType::_var_type corba_port = local_port->_this();
+ return new LocalTransport(parent, local_port, corba_port);
+ }
+ return 0;
+ }
+
+ template
+ LocalTransport::LocalTransport(OutPort* parent, LocalPortType* localPort, PtrType port) :
+ OutputTransport(parent, port),
+ _localPort(localPort)
+ {
+ _localPort->_add_ref();
+ }
+
+ template
+ LocalTransport::~LocalTransport()
+ {
+ _localPort->_remove_ref();
+ }
+
+ template