source: rtems/cpukit/libcsupport/src/resource_snapshot.c @ 1c6926c1

5
Last change on this file since 1c6926c1 was c42be504, checked in by Sebastian Huber <sebastian.huber@…>, on 11/16/16 at 13:50:09

posix: Add self-contained pthread spinlock

Turn pthread_spinlock_t into a self-contained object. On uni-processor
configurations, interrupts are disabled in the lock/trylock operations
and the previous interrupt status is restored in the corresponding
unlock operations. On SMP configurations, a ticket lock is a acquired
and released in addition.

The self-contained pthread_spinlock_t object is defined by Newlib in
<sys/_pthreadtypes.h>.

typedef struct {

struct _Ticket_lock_Control _lock;
uint32_t _interrupt_state;

} pthread_spinlock_t;

This implementation is simple and efficient. However, this test case of
the Linux Test Project would fail due to call of printf() and sleep()
during spin lock ownership:

https://github.com/linux-test-project/ltp/blob/master/testcases/open_posix_testsuite/conformance/interfaces/pthread_spin_lock/1-2.c

There is only limited support for profiling on SMP configurations.

Delete CORE spinlock implementation.

Update #2674.

  • Property mode set to 100644
File size: 4.5 KB
Line 
1/*
2 * Copyright (c) 2012-2014 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#if HAVE_CONFIG_H
16  #include "config.h"
17#endif
18
19#include <rtems/libcsupport.h>
20
21#include <string.h>
22
23#include <rtems/libio_.h>
24#include <rtems/malloc.h>
25#include <rtems/score/rbtreeimpl.h>
26#include <rtems/score/protectedheap.h>
27#include <rtems/score/threadimpl.h>
28#include <rtems/score/wkspace.h>
29
30#include <rtems/posix/keyimpl.h>
31
32#include <rtems/rtems/barrierimpl.h>
33#include <rtems/extensionimpl.h>
34#include <rtems/rtems/dpmemimpl.h>
35#include <rtems/rtems/messageimpl.h>
36#include <rtems/rtems/partimpl.h>
37#include <rtems/rtems/ratemonimpl.h>
38#include <rtems/rtems/regionimpl.h>
39#include <rtems/rtems/semimpl.h>
40#include <rtems/rtems/tasksimpl.h>
41#include <rtems/rtems/timerimpl.h>
42
43#ifdef RTEMS_POSIX_API
44  #include <rtems/posix/barrierimpl.h>
45  #include <rtems/posix/condimpl.h>
46  #include <rtems/posix/mqueueimpl.h>
47  #include <rtems/posix/muteximpl.h>
48  #include <rtems/posix/psignal.h>
49  #include <rtems/posix/pthreadimpl.h>
50  #include <rtems/posix/rwlockimpl.h>
51  #include <rtems/posix/semaphoreimpl.h>
52  #include <rtems/posix/timerimpl.h>
53#endif
54
55static const struct {
56  Objects_APIs api;
57  uint16_t cls;
58} objects_info_table[] = {
59  { OBJECTS_POSIX_API, OBJECTS_POSIX_KEYS },
60  { OBJECTS_CLASSIC_API, OBJECTS_RTEMS_BARRIERS },
61  { OBJECTS_CLASSIC_API, OBJECTS_RTEMS_EXTENSIONS },
62  { OBJECTS_CLASSIC_API, OBJECTS_RTEMS_MESSAGE_QUEUES },
63  { OBJECTS_CLASSIC_API, OBJECTS_RTEMS_PARTITIONS },
64  { OBJECTS_CLASSIC_API, OBJECTS_RTEMS_PERIODS },
65  { OBJECTS_CLASSIC_API, OBJECTS_RTEMS_PORTS },
66  { OBJECTS_CLASSIC_API, OBJECTS_RTEMS_REGIONS },
67  { OBJECTS_CLASSIC_API, OBJECTS_RTEMS_SEMAPHORES },
68  { OBJECTS_CLASSIC_API, OBJECTS_RTEMS_TASKS },
69  { OBJECTS_CLASSIC_API, OBJECTS_RTEMS_TIMERS }
70  #ifdef RTEMS_POSIX_API
71    ,
72    { OBJECTS_POSIX_API, OBJECTS_POSIX_BARRIERS },
73    { OBJECTS_POSIX_API, OBJECTS_POSIX_CONDITION_VARIABLES },
74    { OBJECTS_POSIX_API, OBJECTS_POSIX_MESSAGE_QUEUES },
75    { OBJECTS_POSIX_API, OBJECTS_POSIX_MUTEXES },
76    { OBJECTS_POSIX_API, OBJECTS_POSIX_RWLOCKS },
77    { OBJECTS_POSIX_API, OBJECTS_POSIX_SEMAPHORES },
78    { OBJECTS_POSIX_API, OBJECTS_POSIX_THREADS },
79    { OBJECTS_POSIX_API, OBJECTS_POSIX_TIMERS }
80  #endif
81};
82
83static int open_files(void)
84{
85  int free_count = 0;
86  rtems_libio_t *iop;
87
88  rtems_libio_lock();
89
90  iop = rtems_libio_iop_freelist;
91  while (iop != NULL) {
92    ++free_count;
93
94    iop = iop->data1;
95  }
96
97  rtems_libio_unlock();
98
99  return (int) rtems_libio_number_iops - free_count;
100}
101
102static void get_heap_info(Heap_Control *heap, Heap_Information_block *info)
103{
104  _Heap_Get_information(heap, info);
105  memset(&info->Stats, 0, sizeof(info->Stats));
106}
107
108static POSIX_Keys_Control *get_next_key(Objects_Id *id)
109{
110  return (POSIX_Keys_Control *)
111    _Objects_Get_next(*id, &_POSIX_Keys_Information, id);
112}
113
114static uint32_t get_active_posix_key_value_pairs(void)
115{
116  uint32_t count = 0;
117  Objects_Id id = OBJECTS_ID_INITIAL_INDEX;
118  POSIX_Keys_Control *the_key;
119
120  while ((the_key = get_next_key(&id)) != NULL ) {
121    count += _Chain_Node_count_unprotected(&the_key->Key_value_pairs);
122    _Objects_Allocator_unlock();
123  }
124
125  return count;
126}
127
128void rtems_resource_snapshot_take(rtems_resource_snapshot *snapshot)
129{
130  uint32_t *active;
131  size_t i;
132
133  memset(snapshot, 0, sizeof(*snapshot));
134
135  _RTEMS_Lock_allocator();
136
137  _Thread_Kill_zombies();
138
139  get_heap_info(RTEMS_Malloc_Heap, &snapshot->heap_info);
140  get_heap_info(&_Workspace_Area, &snapshot->workspace_info);
141
142  active = &snapshot->active_posix_keys;
143
144  for (i = 0; i < RTEMS_ARRAY_SIZE(objects_info_table); ++i) {
145    const Objects_Information *information;
146
147    information = _Objects_Get_information(
148      objects_info_table[i].api,
149      objects_info_table[i].cls
150    );
151
152    if (information != NULL) {
153      active[i] = _Objects_Active_count(information);
154    }
155  }
156
157  _RTEMS_Unlock_allocator();
158
159  snapshot->active_posix_key_value_pairs = get_active_posix_key_value_pairs();
160  snapshot->open_files = open_files();
161}
162
163bool rtems_resource_snapshot_equal(
164  const rtems_resource_snapshot *a,
165  const rtems_resource_snapshot *b
166)
167{
168  return memcmp(a, b, sizeof(*a)) == 0;
169}
170
171bool rtems_resource_snapshot_check(const rtems_resource_snapshot *snapshot)
172{
173  rtems_resource_snapshot now;
174
175  rtems_resource_snapshot_take(&now);
176
177  return rtems_resource_snapshot_equal(&now, snapshot);
178}
Note: See TracBrowser for help on using the repository browser.