tools: resource-monitor: Add hal-api-foo test code
[platform/core/system/pass.git] / tools / resource-monitor / resource-monitor.c
1 /*
2  * PASS (Power Aware System Service) - Resource Monitor Tool
3  *
4  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <glib.h>
20
21 #include <sys/types.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <signal.h>
26 #include <unistd.h>
27 #include <inttypes.h>
28
29 #include <util/common.h>
30
31 #include <libsyscommon/resource-type.h>
32
33 #include "resource-monitor.h"
34
35 #include <hal/hal-foo.h>
36
37 #define BUFF_MAX        255
38 #define MAX_RESOURCE    100
39 #define MAX_ATTR        64
40
41 struct syscommon_resman_resource_attr_data {
42         const u_int64_t id;
43         const int type;
44         const int array_type;
45         const char *name;
46         const char *unit;
47         const char *desc;
48
49         u_int32_t value_uint32;
50         u_int64_t value_uint64;
51         int32_t value_int32;
52         int64_t value_int64;
53         double value_double;
54         char *value_string;
55 };
56
57 static struct syscommon_resman_resource_attr_data cpu_attrs[] = {
58         { .id = CPU_ATTR_NAME,                          .type = SYSCOMMON_RESMAN_DATA_TYPE_STRING,      .name = "CPU_ATTR_NAME",                                .unit = "",             .desc = "CPU cluster name", },
59         { .id = CPU_ATTR_CUR_FREQ,                      .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "CPU_ATTR_CUR_FREQ",                            .unit = "kHz",          .desc = "Current CPU frequency", },
60         { .id = CPU_ATTR_MIN_FREQ,                      .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "CPU_ATTR_MIN_FREQ",                            .unit = "kHz",          .desc = "Current CPU minimum frequency", },
61         { .id = CPU_ATTR_MAX_FREQ,                      .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "CPU_ATTR_MAX_FREQ",                            .unit = "kHz",          .desc = "Current CPU maximum frequency", },
62         { .id = CPU_ATTR_AVAILABLE_MIN_FREQ,            .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "CPU_ATTR_AVAILABLE_MIN_FREQ",                  .unit = "kHz",          .desc = "Available CPU minimum frequency", },
63         { .id = CPU_ATTR_AVAILABLE_MAX_FREQ,            .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "CPU_ATTR_AVAILABLE_MAX_FREQ",                  .unit = "kHz",          .desc = "Available CPU maximum frequency", },
64         { .id = CPU_ATTR_CUR_GOVERNOR,                  .type = SYSCOMMON_RESMAN_DATA_TYPE_STRING,      .name = "CPU_ATTR_CUR_GOVERNOR",                        .unit = "",             .desc = "Current CPU frequency governor name", },
65 };
66
67 static struct syscommon_resman_resource_attr_data bus_attrs[] = {
68         { .id = BUS_ATTR_NAME,                          .type = SYSCOMMON_RESMAN_DATA_TYPE_STRING,      .name = "BUS_ATTR_NAME",                                .unit = "",             .desc = "Bus device name", },
69         { .id = BUS_ATTR_CUR_FREQ,                      .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "BUS_ATTR_CUR_FREQ",                            .unit = "kHz",          .desc = "Current bus frequency", },
70         { .id = BUS_ATTR_MIN_FREQ,                      .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "BUS_ATTR_MIN_FREQ",                            .unit = "kHz",          .desc = "Current bus minimum frequency", },
71         { .id = BUS_ATTR_MAX_FREQ,                      .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "BUS_ATTR_MAX_FREQ",                            .unit = "kHz",          .desc = "Current bus maximum frequency", },
72         { .id = BUS_ATTR_AVAILABLE_MIN_FREQ,            .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "BUS_ATTR_AVAILABLE_MIN_FREQ",                  .unit = "kHz",          .desc = "Available bus minimum frequency", },
73         { .id = BUS_ATTR_AVAILABLE_MAX_FREQ,            .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "BUS_ATTR_AVAILABLE_MAX_FREQ",                  .unit = "kHz",          .desc = "Available bus maximum frequency", },
74         { .id = BUS_ATTR_CUR_GOVERNOR,                  .type = SYSCOMMON_RESMAN_DATA_TYPE_STRING,      .name = "BUS_ATTR_CUR_GOVERNOR",                        .unit = "",             .desc = "Current bus frequency governor name", },
75 };
76
77 static struct syscommon_resman_resource_attr_data gpu_attrs[] = {
78         { .id = GPU_ATTR_NAME,                          .type = SYSCOMMON_RESMAN_DATA_TYPE_STRING,      .name = "GPU_ATTR_NAME",                                .unit = "",             .desc = "GPU device name", },
79         { .id = GPU_ATTR_CUR_FREQ,                      .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "GPU_ATTR_CUR_FREQ",                            .unit = "kHz",          .desc = "Current GPU frequency", },
80         { .id = GPU_ATTR_MIN_FREQ,                      .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "GPU_ATTR_MIN_FREQ",                            .unit = "kHz",          .desc = "Current GPU minimum frequency", },
81         { .id = GPU_ATTR_MAX_FREQ,                      .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "GPU_ATTR_MAX_FREQ",                            .unit = "kHz",          .desc = "Current GPU maximum frequency", },
82         { .id = GPU_ATTR_AVAILABLE_MIN_FREQ,            .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "GPU_ATTR_AVAILABLE_MIN_FREQ",                  .unit = "kHz",          .desc = "Available GPU minimum frequency", },
83         { .id = GPU_ATTR_AVAILABLE_MAX_FREQ,            .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "GPU_ATTR_AVAILABLE_MAX_FREQ",                  .unit = "kHz",          .desc = "Available GPU maximum frequency", },
84         { .id = GPU_ATTR_CUR_GOVERNOR,                  .type = SYSCOMMON_RESMAN_DATA_TYPE_STRING,      .name = "GPU_ATTR_CUR_GOVERNOR",                        .unit = "",             .desc = "Current GPU frequency governor name", },
85 };
86
87 static struct syscommon_resman_resource_attr_data memory_attrs[] = {
88         { .id = MEMORY_ATTR_TOTAL,                      .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "MEMORY_ATTR_TOTAL",                            .unit = "kB",           .desc = "Memory total size", },
89         { .id = MEMORY_ATTR_AVAILABLE,                  .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "MEMORY_ATTR_AVAILABLE",                        .unit = "kB",           .desc = "Memory available size", },
90         { .id = MEMORY_ATTR_FREE,                       .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "MEMORY_ATTR_FREE",                             .unit = "kB",           .desc = "Memory free size", },
91         { .id = MEMORY_ATTR_BUFFER,                     .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "MEMORY_ATTR_BUFFER",                           .unit = "kB",           .desc = "Memorry buffer size", },
92         { .id = MEMORY_ATTR_CACHED,                     .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "MEMORY_ATTR_CACHED",                           .unit = "kB",           .desc = "Memory cached size", },
93         { .id = MEMORY_ATTR_CMA_TOTAL,                  .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "MEMORY_ATTR_CMA_TOTAL",                        .unit = "kB",           .desc = "CMA memory total size", },
94         { .id = MEMORY_ATTR_CMA_FREE,                   .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "MEMORY_ATTR_CMA_FREE",                         .unit = "kB",           .desc = "CMA memory free size", },
95         { .id = MEMORY_ATTR_SWAP_TOTAL,                 .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "MEMORY_ATTR_SWAP_TOTAL",                       .unit = "kB",           .desc = "Swap memory total size", },
96         { .id = MEMORY_ATTR_SWAP_FREE,                  .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "MEMORY_ATTR_SWAP_FREE",                        .unit = "kB",           .desc = "Swap memory free size", },
97 };
98
99 static struct syscommon_resman_resource_attr_data battery_attrs[] = {
100         { .id = BATTERY_ATTR_CAPACITY,                  .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "BATTERY_ATTR_CAPACITY",                        .unit = "%",            .desc = "Battery capacity", },
101         { .id = BATTERY_ATTR_STATUS,                    .type = SYSCOMMON_RESMAN_DATA_TYPE_STRING,      .name = "BATTERY_ATTR_STATUS",                          .unit = "",             .desc = "Battery status", },
102         { .id = BATTERY_ATTR_TEMPERATURE,               .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "BATTERY_ATTR_TEMPERATURE",                     .unit = "",             .desc = "Battery temperature", },
103         { .id = BATTERY_ATTR_VOLTAGE_NOW,               .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "BATTERY_ATTR_VOLTAGE_NOW",                     .unit = "uV",           .desc = "Battery voltage figure", },
104         { .id = BATTERY_ATTR_CURRENT_NOW,               .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "BATTERY_ATTR_CURRENT_NOW",                     .unit = "uA",           .desc = "Battery current figure", },
105         { .id = BATTERY_ATTR_PRESENT,                   .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "BATTERY_ATTR_PRESENT",                         .unit = "",             .desc = "Battery connected status", },
106         { .id = BATTERY_ATTR_ONLINE,                    .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "BATTERY_ATTR_ONLINE",                          .unit = "",             .desc = "Battery charger connector status", },
107 };
108
109 static struct syscommon_resman_resource_attr_data display_attrs[] = {
110         { .id = DISPLAY_ATTR_NAME,                      .type = SYSCOMMON_RESMAN_DATA_TYPE_STRING,      .name = "DISPLAY_ATTR_NAME",                            .unit = "",             .desc = "Display device name", },
111         { .id = DISPLAY_ATTR_FPS,                       .type = SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE,      .name = "DISPLAY_ATTR_FPS",                             .unit = "fps",          .desc = "Frame per second", },
112 };
113
114 static struct syscommon_resman_resource_attr_data system_attrs[] = {
115         { .id = SYSTEM_ATTR_CPU_UTIL,                   .type = SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE,      .name = "SYSTEM_ATTR_CPU_UTIL",                         .unit = "%",            .desc = "CPU average utilization", },
116         { .id = SYSTEM_ATTR_CPU_USER_UTIL,              .type = SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE,      .name = "SYSTEM_ATTR_CPU_USER_UTIL",                    .unit = "%",            .desc = "CPU average utilization on user", },
117         { .id = SYSTEM_ATTR_CPU_SYS_UTIL,               .type = SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE,      .name = "SYSTEM_ATTR_CPU_SYS_UTIL",                     .unit = "%",            .desc = "CPU average utilization on system", },
118         { .id = SYSTEM_ATTR_PER_CPU_UTIL,               .type = SYSCOMMON_RESMAN_DATA_TYPE_ARRAY,       .name = "SYSTEM_ATTR_PER_CPU_UTIL",                     .unit = "%",            .desc = "Per-CPU utilization",                  .array_type = SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE, },
119         { .id = SYSTEM_ATTR_PER_CPU_USER_UTIL,          .type = SYSCOMMON_RESMAN_DATA_TYPE_ARRAY,       .name = "SYSTEM_ATTR_PER_CPU_USER_UTIL",                .unit = "%",            .desc = "Per-CPU utilization on user",          .array_type = SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE, },
120         { .id = SYSTEM_ATTR_PER_CPU_SYS_UTIL,           .type = SYSCOMMON_RESMAN_DATA_TYPE_ARRAY,       .name = "SYSTEM_ATTR_PER_CPU_SYS_UTIL",                 .unit = "%",            .desc = "Per-CPU utilization on system",        .array_type = SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE, },
121         { .id = SYSTEM_ATTR_POSSIBLE_CPU,               .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "SYSTEM_ATTR_POSSIBLE_CPU",                     .unit = "ea",           .desc = "Number of possible CPU", },
122         { .id = SYSTEM_ATTR_ONLINE_CPU,                 .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "SYSTEM_ATTR_ONLINE_CPU",                       .unit = "ea",           .desc = "Number of online CPU", },
123         { .id = SYSTEM_ATTR_MEMORY_PRESSURE_LEVEL,      .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "SYSTEM_ATTR_MEMORY_PRESSURE_LEVEL",            .unit = "lv",           .desc = "Level of memory pressure", },
124
125 };
126
127 struct syscommon_resman_resource_attr_data process_attrs[] = {
128         { .id = PROCESS_ATTR_NAME,                      .type = SYSCOMMON_RESMAN_DATA_TYPE_STRING,      .name = "PROCESS_ATTR_NAME",                            .unit = "",             .desc = "Process name", },
129         { .id = PROCESS_ATTR_CPU_UTIL,                  .type = SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE,      .name = "PROCESS_ATTR_CPU_UTIL",                        .unit = "%",            .desc = "Process CPU utilization", },
130         { .id = PROCESS_ATTR_MEM_VIRT,                  .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "PROCESS_ATTR_MEM_VIRT",                        .unit = "kB",           .desc = "Process VIRT memory size", },
131         { .id = PROCESS_ATTR_MEM_RSS,                   .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "PROCESS_ATTR_MEM_RSS",                         .unit = "kB",           .desc = "Process RSS(Resident Set Size) memory size", },
132         { .id = PROCESS_ATTR_MEM_RSS_PERCENT,           .type = SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE,      .name = "PROCESS_ATTR_MEM_RSS_PERCENT",                 .unit = "%",            .desc = "Process RSS(Resident Set Size) memory percent", },
133         { .id = PROCESS_ATTR_DISK_READ_PER_SEC,         .type = SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE,      .name = "PROCESS_ATTR_DISK_READ_PER_SEC",               .unit = "kB/s",         .desc = "Process disk read per second", },
134         { .id = PROCESS_ATTR_DISK_WRITE_PER_SEC,        .type = SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE,      .name = "PROCESS_ATTR_DISK_WRITE_PER_SEC",              .unit = "kB/s",         .desc = "Process disk write per second", },
135         { .id = PROCESS_ATTR_PGID,                      .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "PROCESS_ATTR_PGID",                            .unit = "",             .desc = "Process group ID", },
136         { .id = PROCESS_ATTR_PPID,                      .type = SYSCOMMON_RESMAN_DATA_TYPE_INT,         .name = "PROCESS_ATTR_PPID",                            .unit = "",             .desc = "Process parent PID(Process ID)", },
137         { .id = PROCESS_ATTR_MEM_PSS,                   .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "PROCESS_ATTR_MEM_PSS",                         .unit = "kB",           .desc = "Process PSS(Propotional Set Size) memory size", },
138         { .id = PROCESS_ATTR_MEM_SWAP,                  .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "PROCESS_ATTR_MEM_SWAP",                        .unit = "kB",           .desc = "Process Swap memory size", },
139         { .id = PROCESS_ATTR_MEM_SWAP_PSS,              .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "PROCESS_ATTR_MEM_SWAP_PSS",                    .unit = "kB",           .desc = "Process Swap PSS(Propotional Set Size) memory size", },
140         { .id = PROCESS_ATTR_MEM_GPU,                   .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "PROCESS_ATTR_MEM_GPU",                         .unit = "kB",           .desc = "Process GPU memory size", },
141 };
142
143 struct syscommon_resman_resource_attr_data process_group_attrs[] = {
144         { .id = PROCESS_GROUP_ATTR_PID_LIST,            .type = SYSCOMMON_RESMAN_DATA_TYPE_ARRAY,       .name = "PROCESS_GROUP_ATTR_PID_LIST",                  .unit = "",             .desc = "Process-group PID(Process ID) list",   .array_type = SYSCOMMON_RESMAN_DATA_TYPE_INT, },
145         { .id = PROCESS_GROUP_ATTR_NAME_LIST,           .type = SYSCOMMON_RESMAN_DATA_TYPE_ARRAY,       .name = "PROCESS_GROUP_ATTR_NAME_LIST",                 .unit = "",             .desc = "Process-group name list",              .array_type = SYSCOMMON_RESMAN_DATA_TYPE_STRING, },
146         { .id = PROCESS_GROUP_ATTR_CPU_UTIL,            .type = SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE,      .name = "PROCESS_GROUP_ATTR_CPU_UTIL",                  .unit = "%",            .desc = "Process-group CPU utilization", },
147         { .id = PROCESS_GROUP_ATTR_DISK_READ_PER_SEC,   .type = SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE,      .name = "PROCESS_GROUP_ATTR_DISK_READ_PER_SEC",         .unit = "kB/s",         .desc = "Process-group disk read per second", },
148         { .id = PROCESS_GROUP_ATTR_DISK_WRITE_PER_SEC,  .type = SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE,      .name = "PROCESS_GROUP_ATTR_DISK_WRITE_PER_SEC",        .unit = "kB/s",         .desc = "Process-group disk write per second", },
149         { .id = PROCESS_GROUP_ATTR_MEM_VIRT,            .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "PROCESS_GROUP_ATTR_MEM_VIRT",                  .unit = "kB",           .desc = "Process-group VIRT memory size", },
150         { .id = PROCESS_GROUP_ATTR_MEM_RSS,             .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "PROCESS_GROUP_ATTR_MEM_RSS",                   .unit = "kB",           .desc = "Process-group RSS(Resident Set Size) memory size", },
151         { .id = PROCESS_GROUP_ATTR_MEM_PSS,             .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "PROCESS_GROUP_ATTR_MEM_PSS",                   .unit = "kB",           .desc = "Process-group PSS(Propotional Set Size) memory size", },
152         { .id = PROCESS_GROUP_ATTR_MEM_SWAP,            .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "PROCESS_GROUP_ATTR_MEM_SWAP",                  .unit = "kB",           .desc = "Process-group Swap memory size", },
153         { .id = PROCESS_GROUP_ATTR_MEM_SWAP_PSS,        .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "PROCESS_GROUP_ATTR_MEM_SWAP_PSS",              .unit = "kB",           .desc = "Process-group Swap PSS(Propotional Set Size) memory size", },
154         { .id = PROCESS_GROUP_ATTR_MEM_GPU,             .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "PROCESS_GROUP_ATTR_MEM_GPU",                   .unit = "kB",           .desc = "Process-group GPU memory size", },
155 };
156
157 struct syscommon_resman_resource_attr_data disk_attrs[] = {
158         { .id = DISK_ATTR_NAME,                         .type = SYSCOMMON_RESMAN_DATA_TYPE_STRING,      .name = "DISK_ATTR_NAME",                               .unit = "",             .desc = "Disk device name", },
159         { .id = DISK_ATTR_READ_PER_SEC,                 .type = SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE,      .name = "DISK_ATTR_READ_PER_SEC",                       .unit = "kB/s",         .desc = "Disk read per second", },
160         { .id = DISK_ATTR_WRITE_PER_SEC,                .type = SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE,      .name = "DISK_ATTR_WRITE_PER_SEC",                      .unit = "kB/s",         .desc = "Disk write per second", },
161         { .id = DISK_ATTR_READ_TOTAL,                   .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "DISK_ATTR_READ_TOTAL",                         .unit = "kB",           .desc = "Disk read total size", },
162         { .id = DISK_ATTR_WRITE_TOTAL,                  .type = SYSCOMMON_RESMAN_DATA_TYPE_UINT64,      .name = "DISK_ATTR_WRITE_TOTAL",                        .unit = "kB",           .desc = "Disk write total size", },
163 };
164
165 struct syscommon_resman_resource_attr_data network_attrs[] = {
166         { .id = NETWORK_ATTR_NAME,                      .type = SYSCOMMON_RESMAN_DATA_TYPE_STRING,      .name = "NETWORK_ATTR_NAME",                            .unit = "",             .desc = "Network device name", },
167 };
168
169 struct syscommon_resman_resource_data {
170         int mon_id;
171         int res_index;
172         int res_id;
173         u_int64_t mask;
174
175         /* Copy data from g_resource_type */
176         int type;
177         u_int64_t ctrl_id;
178         int ctrl_val;
179         int num_attrs;
180         struct syscommon_resman_resource_attr_data attrs[MAX_ATTR];
181 };
182
183 struct syscommon_resman_resource_monitor_data {
184         unsigned int pid;
185         unsigned int ppid;
186         int secs;
187         int max;
188
189         int mon_id;
190         int num_res;
191         struct syscommon_resman_resource_data res[MAX_RESOURCE];
192 } g_data;
193
194 struct __resource_type {
195         int type;
196         u_int64_t ctrl_id;
197         int ctrl_val;
198         int num_attrs;
199         struct syscommon_resman_resource_attr_data *attrs;
200
201         int res_count;
202 } g_resource_type[] = {
203         {
204                 .type           = RESOURCE_TYPE_SYSTEM,
205                 .ctrl_id        = 0,
206                 .attrs          = system_attrs,
207                 .num_attrs      = ARRAY_SIZE(system_attrs),
208         }, {
209                 .type           = RESOURCE_TYPE_MEMORY,
210                 .ctrl_id        = 0,
211                 .attrs          = memory_attrs,
212                 .num_attrs      = ARRAY_SIZE(memory_attrs),
213         }, {
214                 .type           = RESOURCE_TYPE_DISPLAY,
215                 .ctrl_id        = DISPLAY_CTRL_DEVICE_ID,
216                 .attrs          = display_attrs,
217                 .num_attrs      = ARRAY_SIZE(display_attrs),
218         }, {
219                 .type           = RESOURCE_TYPE_BATTERY,
220                 .ctrl_id        = 0,
221                 .attrs          = battery_attrs,
222                 .num_attrs      = ARRAY_SIZE(battery_attrs),
223         }, {
224                 .type           = RESOURCE_TYPE_CPU,
225                 .ctrl_id        = CPU_CTRL_CLUSTER_ID,
226                 .attrs          = cpu_attrs,
227                 .num_attrs      = ARRAY_SIZE(cpu_attrs),
228         }, {
229                 .type           = RESOURCE_TYPE_BUS,
230                 .ctrl_id        = BUS_CTRL_DEVICE_ID,
231                 .attrs          = bus_attrs,
232                 .num_attrs      = ARRAY_SIZE(bus_attrs),
233         }, {
234                 .type           = RESOURCE_TYPE_GPU,
235                 .ctrl_id        = GPU_CTRL_DEVICE_ID,
236                 .attrs          = gpu_attrs,
237                 .num_attrs      = ARRAY_SIZE(gpu_attrs),
238         }, {
239                 .type           = RESOURCE_TYPE_DISK,
240                 .ctrl_id        = DISK_CTRL_DEVICE_ID,
241                 .attrs          = disk_attrs,
242                 .num_attrs      = ARRAY_SIZE(disk_attrs),
243         }, {
244                 .type           = RESOURCE_TYPE_NETWORK,
245                 .ctrl_id        = NETWORK_CTRL_DEVICE_ID,
246                 .attrs          = network_attrs,
247                 .num_attrs      = ARRAY_SIZE(network_attrs),
248         }, {
249                 .type           = RESOURCE_TYPE_PROCESS,
250                 .ctrl_id        = PROCESS_CTRL_TGID,
251                 .attrs          = process_attrs,
252                 .num_attrs      = ARRAY_SIZE(process_attrs),
253                 .res_count      = 1,
254         }, {
255                 .type           = RESOURCE_TYPE_PROCESS_GROUP,
256                 .ctrl_id        = PROCESS_GROUP_CTRL_ROOT_PID,
257                 .attrs          = process_group_attrs,
258                 .num_attrs      = ARRAY_SIZE(process_group_attrs),
259                 .res_count      = 1,
260         },
261 };
262
263 static inline void create_resource_and_set_attrs(struct syscommon_resman_resource_data *res, int ctrl_val)
264 {
265         int i, ret;
266         bool supported;
267
268         if (!res)
269                 return;
270
271         res->res_id = pass_resource_monitor_create_resource(res->mon_id, res->type);
272
273         if (res->ctrl_id)
274                 pass_resource_monitor_set_resource_ctrl(
275                                 res->mon_id, res->res_id, res->ctrl_id, ctrl_val);
276
277         for (i = 0; i < res->num_attrs; i++) {
278                 ret = pass_resource_monitor_is_resource_attr_supported(
279                                 res->mon_id, res->res_id, res->attrs[i].id,
280                                 &supported);
281                 if (ret < 0)
282                         continue;
283
284                 if (supported)
285                         res->mask |= res->attrs[i].id;
286         }
287
288         pass_resource_monitor_set_resource_attr(res->mon_id, res->res_id, res->mask);
289 }
290
291 static inline void unset_attrs_and_delete_resource(struct syscommon_resman_resource_data *res)
292 {
293         if (!res)
294                 return;
295
296         pass_resource_monitor_unset_resource_attr(res->mon_id, res->res_id, res->mask);
297         pass_resource_monitor_delete_resource(res->mon_id, res->res_id);
298 }
299
300 static inline int syscommon_resman_get_resource_attr_array_value(struct syscommon_resman_resource_data *res, int idx)
301 {
302         int i;
303         int ret = 0;
304         int length;
305         double *array = NULL;
306         char buf[BUFF_MAX + 1];
307         char temp[BUFF_MAX];
308
309         if (!res)
310                 return -1;
311
312         switch (res->attrs[idx].array_type) {
313         case SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE:
314                 ret = pass_resource_monitor_get_array_double(
315                                 res->mon_id, res->res_id,
316                                 res->attrs[idx].id, &array, &length);
317
318                 /*
319                  * Since each array item is represented with %2.2f, they
320                  * occupy 4bytes each at least, for instance, x.xx. So,
321                  * if length is larger than BUFF_MAX/4, it will obviously
322                  * be failed to store in 'buf' and there is no need to proceed.
323                  */
324                 if (ret < 0 || length < 0 || length > (BUFF_MAX / 4))
325                         break;
326
327                 memset(buf, 0, BUFF_MAX + 1);
328                 for (i = 0; i < length; i++) {
329                         snprintf(temp, BUFF_MAX, "%2.2f ", array[i]);
330                         if (strlen(buf) + strlen(temp) >= BUFF_MAX)
331                                 break;
332
333                         strncat(buf, temp, BUFF_MAX);
334                 }
335
336                 printf("%40s | %-5s | %s", buf, res->attrs[idx].unit, res->attrs[idx].desc);
337
338                 free(array);
339                 break;
340         case SYSCOMMON_RESMAN_DATA_TYPE_INT:
341         case SYSCOMMON_RESMAN_DATA_TYPE_INT64:
342         case SYSCOMMON_RESMAN_DATA_TYPE_UINT:
343         case SYSCOMMON_RESMAN_DATA_TYPE_UINT64:
344         case SYSCOMMON_RESMAN_DATA_TYPE_STRING:
345                 printf("%40s | %-5s | %s", "Not Implemented",
346                                 res->attrs[idx].unit, res->attrs[idx].desc);
347                 break;
348         default:
349                 break;
350         }
351
352         return ret;
353 }
354
355 static inline void syscommon_resman_get_resource_attr_value(struct syscommon_resman_resource_data *res, int i)
356 {
357         bool supported;
358         int ret = 0;
359
360         ret = pass_resource_monitor_is_resource_attr_supported(
361                                                 res->mon_id, res->res_id,
362                                                 res->attrs[i].id,
363                                                 &supported);
364         if(ret < 0) {
365                 printf("%40s | %-5s | %s", "Not Implemented",
366                                 res->attrs[i].unit, res->attrs[i].desc);
367                 return;
368         }
369
370         if (!supported) {
371                 printf("%40s | %-5s | %s", "Not Supported",
372                                 res->attrs[i].unit, res->attrs[i].desc);
373                 return;
374         }
375
376         switch (res->attrs[i].type) {
377         case SYSCOMMON_RESMAN_DATA_TYPE_INT:
378                 ret = pass_resource_monitor_get_value_int(
379                                                 res->mon_id, res->res_id,
380                                                 res->attrs[i].id,
381                                                 &(res->attrs[i].value_int32));
382                 if (ret < 0) break;
383
384                 printf("%40d | %-5s | %s",
385                                 res->attrs[i].value_int32,
386                                 res->attrs[i].unit, res->attrs[i].desc);
387                 break;
388         case SYSCOMMON_RESMAN_DATA_TYPE_INT64:
389                 ret = pass_resource_monitor_get_value_int64(
390                                                 res->mon_id, res->res_id,
391                                                 res->attrs[i].id,
392                                                 &(res->attrs[i].value_int64));
393                 if (ret < 0) break;
394
395                 printf("%40"PRId64" | %-5s | %s",
396                                 res->attrs[i].value_int64,
397                                 res->attrs[i].unit, res->attrs[i].desc);
398                 break;
399         case SYSCOMMON_RESMAN_DATA_TYPE_UINT:
400                 ret = pass_resource_monitor_get_value_uint(
401                                                 res->mon_id, res->res_id,
402                                                 res->attrs[i].id,
403                                                 &(res->attrs[i].value_uint32));
404                 if (ret < 0) break;
405
406                 printf("%40u | %-5s | %s",
407                                 res->attrs[i].value_uint32,
408                                 res->attrs[i].unit, res->attrs[i].desc);
409                 break;
410         case SYSCOMMON_RESMAN_DATA_TYPE_UINT64:
411                 ret = pass_resource_monitor_get_value_uint64(
412                                                 res->mon_id, res->res_id,
413                                                 res->attrs[i].id,
414                                                 &(res->attrs[i].value_uint64));
415                 if (ret < 0) break;
416
417                 printf("%40"PRId64" | %-5s | %s",
418                                 res->attrs[i].value_uint64,
419                                 res->attrs[i].unit, res->attrs[i].desc);
420                 break;
421         case SYSCOMMON_RESMAN_DATA_TYPE_DOUBLE:
422                 ret = pass_resource_monitor_get_value_double(
423                                                 res->mon_id, res->res_id,
424                                                 res->attrs[i].id,
425                                                 &(res->attrs[i].value_double));
426                 if (ret < 0) break;
427
428                 printf("%40.2f | %-5s | %s",
429                                 res->attrs[i].value_double,
430                                 res->attrs[i].unit, res->attrs[i].desc);
431                 break;
432         case SYSCOMMON_RESMAN_DATA_TYPE_STRING:
433                 ret = pass_resource_monitor_get_value_string(
434                                                 res->mon_id, res->res_id,
435                                                 res->attrs[i].id,
436                                                 &res->attrs[i].value_string);
437                 if (ret < 0) break;
438
439                 printf("%40s | %-5s | %s",
440                                 res->attrs[i].value_string,
441                                 res->attrs[i].unit, res->attrs[i].desc);
442                 g_free(res->attrs[i].value_string);
443                 break;
444         case SYSCOMMON_RESMAN_DATA_TYPE_ARRAY:
445                 ret = syscommon_resman_get_resource_attr_array_value(res, i);
446                 break;
447         case SYSCOMMON_RESMAN_DATA_TYPE_PTR:
448         case SYSCOMMON_RESMAN_DATA_TYPE_BOOLEAN:
449                 printf("(%40s) | %-5s | %s", "Not Implemented",
450                                 res->attrs[i].unit, res->attrs[i].desc);
451                 break;
452         default:
453                 printf("(%40s)", "Unknown Data Type");
454                 break;
455         }
456
457         if (ret < 0)
458                 printf("%40s | %-5s | %s", "Failed to Get Value",
459                                 res->attrs[i].unit, res->attrs[i].desc);
460 }
461
462 static void resource_monitor_exit(int signal)
463 {
464         int i;
465
466         for (i = 0; i < g_data.num_res; i++)
467                 unset_attrs_and_delete_resource(&g_data.res[i]);
468
469         pass_resource_monitor_exit(g_data.mon_id);
470
471         printf("Exit resource-monitor\n");
472         exit(0);
473 }
474
475 static int resource_monitor_init(void)
476 {
477         int id, i, j, count, ret;
478
479         /* 1. Initialize resource-monitor */
480         id = pass_resource_monitor_init();
481         if (id < 0)
482                 return id;
483
484         g_data.mon_id = id;
485
486         /* 2. Get resource count */
487         for (i = 0; i < ARRAY_SIZE(g_resource_type); i++) {
488                 if (g_resource_type[i].res_count) {
489                         count = g_resource_type[i].res_count;
490                 } else {
491                         ret =  pass_resource_monitor_get_resource_count(id, g_resource_type[i].type, &count);
492                         if (ret < 0)
493                                 continue;
494                 }
495
496                 if (count < 0)
497                         continue;
498
499                 if (g_resource_type[i].ctrl_val < 0)
500                         continue;
501
502                 for (j = 0; j < count; j++) {
503                         struct syscommon_resman_resource_data *res = &g_data.res[g_data.num_res++];
504
505                         res->mon_id = g_data.mon_id;
506                         res->res_index = j;
507                         res->type = g_resource_type[i].type;
508                         res->ctrl_id = g_resource_type[i].ctrl_id;
509                         res->num_attrs = g_resource_type[i].num_attrs;
510                         memcpy(res->attrs, g_resource_type[i].attrs, sizeof(struct syscommon_resman_resource_attr_data) * res->num_attrs);
511                         res->ctrl_val = g_resource_type[i].ctrl_val;
512                 }
513         }
514
515         for (i = 0; i < g_data.num_res; i++) {
516                 struct syscommon_resman_resource_data *res = &g_data.res[i];
517
518                 if (res->ctrl_val > 0)
519                         create_resource_and_set_attrs(res, res->ctrl_val);
520                 else
521                         create_resource_and_set_attrs(res, res->res_index);
522         }
523
524         return 0;
525 }
526
527 static void resource_monitor(void)
528 {
529         int id = g_data.mon_id;
530         int count = 0;
531         int i, j;
532
533         hal_foo_get_backend();
534
535         while (1) {
536                 if (g_data.max != -1 && g_data.max <= count++)
537                         break;
538
539                 /* 4. Update resource attribute value */
540                 pass_resource_monitor_update(id);
541
542                 printf("-------------------------------------------------------------------------------------------------------------------------------\n");
543                 printf("%2s:%2s| %40s | %40s | %-5s | %s\n",
544                                 "", "", "Resource Attribute Name", "Resource Attribute Value", "Unit", "Resource Attribute Description");
545                 printf("-------------------------------------------------------------------------------------------------------------------------------\n");
546
547                 for (i = 0; i < g_data.num_res; i++) {
548                         struct syscommon_resman_resource_data *res = &g_data.res[i];
549
550                         for (j = 0; j < res->num_attrs; j++) {
551                                 printf("%2d:%2d| %40s | ", i, j, res->attrs[j].name);
552                                 syscommon_resman_get_resource_attr_value(res, j);
553                                 printf("\n");
554                         }
555                         printf("\n");
556                 }
557                 sleep(g_data.secs);
558
559                 printf("hal_foo_start() : %d\n", hal_foo_start());
560                 printf("hal_foo_stop()  : %d\n", hal_foo_stop());
561         }
562
563         hal_foo_put_backend();
564
565         resource_monitor_exit(0);
566 }
567
568 static void usage()
569 {
570         printf("Usage:\n");
571         printf("    resource-moniotr -h | -d secs -n max -p pid -g ppid | --pid pid --ppid ppid\n");
572 }
573
574 int main(int argc, char *argv[])
575 {
576         int i;
577         int opt = 1;
578
579         /* Initialize default value and parse command line */
580         g_data.secs = 1;        /* default sampling rate is 1 second. */
581         g_data.max = -1;        /* default count is infinite. */
582         g_data.pid = -1;
583         g_data.ppid = -1;
584
585         while (opt < argc) {
586                 if (!strncmp(argv[opt], "--pid", 5)) {
587                         g_data.pid = atoi(argv[opt + 1]);
588                 } else if (!strncmp(argv[opt], "--ppid", 6)) {
589                         g_data.ppid = atoi(argv[opt + 1]);
590                 } else if (!strncmp(argv[opt], "-", 1)) {
591                         for (i = 1; *(argv[opt] + i); i++) {
592                                 int input;
593
594                                 switch (*(argv[opt] + i)) {
595                                 case 'd':
596                                         input = atoi(argv[opt + 1]);
597                                         if (input < 0 || input >= INT_MAX)
598                                                 break;
599                                         g_data.secs = input;
600                                         break;
601                                 case 'n':
602                                         input = atoi(argv[opt + 1]);
603                                         if (input < 0 || input >= INT_MAX)
604                                                 break;
605                                         g_data.max = input;
606                                         break;
607                                 case 'p':
608                                         g_data.pid = atoi(argv[opt + 1]);
609                                         break;
610                                 case 'g':
611                                         g_data.ppid = atoi(argv[opt + 1]);
612                                         break;
613                                 case 'h':
614                                         usage();
615                                         exit(0);
616                                 default:
617                                         usage();
618                                 }
619                         }
620                 }
621                 opt++;
622         }
623
624         for (i = 0; i < ARRAY_SIZE(g_resource_type); i++) {
625                 if (g_resource_type[i].type == RESOURCE_TYPE_PROCESS)
626                         g_resource_type[i].ctrl_val = g_data.pid;
627
628                 if (g_resource_type[i].type == RESOURCE_TYPE_PROCESS_GROUP)
629                         g_resource_type[i].ctrl_val = g_data.ppid;
630         }
631
632         /* Register signal handler for freeing resources */
633         signal(SIGINT, resource_monitor_exit);
634
635         /* Initialize available resources and resource attributes */
636         resource_monitor_init();
637
638         /* Start resource monitor */
639         resource_monitor();
640
641         return 0;
642 }