132e224369e5e75ab4b07ffa999f9ff8c6d4b907
[platform/core/system/pass.git] / src / monitor / monitor-thread.c
1 /*
2  * PASS (Power Aware System Service)
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 <util/log.h>
20 #include <monitor/monitor.h>
21
22 thread_local int empty_counter = 0;
23
24 static int monitor_func(void *data, void **result)
25 {
26         struct monitor *monitor = data;
27         struct monitor_command *cmd;
28
29 new_command:
30         if (dequeue(monitor->q, (void *)&cmd) < 0) {
31                 if (empty_counter++ > MONITOR_POLLING_DURATION) {
32                         empty_counter = 0;
33                         mtx_lock(&monitor->lock);
34                         cnd_wait(&monitor->signal, &monitor->lock);
35                         mtx_unlock(&monitor->lock);
36                         goto new_command;
37                 }
38                 return THREAD_RETURN_CONTINUE;
39         }
40
41         syscommon_resman_update_resource_attrs(cmd->resource);
42
43         cmd->done = true;
44         smp_wmb();
45
46         cnd_signal(&cmd->signal);
47
48         return THREAD_RETURN_CONTINUE;
49 }
50
51 int monitor_thread_init(struct monitor *monitor)
52 {
53         struct thread *thread;
54         struct queue *queue;
55         int ret;
56
57         ret = create_queue(&queue, free);
58         if (ret < 0) {
59                 _E("failed to create command queue\n");
60                 return ret;
61         }
62
63         /* q should be assigned before create daemon thread */
64         monitor->q = queue;
65         monitor->priv = NULL;
66         mtx_init(&monitor->lock, mtx_plain);
67         cnd_init(&monitor->signal);
68
69         ret = create_daemon_thread(&thread, monitor_func, monitor);
70         if (ret < 0) {
71                 _E("failed to create monitor thread\n");
72                 cnd_destroy(&monitor->signal);
73                 mtx_destroy(&monitor->lock);
74                 destroy_queue(queue);
75                 monitor->q = NULL;
76                 return ret;
77         }
78
79         monitor->thread = thread;
80
81         return 0;
82 }
83
84 void monitor_thread_exit(struct monitor *monitor)
85 {
86         if (monitor->thread) {
87                 cnd_signal(&monitor->signal);
88                 destroy_thread(monitor->thread);
89                 monitor->thread = NULL;
90         }
91
92         cnd_destroy(&monitor->signal);
93         mtx_destroy(&monitor->lock);
94
95         if (monitor->q) {
96                 destroy_queue(monitor->q);
97                 monitor->q = NULL;
98         }
99 }