process: add missing license
[apps/native/ttsd-worker-task.git] / src / process.c
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Flora License, Version 1.1 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <string.h>
18 #include <stdlib.h>
19 #include <unistd.h>
20
21 #include "process.h"
22 #include "clock.h"
23 #include "sys-stats.h"
24 #include "err-check.h"
25 #include "procfs.h"
26 #include "appinfo-provider.h"
27 #include "json-schema-defs.h"
28
29 static struct sys_stats sys;
30 static int pagesize;
31 static float timescale;
32
33 int process_get_memory_usage(struct process *proc, int *usage)
34 {
35         ON_NULL_RETURN_VAL(proc, -1);
36         ON_NULL_RETURN_VAL(usage, -1);
37
38         *usage = proc->memory_used;
39         return 0;
40 }
41
42 int process_get_cpu_usage(struct process *proc, unsigned long long *usage)
43 {
44         ON_NULL_RETURN_VAL(proc, -1);
45         ON_NULL_RETURN_VAL(usage, -1);
46
47         *usage = proc->frame_ticks_used;
48         return 0;
49 }
50
51 int process_update(struct process *proc)
52 {
53         struct procfs_process_stat info;
54         unsigned long long ticks;
55
56         if (procfs_read_process_stat(proc->pid, &info) != 0) {
57                 return -1;
58         }
59         ticks = info.stime + info.utime;
60         proc->frame_ticks_used = ticks - proc->total_ticks_used;
61         proc->total_ticks_used = ticks;
62         proc->memory_used = info.rss * pagesize / 1024;
63         float now = clock_monotonic_get();
64         proc->frame_time_inverted = 1.0f / (now - proc->update_time);
65         proc->update_time = now;
66
67         return 0;
68 }
69
70 void process_init_process(int pid, struct process *proc)
71 {
72         memset(proc, 0x0, sizeof(struct process));
73         proc->pid = pid;
74 }
75
76 int process_get_pid(const struct process *proc)
77 {
78         ON_NULL_RETURN_VAL(proc, -1);
79         return proc->pid;
80 }
81
82 const char *process_get_appid(struct process *proc)
83 {
84         ON_NULL_RETURN_VAL(proc, NULL);
85
86         if (!proc->appid) {
87                 proc->appid = app_info_provider_find_app_id(proc->pid);
88         }
89         return proc->appid;
90 }
91
92 const char *process_get_exe(struct process *proc)
93 {
94         ON_NULL_RETURN_VAL(proc, NULL);
95
96         if (!proc->exe) {
97                 if (procfs_read_process_exe(proc->pid, &proc->exe) != 0)
98                         return NULL;
99         }
100         return proc->exe;
101 }
102
103 void process_shutdown(struct process *proc)
104 {
105         if (!proc) return;
106         free(proc->appid);
107         free(proc->exe);
108         memset(proc, 0x0, sizeof(struct process));
109 }
110
111 void process_move(struct process *dst, struct process *src)
112 {
113         memcpy(dst, src, sizeof(struct process));
114         src->appid = NULL;
115         src->exe = NULL;
116 }
117
118 int process_get_cpu_usage_percentage(struct process *proc, float *usage)
119 {
120         ON_NULL_RETURN_VAL(proc, -1);
121         ON_NULL_RETURN_VAL(usage, -1);
122
123         *usage = (float)proc->frame_ticks_used * proc->frame_time_inverted * timescale;
124         return 0;
125 }
126
127 int process_get_memory_usage_percentage(struct process *proc, float *usage)
128 {
129         ON_NULL_RETURN_VAL(proc, -1);
130         ON_NULL_RETURN_VAL(usage, -1);
131
132         *usage = (float)proc->memory_used / sys.total_memory;
133         return 0;
134 }
135
136 int process_init()
137 {
138         if (sys_stats_update(&sys) != 0) {
139                 ERR("stats_update_system_stats failed.");
140                 return -1;
141         }
142         timescale = 1.0f / (float)sysconf(_SC_CLK_TCK);
143         pagesize = getpagesize();
144         return 0;
145 }
146
147 void process_serialize(struct process *proc, JsonBuilder *builder)
148 {
149         ON_NULL_RETURN(proc);
150
151         float tmp;
152         json_builder_begin_object(builder);
153
154         json_builder_set_member_name(builder, SCHEMA_RESULT_APP_ID);
155         json_builder_add_string_value(builder, process_get_appid(proc));
156         json_builder_set_member_name(builder, SCHEMA_RESULT_EXE);
157         json_builder_add_string_value(builder, process_get_exe(proc));
158         json_builder_set_member_name(builder, SCHEMA_RESULT_PID);
159         json_builder_add_int_value(builder, process_get_pid(proc));
160         json_builder_set_member_name(builder, SCHEMA_RESULT_CPU);
161         process_get_cpu_usage_percentage(proc, &tmp);
162         json_builder_add_double_value(builder, tmp);
163         json_builder_set_member_name(builder, SCHEMA_RESULT_MEMORY);
164         process_get_memory_usage_percentage(proc, &tmp);
165         json_builder_add_double_value(builder, tmp);
166
167         json_builder_end_object(builder);
168 }