[rtems commit] libcsupport: Add rtems_resource_snapshot_take()

Sebastian Huber sebh at rtems.org
Fri Dec 21 15:07:42 UTC 2012


Module:    rtems
Branch:    master
Commit:    c5d27600f99a259430a73630255cbb01d397f96d
Changeset: http://git.rtems.org/rtems/commit/?id=c5d27600f99a259430a73630255cbb01d397f96d

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri Dec 21 10:59:04 2012 +0100

libcsupport: Add rtems_resource_snapshot_take()

Add rtems_resource_rtems_api, rtems_resource_posix_api,
rtems_resource_snapshot, rtems_resource_snapshot_equal(), and
rtems_resource_snapshot_check().

---

 cpukit/libcsupport/Makefile.am                  |    1 +
 cpukit/libcsupport/include/rtems/libcsupport.h  |   87 ++++++++++++++++
 cpukit/libcsupport/src/resource_snapshot.c      |  127 +++++++++++++++++++++++
 testsuites/psxtests/psxconfig01/init.c          |   98 +++++++++++++++++-
 testsuites/psxtests/psxconfig01/psxconfig01.scn |    8 +-
 5 files changed, 316 insertions(+), 5 deletions(-)

diff --git a/cpukit/libcsupport/Makefile.am b/cpukit/libcsupport/Makefile.am
index 703ef60..76147c9 100644
--- a/cpukit/libcsupport/Makefile.am
+++ b/cpukit/libcsupport/Makefile.am
@@ -136,6 +136,7 @@ libcsupport_a_SOURCES = src/gxx_wrappers.c src/getchark.c src/printk.c \
     src/sup_fs_deviceerrno.c \
     src/clonenode.c \
     src/freenode.c \
+    src/resource_snapshot.c \
     $(BSD_LIBC_C_FILES) $(BASE_FS_C_FILES) $(MALLOC_C_FILES) \
     $(ERROR_C_FILES) $(ASSOCIATION_C_FILES)
 
diff --git a/cpukit/libcsupport/include/rtems/libcsupport.h b/cpukit/libcsupport/include/rtems/libcsupport.h
index 81e2156..2c49884 100644
--- a/cpukit/libcsupport/include/rtems/libcsupport.h
+++ b/cpukit/libcsupport/include/rtems/libcsupport.h
@@ -99,6 +99,93 @@ void newlib_delete_hook(
   0                       /* fatal        */ \
 }
 
+typedef struct {
+  uint32_t active_barriers;
+  uint32_t active_extensions;
+  uint32_t active_message_queues;
+  uint32_t active_partitions;
+  uint32_t active_periods;
+  uint32_t active_ports;
+  uint32_t active_regions;
+  uint32_t active_semaphores;
+  uint32_t active_tasks;
+  uint32_t active_timers;
+} rtems_resource_rtems_api;
+
+typedef struct {
+  uint32_t active_barriers;
+  uint32_t active_condition_variables;
+  uint32_t active_keys;
+  uint32_t active_message_queues;
+  uint32_t active_message_queue_descriptors;
+  uint32_t active_mutexes;
+  uint32_t active_rwlocks;
+  uint32_t active_semaphores;
+  uint32_t active_spinlocks;
+  uint32_t active_threads;
+  uint32_t active_timers;
+} rtems_resource_posix_api;
+
+typedef struct {
+  Heap_Information_block workspace_info;
+  Heap_Information_block heap_info;
+  rtems_resource_rtems_api rtems_api;
+  rtems_resource_posix_api posix_api;
+  int open_files;
+} rtems_resource_snapshot;
+
+/**
+ * @brief Tasks a snapshot of the resource usage of the system.
+ *
+ * @param[out] snapshot The snapshot of used resources.
+ *
+ * @see rtems_resource_snapshot_equal() and rtems_resource_snapshot_check().
+ *
+ * @code
+ * #include <assert.h>
+ *
+ * #include <rtems/libcsupport.h>
+ *
+ * void example(void)
+ * {
+ *   rtems_resource_snapshot before;
+ *
+ *   test_setup();
+ *   rtems_resource_snapshot_take(&before);
+ *   test();
+ *   assert(rtems_resource_snapshot_check(&before));
+ *   test_cleanup();
+ * }
+ * @endcode
+ */
+void rtems_resource_snapshot_take(rtems_resource_snapshot *snapshot);
+
+/**
+ * @brief Compares two resource snapshots for equality.
+ *
+ * @return Returns true if the resource snapshots are equal, and false
+ * otherwise.
+ *
+ * @see rtems_resource_snapshot_take().
+ */
+bool rtems_resource_snapshot_equal(
+  const rtems_resource_snapshot *a,
+  const rtems_resource_snapshot *b
+);
+
+/**
+ * @brief Takes a new resource snapshot and checks that it is equal to the
+ * given snapshot.
+ *
+ * @param[in] snapshot The snapshot used for comparison with the new snapshot.
+ *
+ * @return Returns true if the resource snapshots are equal, and false
+ * otherwise.
+ *
+ * @see rtems_resource_snapshot_take().
+ */
+bool rtems_resource_snapshot_check(const rtems_resource_snapshot *snapshot);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/cpukit/libcsupport/src/resource_snapshot.c b/cpukit/libcsupport/src/resource_snapshot.c
new file mode 100644
index 0000000..e143fdf
--- /dev/null
+++ b/cpukit/libcsupport/src/resource_snapshot.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Obere Lagerstr. 30
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems/libcsupport.h>
+
+#include <string.h>
+
+#include <rtems/libio_.h>
+#include <rtems/malloc.h>
+#include <rtems/score/wkspace.h>
+#include <rtems/score/protectedheap.h>
+
+#ifdef RTEMS_POSIX_API
+  #include <rtems/posix/barrier.h>
+  #include <rtems/posix/cond.h>
+  #include <rtems/posix/mqueue.h>
+  #include <rtems/posix/mutex.h>
+  #include <rtems/posix/key.h>
+  #include <rtems/posix/psignal.h>
+  #include <rtems/posix/pthread.h>
+  #include <rtems/posix/rwlock.h>
+  #include <rtems/posix/semaphore.h>
+  #include <rtems/posix/spinlock.h>
+  #include <rtems/posix/timer.h>
+#endif
+
+static const Objects_Information *objects_info_table[] = {
+  &_Barrier_Information,
+  &_Extension_Information,
+  &_Message_queue_Information,
+  &_Partition_Information,
+  &_Rate_monotonic_Information,
+  &_Dual_ported_memory_Information,
+  &_Region_Information,
+  &_Semaphore_Information,
+  &_RTEMS_tasks_Information,
+  &_Timer_Information
+  #ifdef RTEMS_POSIX_API
+    ,
+    &_POSIX_Barrier_Information,
+    &_POSIX_Condition_variables_Information,
+    &_POSIX_Keys_Information,
+    &_POSIX_Message_queue_Information,
+    &_POSIX_Message_queue_Information_fds,
+    &_POSIX_Mutex_Information,
+    &_POSIX_RWLock_Information,
+    &_POSIX_Semaphore_Information,
+    &_POSIX_Spinlock_Information,
+    &_POSIX_Threads_Information,
+    &_POSIX_Timer_Information
+  #endif
+};
+
+static int open_files(void)
+{
+  int free_count = 0;
+  rtems_libio_t *iop;
+
+  rtems_libio_lock();
+
+  iop = rtems_libio_iop_freelist;
+  while (iop != NULL) {
+    ++free_count;
+
+    iop = iop->data1;
+  }
+
+  rtems_libio_unlock();
+
+  return (int) rtems_libio_number_iops - free_count;
+}
+
+void rtems_resource_snapshot_take(rtems_resource_snapshot *snapshot)
+{
+  uint32_t *active = &snapshot->rtems_api.active_barriers;
+  size_t i;
+
+  _Protected_heap_Get_information(RTEMS_Malloc_Heap, &snapshot->heap_info);
+
+  _Thread_Disable_dispatch();
+
+  _Heap_Get_information(&_Workspace_Area, &snapshot->workspace_info);
+
+  for (i = 0; i < RTEMS_ARRAY_SIZE(objects_info_table); ++i) {
+    active [i] = _Objects_Active_count(objects_info_table[i]);
+  }
+
+  _Thread_Enable_dispatch();
+
+  #ifndef RTEMS_POSIX_API
+    memset(&snapshot->posix_api, 0, sizeof(snapshot->posix_api));
+  #endif
+
+  snapshot->open_files = open_files();
+}
+
+bool rtems_resource_snapshot_equal(
+  const rtems_resource_snapshot *a,
+  const rtems_resource_snapshot *b
+)
+{
+  return memcmp(a, b, sizeof(*a)) == 0;
+}
+
+bool rtems_resource_snapshot_check(const rtems_resource_snapshot *snapshot)
+{
+  rtems_resource_snapshot now;
+
+  rtems_resource_snapshot_take(&now);
+
+  return rtems_resource_snapshot_equal(&now, snapshot);
+}
diff --git a/testsuites/psxtests/psxconfig01/init.c b/testsuites/psxtests/psxconfig01/init.c
index d8c835c..b2bd639 100644
--- a/testsuites/psxtests/psxconfig01/init.c
+++ b/testsuites/psxtests/psxconfig01/init.c
@@ -7,7 +7,7 @@
  */
 
 /*
- * Copyright (c) 2011 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2011-2012 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Obere Lagerstr. 30
@@ -36,8 +36,12 @@
 #include <stdio.h>
 #include <time.h>
 
+#include <rtems/libcsupport.h>
+
 #define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 5
 
+#define CONFIGURE_MAXIMUM_BARRIERS 2
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 7
 #define CONFIGURE_MAXIMUM_PARTITIONS 37
 #define CONFIGURE_MAXIMUM_PERIODS 41
 #define CONFIGURE_MAXIMUM_REGIONS 43
@@ -228,6 +232,7 @@ static rtems_task Init(rtems_task_argument argument)
   rtems_id id = RTEMS_ID_NONE;
   rtems_name name = rtems_build_name('C', 'O', 'N', 'F');
   rtems_extensions_table table;
+  rtems_resource_snapshot snapshot;
   int i = 0;
 
   puts("\n\n*** POSIX TEST CONFIG 01 ***");
@@ -236,6 +241,10 @@ static rtems_task Init(rtems_task_argument argument)
 
   print_info();
 
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(rtems_resource_snapshot_equal(&snapshot, &snapshot));
+  rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
+
 #ifdef CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS
   for (i = 3; i < CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS; ++i) {
     int oflag = O_WRONLY | O_CREAT | O_TRUNC;
@@ -244,6 +253,10 @@ static rtems_task Init(rtems_task_argument argument)
     int fd = open(path, oflag, mode);
     rtems_test_assert(fd == i);
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.open_files == CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS
+  );
 #endif
 
 #ifdef CONFIGURE_MAXIMUM_USER_EXTENSIONS
@@ -252,6 +265,10 @@ static rtems_task Init(rtems_task_argument argument)
     sc = rtems_extension_create(name, &table, &id);
     directive_failed(sc, "rtems_extension_create");
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.rtems_api.active_extensions == CONFIGURE_MAXIMUM_USER_EXTENSIONS
+  );
 #endif
 
 #ifdef CONFIGURE_MAXIMUM_BARRIERS
@@ -259,6 +276,10 @@ static rtems_task Init(rtems_task_argument argument)
     sc = rtems_barrier_create(name, RTEMS_DEFAULT_ATTRIBUTES, 1, &id);
     directive_failed(sc, "rtems_barrier_create");
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.rtems_api.active_barriers == CONFIGURE_MAXIMUM_BARRIERS
+  );
 #endif
 
 #ifdef CONFIGURE_MAXIMUM_MESSAGE_QUEUES
@@ -272,6 +293,11 @@ static rtems_task Init(rtems_task_argument argument)
     );
     directive_failed(sc, "rtems_message_queue_create");
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.rtems_api.active_message_queues
+      == CONFIGURE_MAXIMUM_MESSAGE_QUEUES
+  );
 #endif
 
 #ifdef CONFIGURE_MAXIMUM_PARTITIONS
@@ -286,6 +312,10 @@ static rtems_task Init(rtems_task_argument argument)
     );
     directive_failed(sc, "rtems_partition_create");
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.rtems_api.active_partitions == CONFIGURE_MAXIMUM_PARTITIONS
+  );
 #endif
 
 #ifdef CONFIGURE_MAXIMUM_PERIODS
@@ -293,6 +323,10 @@ static rtems_task Init(rtems_task_argument argument)
     sc = rtems_rate_monotonic_create(name, &id);
     directive_failed(sc, "rtems_rate_monotonic_create");
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.rtems_api.active_periods == CONFIGURE_MAXIMUM_PERIODS
+  );
 #endif
 
 #ifdef CONFIGURE_MAXIMUM_REGIONS
@@ -307,6 +341,10 @@ static rtems_task Init(rtems_task_argument argument)
     );
     directive_failed(sc, "rtems_region_create");
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.rtems_api.active_regions == CONFIGURE_MAXIMUM_REGIONS
+  );
 #endif
 
 #ifdef CONFIGURE_MAXIMUM_SEMAPHORES
@@ -320,6 +358,10 @@ static rtems_task Init(rtems_task_argument argument)
     );
     directive_failed(sc, "rtems_semaphore_create");
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.rtems_api.active_semaphores >= CONFIGURE_MAXIMUM_SEMAPHORES
+  );
 #endif
 
 #ifdef CONFIGURE_MAXIMUM_TASKS
@@ -334,6 +376,10 @@ static rtems_task Init(rtems_task_argument argument)
     );
     directive_failed(sc, "rtems_task_create");
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.rtems_api.active_tasks == CONFIGURE_MAXIMUM_TASKS
+  );
 #endif
 
 #ifdef CONFIGURE_MAXIMUM_TASK_VARIABLES
@@ -348,6 +394,10 @@ static rtems_task Init(rtems_task_argument argument)
     sc = rtems_timer_create(name, &id);
     directive_failed(sc, "rtems_timer_create");
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.rtems_api.active_timers == CONFIGURE_MAXIMUM_TIMERS
+  );
 #endif
 
 #ifdef CONFIGURE_MAXIMUM_POSIX_BARRIERS
@@ -356,6 +406,10 @@ static rtems_task Init(rtems_task_argument argument)
     eno = pthread_barrier_init(&barrier, NULL, 1);
     rtems_test_assert(eno == 0);
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.posix_api.active_barriers == CONFIGURE_MAXIMUM_POSIX_BARRIERS
+  );
 #endif
 
 #ifdef CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES
@@ -364,6 +418,11 @@ static rtems_task Init(rtems_task_argument argument)
     eno = pthread_cond_init(&cond, NULL);
     rtems_test_assert(eno == 0);
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.posix_api.active_condition_variables
+      == CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES
+  );
 #endif
 
 #ifdef CONFIGURE_MAXIMUM_POSIX_KEYS
@@ -372,6 +431,10 @@ static rtems_task Init(rtems_task_argument argument)
     eno = pthread_key_create(&key, posix_key_dtor);
     rtems_test_assert(eno == 0);
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.posix_api.active_keys == CONFIGURE_MAXIMUM_POSIX_KEYS
+  );
 #endif
 
 #ifdef POSIX_MQ_COUNT
@@ -386,6 +449,15 @@ static rtems_task Init(rtems_task_argument argument)
     mqd_t mq = mq_open(path, oflag, mode, &attr);
     rtems_test_assert(mq >= 0);
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.posix_api.active_message_queue_descriptors
+      == CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUE_DESCRIPTORS
+  );
+  rtems_test_assert(
+    snapshot.posix_api.active_message_queues
+      == CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES
+  );
 #endif
 
 #ifdef CONFIGURE_MAXIMUM_POSIX_MUTEXES
@@ -394,6 +466,10 @@ static rtems_task Init(rtems_task_argument argument)
     eno = pthread_mutex_init(&mutex, NULL);
     rtems_test_assert(eno == 0);
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.posix_api.active_mutexes == CONFIGURE_MAXIMUM_POSIX_MUTEXES
+  );
 #endif
 
 #ifdef CONFIGURE_MAXIMUM_POSIX_RWLOCKS
@@ -402,6 +478,10 @@ static rtems_task Init(rtems_task_argument argument)
     eno = pthread_rwlock_init(&rwlock, NULL);
     rtems_test_assert(eno == 0);
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.posix_api.active_rwlocks == CONFIGURE_MAXIMUM_POSIX_RWLOCKS
+  );
 #endif
 
 #ifdef CONFIGURE_MAXIMUM_POSIX_SEMAPHORES
@@ -413,6 +493,10 @@ static rtems_task Init(rtems_task_argument argument)
     sem_t *sem = sem_open(path, oflag, mode, value);
     rtems_test_assert(sem != SEM_FAILED);
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.posix_api.active_semaphores == CONFIGURE_MAXIMUM_POSIX_SEMAPHORES
+  );
 #endif
 
 #ifdef CONFIGURE_MAXIMUM_POSIX_SPINLOCKS
@@ -421,6 +505,10 @@ static rtems_task Init(rtems_task_argument argument)
     eno = pthread_spin_init(&spinlock, 0);
     rtems_test_assert(eno == 0);
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.posix_api.active_spinlocks == CONFIGURE_MAXIMUM_POSIX_SPINLOCKS
+  );
 #endif
 
 #ifdef CONFIGURE_MAXIMUM_POSIX_THREADS
@@ -429,6 +517,10 @@ static rtems_task Init(rtems_task_argument argument)
     eno = pthread_create(&thread, NULL, posix_thread, NULL);
     rtems_test_assert(eno == 0);
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.posix_api.active_threads == CONFIGURE_MAXIMUM_POSIX_THREADS
+  );
 #endif
 
 #ifdef CONFIGURE_MAXIMUM_POSIX_TIMERS
@@ -437,6 +529,10 @@ static rtems_task Init(rtems_task_argument argument)
     rv = timer_create(CLOCK_REALTIME, NULL, &timer_id);
     rtems_test_assert(rv == 0);
   }
+  rtems_resource_snapshot_take(&snapshot);
+  rtems_test_assert(
+    snapshot.posix_api.active_timers == CONFIGURE_MAXIMUM_POSIX_TIMERS
+  );
 #endif
 
   printf("object creation done\n");
diff --git a/testsuites/psxtests/psxconfig01/psxconfig01.scn b/testsuites/psxtests/psxconfig01/psxconfig01.scn
index 7283494..c2aeee5 100644
--- a/testsuites/psxtests/psxconfig01/psxconfig01.scn
+++ b/testsuites/psxtests/psxconfig01/psxconfig01.scn
@@ -1,7 +1,7 @@
 *** POSIX TEST CONFIG 01 ***
-used blocks = 46, largest used block = 8264, used space = 64344
-free blocks = 1, largest free block = 97040, free space = 97040
+used blocks = 61, largest used block = 8264, used space = 78792
+free blocks = 1, largest free block = 115944, free space = 115944
 object creation done
-used blocks = 204, largest used block = 8264, used space = 160984
-free blocks = 1, largest free block = 400, free space = 400
+used blocks = 280, largest used block = 8264, used space = 193704
+free blocks = 1, largest free block = 1032, free space = 1032
 *** END OF POSIX TEST CONFIG 01 ***




More information about the vc mailing list