Commit | Line | Data |
---|---|---|
ece3fb0f PP |
1 | /* |
2 | * Copyright 2017 Philippe Proulx <pproulx@efficios.com> | |
3 | * | |
4 | * Permission is hereby granted, free of charge, to any person obtaining a copy | |
5 | * of this software and associated documentation files (the "Software"), to deal | |
6 | * in the Software without restriction, including without limitation the rights | |
7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
8 | * copies of the Software, and to permit persons to whom the Software is | |
9 | * furnished to do so, subject to the following conditions: | |
10 | * | |
11 | * The above copyright notice and this permission notice shall be included in | |
12 | * all copies or substantial portions of the Software. | |
13 | * | |
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
20 | * SOFTWARE. | |
21 | */ | |
22 | ||
fe30b20b PP |
23 | #define BT_LOG_TAG "NOTIF-INACTIVITY" |
24 | #include <babeltrace/lib-logging-internal.h> | |
25 | ||
ece3fb0f | 26 | #include <babeltrace/object-internal.h> |
3d9990ac | 27 | #include <babeltrace/compiler-internal.h> |
ece3fb0f PP |
28 | #include <babeltrace/ctf-ir/clock-class.h> |
29 | #include <babeltrace/graph/clock-class-priority-map.h> | |
fe650ea4 | 30 | #include <babeltrace/graph/clock-class-priority-map-internal.h> |
ece3fb0f PP |
31 | #include <babeltrace/graph/notification-internal.h> |
32 | #include <babeltrace/graph/notification-inactivity-internal.h> | |
33 | ||
34 | static | |
35 | void bt_notification_inactivity_destroy(struct bt_object *obj) | |
36 | { | |
37 | struct bt_notification_inactivity *notification = | |
38 | (struct bt_notification_inactivity *) obj; | |
39 | ||
fe30b20b PP |
40 | BT_LOGD("Destroying inactivity notification: addr=%p", notification); |
41 | BT_LOGD_STR("Putting clock class priority map."); | |
ece3fb0f PP |
42 | bt_put(notification->cc_prio_map); |
43 | ||
44 | if (notification->clock_values) { | |
fe30b20b | 45 | BT_LOGD_STR("Putting clock values."); |
ece3fb0f PP |
46 | g_hash_table_destroy(notification->clock_values); |
47 | } | |
48 | ||
49 | g_free(notification); | |
50 | } | |
51 | ||
52 | struct bt_notification *bt_notification_inactivity_create( | |
53 | struct bt_clock_class_priority_map *cc_prio_map) | |
54 | { | |
55 | struct bt_notification_inactivity *notification; | |
56 | struct bt_notification *ret_notif = NULL; | |
57 | ||
7acb78a0 PP |
58 | if (cc_prio_map) { |
59 | /* Function's reference, released at the end */ | |
60 | bt_get(cc_prio_map); | |
61 | } else { | |
62 | cc_prio_map = bt_clock_class_priority_map_create(); | |
63 | if (!cc_prio_map) { | |
64 | BT_LOGE_STR("Cannot create empty clock class priority map."); | |
65 | goto error; | |
66 | } | |
ece3fb0f PP |
67 | } |
68 | ||
fe30b20b PP |
69 | BT_LOGD("Creating inactivity notification object: " |
70 | "cc-prio-map-addr=%p", | |
71 | cc_prio_map); | |
ece3fb0f PP |
72 | notification = g_new0(struct bt_notification_inactivity, 1); |
73 | if (!notification) { | |
fe30b20b | 74 | BT_LOGE_STR("Failed to allocate one inactivity notification."); |
ece3fb0f PP |
75 | goto error; |
76 | } | |
77 | bt_notification_init(¬ification->parent, | |
fe30b20b PP |
78 | BT_NOTIFICATION_TYPE_INACTIVITY, |
79 | bt_notification_inactivity_destroy); | |
ece3fb0f PP |
80 | ret_notif = ¬ification->parent; |
81 | notification->clock_values = g_hash_table_new_full(g_direct_hash, | |
fe30b20b | 82 | g_direct_equal, bt_put, bt_put); |
ece3fb0f | 83 | if (!notification->clock_values) { |
fe30b20b | 84 | BT_LOGE_STR("Failed to allocate a GHashTable."); |
ece3fb0f PP |
85 | goto error; |
86 | } | |
87 | ||
88 | notification->cc_prio_map = bt_get(cc_prio_map); | |
fe30b20b | 89 | BT_LOGD_STR("Freezing inactivity notification's clock class priority map."); |
fe650ea4 | 90 | bt_clock_class_priority_map_freeze(cc_prio_map); |
fe30b20b PP |
91 | BT_LOGD("Created inactivity notification object: " |
92 | "cc-prio-map-addr=%p, notif-addr=%p", | |
93 | cc_prio_map, ret_notif); | |
ece3fb0f PP |
94 | goto end; |
95 | ||
96 | error: | |
97 | BT_PUT(ret_notif); | |
98 | ||
99 | end: | |
7acb78a0 | 100 | bt_put(cc_prio_map); |
ece3fb0f PP |
101 | return ret_notif; |
102 | } | |
103 | ||
104 | extern struct bt_clock_class_priority_map * | |
105 | bt_notification_inactivity_get_clock_class_priority_map( | |
106 | struct bt_notification *notification) | |
107 | { | |
108 | struct bt_clock_class_priority_map *cc_prio_map = NULL; | |
109 | struct bt_notification_inactivity *inactivity_notification; | |
110 | ||
fe30b20b PP |
111 | if (!notification) { |
112 | BT_LOGW_STR("Invalid parameter: notification is NULL."); | |
113 | goto end; | |
114 | } | |
115 | ||
ece3fb0f PP |
116 | if (bt_notification_get_type(notification) != |
117 | BT_NOTIFICATION_TYPE_INACTIVITY) { | |
fe30b20b PP |
118 | BT_LOGW("Invalid parameter: notification is not an inactivity notification: " |
119 | "addr%p, notif-type=%s", | |
120 | notification, bt_notification_type_string( | |
121 | bt_notification_get_type(notification))); | |
ece3fb0f PP |
122 | goto end; |
123 | } | |
124 | ||
125 | inactivity_notification = container_of(notification, | |
126 | struct bt_notification_inactivity, parent); | |
127 | cc_prio_map = bt_get(inactivity_notification->cc_prio_map); | |
128 | end: | |
129 | return cc_prio_map; | |
130 | } | |
131 | ||
50842bdc | 132 | struct bt_clock_value *bt_notification_inactivity_get_clock_value( |
ece3fb0f | 133 | struct bt_notification *notification, |
50842bdc | 134 | struct bt_clock_class *clock_class) |
ece3fb0f | 135 | { |
50842bdc | 136 | struct bt_clock_value *clock_value = NULL; |
ece3fb0f PP |
137 | struct bt_notification_inactivity *inactivity_notification; |
138 | ||
fe30b20b PP |
139 | if (!notification) { |
140 | BT_LOGW_STR("Invalid parameter: notification is NULL."); | |
141 | goto end; | |
142 | } | |
143 | ||
144 | if (!clock_class) { | |
145 | BT_LOGW_STR("Invalid parameter: clock class is NULL."); | |
ece3fb0f PP |
146 | goto end; |
147 | } | |
148 | ||
149 | if (bt_notification_get_type(notification) != | |
150 | BT_NOTIFICATION_TYPE_INACTIVITY) { | |
fe30b20b PP |
151 | BT_LOGW("Invalid parameter: notification is not an inactivity notification: " |
152 | "addr%p, notif-type=%s", | |
153 | notification, bt_notification_type_string( | |
154 | bt_notification_get_type(notification))); | |
ece3fb0f PP |
155 | goto end; |
156 | } | |
157 | ||
158 | inactivity_notification = container_of(notification, | |
fe30b20b | 159 | struct bt_notification_inactivity, parent); |
ece3fb0f PP |
160 | clock_value = g_hash_table_lookup(inactivity_notification->clock_values, |
161 | clock_class); | |
162 | bt_get(clock_value); | |
163 | ||
164 | end: | |
165 | return clock_value; | |
166 | } | |
167 | ||
168 | int bt_notification_inactivity_set_clock_value( | |
169 | struct bt_notification *notification, | |
50842bdc | 170 | struct bt_clock_value *clock_value) |
ece3fb0f PP |
171 | { |
172 | int ret = 0; | |
173 | uint64_t prio; | |
50842bdc | 174 | struct bt_clock_class *clock_class = NULL; |
ece3fb0f PP |
175 | struct bt_notification_inactivity *inactivity_notification; |
176 | ||
fe30b20b PP |
177 | if (!notification) { |
178 | BT_LOGW_STR("Invalid parameter: notification is NULL."); | |
179 | ret = -1; | |
180 | goto end; | |
181 | } | |
182 | ||
183 | if (!clock_value) { | |
184 | BT_LOGW_STR("Invalid parameter: clock value is NULL."); | |
185 | ret = -1; | |
186 | goto end; | |
187 | } | |
188 | ||
189 | if (notification->frozen) { | |
190 | BT_LOGW_STR("Invalid parameter: notification is frozen."); | |
ece3fb0f PP |
191 | ret = -1; |
192 | goto end; | |
193 | } | |
194 | ||
195 | if (bt_notification_get_type(notification) != | |
196 | BT_NOTIFICATION_TYPE_INACTIVITY) { | |
fe30b20b PP |
197 | BT_LOGW("Invalid parameter: notification is not an inactivity notification: " |
198 | "addr%p, notif-type=%s", | |
199 | notification, bt_notification_type_string( | |
200 | bt_notification_get_type(notification))); | |
7bd556d8 | 201 | ret = -1; |
ece3fb0f PP |
202 | goto end; |
203 | } | |
204 | ||
205 | inactivity_notification = container_of(notification, | |
206 | struct bt_notification_inactivity, parent); | |
50842bdc | 207 | clock_class = bt_clock_value_get_class(clock_value); |
ece3fb0f PP |
208 | ret = bt_clock_class_priority_map_get_clock_class_priority( |
209 | inactivity_notification->cc_prio_map, clock_class, &prio); | |
210 | if (ret) { | |
fe30b20b PP |
211 | BT_LOGW("Clock value's class is not mapped to a priority within the scope of the inactivity notification: " |
212 | "notif-addr=%p, cc-prio-map-addr=%p, " | |
213 | "clock-class-addr=%p, clock-class-name=\"%s\", " | |
214 | "clock-value-addr=%p", | |
215 | inactivity_notification, | |
216 | inactivity_notification->cc_prio_map, | |
50842bdc | 217 | clock_class, bt_clock_class_get_name(clock_class), |
fe30b20b | 218 | clock_value); |
7bd556d8 | 219 | ret = -1; |
ece3fb0f PP |
220 | goto end; |
221 | } | |
222 | ||
223 | g_hash_table_insert(inactivity_notification->clock_values, | |
224 | clock_class, bt_get(clock_value)); | |
225 | clock_class = NULL; | |
fe30b20b PP |
226 | BT_LOGV("Set inactivity notification's clock value: " |
227 | "notif-addr=%p, cc-prio-map-addr=%p, " | |
228 | "clock-class-addr=%p, clock-class-name=\"%s\", " | |
229 | "clock-value-addr=%p", | |
230 | inactivity_notification, | |
231 | inactivity_notification->cc_prio_map, | |
50842bdc | 232 | clock_class, bt_clock_class_get_name(clock_class), |
fe30b20b | 233 | clock_value); |
ece3fb0f PP |
234 | |
235 | end: | |
236 | bt_put(clock_class); | |
237 | return ret; | |
238 | } |