EM-ODP  3.7.0
Event Machine on ODP
em_event_group.c
1 /*
2  * Copyright (c) 2015, Nokia Solutions and Networks
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * * Neither the name of the copyright holder nor the names of its
15  * contributors may be used to endorse or promote products derived
16  * from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "em_include.h"
32 
33 static inline event_group_elem_t *
34 egrp_poolelem2egrp(objpool_elem_t *const event_group_pool_elem)
35 {
36  return (event_group_elem_t *)((uintptr_t)event_group_pool_elem -
37  offsetof(event_group_elem_t, event_group_pool_elem));
38 }
39 
41 event_group_init(event_group_tbl_t *const event_group_tbl,
42  event_group_pool_t *const event_group_pool)
43 {
44  event_group_elem_t *egrp_elem;
45  const uint32_t objpool_subpools = OBJSUBPOOLS_MAX;
46 
47  int ret;
48 
49  memset(event_group_tbl, 0, sizeof(event_group_tbl_t));
50  memset(event_group_pool, 0, sizeof(event_group_pool_t));
51  env_atomic32_init(&em_shm->event_group_count);
52 
53  for (int i = 0; i < EM_MAX_EVENT_GROUPS; i++) {
54  em_event_group_t egrp = egrp_idx2hdl(i);
55 
56  egrp_elem = event_group_elem_get(egrp);
57  if (unlikely(!egrp_elem))
58  return EM_ERR_BAD_POINTER;
59 
60  egrp_elem->event_group = egrp; /* store handle */
61  egrp_elem->all = 0; /* set num_notif = 0, ready = 0 */
62  env_atomic64_set(&egrp_elem->post.atomic, 0);
63  env_atomic64_set(&egrp_elem->pre.atomic, 0);
64  }
65 
66  ret = objpool_init(&event_group_pool->objpool, objpool_subpools);
67  if (ret != 0)
68  return EM_ERR_LIB_FAILED;
69 
70  for (uint32_t i = 0; i < EM_MAX_EVENT_GROUPS; i++) {
71  egrp_elem = &event_group_tbl->egrp_elem[i];
72  objpool_add(&event_group_pool->objpool, i % objpool_subpools,
73  &egrp_elem->event_group_pool_elem);
74  }
75 
76  return EM_OK;
77 }
78 
79 em_event_group_t
80 event_group_alloc(void)
81 {
82  const event_group_elem_t *egrp_elem;
83  objpool_elem_t *egrp_pool_elem;
84 
85  egrp_pool_elem = objpool_rem(&em_shm->event_group_pool.objpool,
86  em_core_id());
87  if (unlikely(egrp_pool_elem == NULL))
88  return EM_EVENT_GROUP_UNDEF;
89 
90  egrp_elem = egrp_poolelem2egrp(egrp_pool_elem);
91 
92  env_atomic32_inc(&em_shm->event_group_count);
93  return egrp_elem->event_group;
94 }
95 
97 event_group_free(em_event_group_t event_group)
98 {
99  event_group_elem_t *egrp_elem = event_group_elem_get(event_group);
100 
101  if (unlikely(egrp_elem == NULL))
102  return EM_ERR_BAD_ID;
103 
104  objpool_add(&em_shm->event_group_pool.objpool,
105  egrp_elem->event_group_pool_elem.subpool_idx,
106  &egrp_elem->event_group_pool_elem);
107 
108  env_atomic32_dec(&em_shm->event_group_count);
109  return EM_OK;
110 }
111 
112 unsigned int
113 event_group_count(void)
114 {
115  return env_atomic32_get(&em_shm->event_group_count);
116 }
117 
118 #define EGRP_INFO_HDR_FMT \
119 "Number of event groups: %d\n\n" \
120 "ID Ready Cnt(post) Gen Num-notif\n" \
121 "------------------------------------------\n%s\n"
122 
123 #define EGRP_INFO_LEN 43
124 #define EGRP_INFO_FMT "%-10" PRI_EGRP "%-7c%-11d%-5d%-9d\n" /*43 bytes*/
125 
127 {
128  unsigned int egrp_num;
129  em_event_group_t egrp;
130  const event_group_elem_t *egrp_elem;
131  egrp_counter_t egrp_count;
132  int len = 0;
133  int n_print = 0;
134 
135  egrp = em_event_group_get_first(&egrp_num);
136 
137  /*
138  * egrp_num may not match the amount of event groups actually returned
139  * by iterating with em_event_group_get_next() if event groups are added
140  * or removed in parallel by another core. Thus space for 10 extra event
141  * groups is reserved. If more than 10 event groups are added by other
142  * cores in paralle, we print only information of the (egrp_num + 10)
143  * event groups.
144  *
145  * The extra 1 byte is reserved for the terminating null byte.
146  */
147  const int egrp_info_str_len = (egrp_num + 10) * EGRP_INFO_LEN + 1;
148  char egrp_info_str[egrp_info_str_len];
149 
150  while (egrp != EM_EVENT_GROUP_UNDEF) {
151  egrp_elem = event_group_elem_get(egrp);
152 
153  if (unlikely(egrp_elem == NULL || !event_group_allocated(egrp_elem))) {
154  egrp = em_event_group_get_next();
155  continue;
156  }
157 
158  egrp_count.all = EM_ATOMIC_GET(&egrp_elem->post.atomic);
159 
160  n_print = snprintf(egrp_info_str + len,
161  egrp_info_str_len - len,
162  EGRP_INFO_FMT, egrp,
163  egrp_elem->ready ? 'Y' : 'N',
164  egrp_count.count, egrp_count.gen,
165  egrp_elem->num_notif);
166 
167  /* Not enough space to hold more event group info */
168  if (n_print >= egrp_info_str_len - len)
169  break;
170 
171  len += n_print;
172  egrp = em_event_group_get_next();
173  }
174 
175  /* No event group */
176  if (len == 0) {
177  EM_PRINT("No event group!\n");
178  return;
179  }
180 
181  /*
182  * To prevent printing incomplete information of the last event group
183  * when there is not enough space to hold all event group info.
184  */
185  egrp_info_str[len] = '\0';
186  EM_PRINT(EGRP_INFO_HDR_FMT, egrp_num, egrp_info_str);
187 }
EM_OK
#define EM_OK
Definition: event_machine_types.h:329
em_shm_t::event_group_count
env_atomic32_t event_group_count
Definition: em_mem.h:140
event_group_elem_t::event_group
em_event_group_t event_group
Definition: em_event_group_types.h:92
event_group_pool_t
Definition: em_event_group_types.h:111
event_group_info_print
void event_group_info_print(void)
Definition: em_event_group.c:126
EM_ERR_LIB_FAILED
@ EM_ERR_LIB_FAILED
Definition: event_machine_hw_types.h:291
EM_MAX_EVENT_GROUPS
#define EM_MAX_EVENT_GROUPS
Definition: event_machine_config.h:161
event_group_elem_t::num_notif
int num_notif
Definition: em_event_group_types.h:83
em_event_group_get_first
em_event_group_t em_event_group_get_first(unsigned int *num)
Definition: event_machine_event_group.c:782
egrp_counter_t::gen
int32_t gen
Definition: em_event_group_types.h:52
EM_ERR_BAD_ID
@ EM_ERR_BAD_ID
Definition: event_machine_hw_types.h:265
em_status_t
uint32_t em_status_t
Definition: event_machine_types.h:321
objpool_elem_t
Definition: objpool.h:48
event_group_elem_t::all
uint64_t all
Definition: em_event_group_types.h:88
em_shm
em_shm_t * em_shm
Definition: event_machine_init.c:41
em_include.h
em_core_id
int em_core_id(void)
Definition: event_machine_core.c:34
egrp_counter_t
Definition: em_event_group_types.h:47
event_group_tbl_t
Definition: em_event_group_types.h:103
event_group_elem_t::ready
bool ready
Definition: em_event_group_types.h:85
EM_ERR_BAD_POINTER
@ EM_ERR_BAD_POINTER
Definition: event_machine_hw_types.h:271
event_group_elem_t::event_group_pool_elem
objpool_elem_t event_group_pool_elem
Definition: em_event_group_types.h:94
event_group_elem_t
Definition: em_event_group_types.h:64
em_event_group_get_next
em_event_group_t em_event_group_get_next(void)
Definition: event_machine_event_group.c:811
EM_EVENT_GROUP_UNDEF
#define EM_EVENT_GROUP_UNDEF
Definition: event_machine_types.h:141
event_group_tbl_t::egrp_elem
event_group_elem_t egrp_elem[EM_MAX_EVENT_GROUPS]
Definition: em_event_group_types.h:105
egrp_counter_t::count
int32_t count
Definition: em_event_group_types.h:50