xref: /OK3568_Linux_fs/external/camera_engine_rkaiq/rkaiq/xcore/xcam_thread.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * xcam_thread.cpp - Thread
3  *
4  *  Copyright (c) 2014 Intel Corporation
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  * Author: Wind Yuan <feng.yuan@intel.com>
19  */
20 
21 #include "xcam_thread.h"
22 #include "xcam_mutex.h"
23 #include <errno.h>
24 #include <signal.h>
25 
26 namespace XCam {
27 
Thread(const char * name)28 Thread::Thread (const char *name)
29     : _name (NULL)
30     , _thread_id (0)
31     , _started (false)
32     , _stopped (true)
33     , _policy (-1)
34     , _priority (-1)
35 {
36     if (name)
37         _name = strndup (name, XCAM_MAX_STR_SIZE);
38 
39     XCAM_LOG_DEBUG ("Thread(%s) construction", XCAM_STR(_name));
40 }
41 
~Thread()42 Thread::~Thread ()
43 {
44     XCAM_LOG_DEBUG ("Thread(%s) destruction", XCAM_STR(_name));
45 
46     if (_name)
47         xcam_free (_name);
48 }
49 
50 void *
thread_func(void * user_data)51 Thread::thread_func (void *user_data)
52 {
53     Thread *thread = (Thread *)user_data;
54     bool ret = true;
55 
56     {
57         // Make sure running after start
58         SmartLock locker(thread->_mutex);
59         pthread_detach (pthread_self());
60     }
61     ret = thread->started ();
62 
63     sigset_t set;
64 
65     /* Block SIGQUIT and SIGTERM */
66 
67     sigemptyset(&set);
68     sigaddset(&set, SIGQUIT);
69     sigaddset(&set, SIGINT);
70     sigaddset(&set, SIGTERM);
71     pthread_sigmask(SIG_BLOCK, &set, NULL);
72     while (true) {
73         {
74             SmartLock locker(thread->_mutex);
75             if (!thread->_started || ret == false) {
76                 thread->_started = false;
77                 thread->_thread_id = 0;
78                 ret = false;
79                 break;
80             }
81         }
82 
83         ret = thread->loop ();
84     }
85 
86     thread->stopped ();
87 
88     {
89         SmartLock locker(thread->_mutex);
90         thread->_stopped = true;
91     }
92     thread->_exit_cond.broadcast ();
93 
94     return NULL;
95 }
96 
97 bool
started()98 Thread::started ()
99 {
100     XCAM_LOG_DEBUG ("Thread(%s) started", XCAM_STR(_name));
101     return true;
102 }
103 
104 void
stopped()105 Thread::stopped ()
106 {
107     XCAM_LOG_DEBUG ("Thread(%s) stopped", XCAM_STR(_name));
108 }
109 
start()110 bool Thread::start ()
111 {
112     SmartLock locker(_mutex);
113     if (_started)
114         return true;
115 
116     pthread_attr_t attr;
117     size_t stacksize = 0;
118 
119     if (pthread_attr_init(&attr)) {
120         XCAM_ASSERT(0);
121     }
122     if (!pthread_attr_getstacksize(&attr, &stacksize)) {
123         if (stacksize < 2048 * 1024) {
124             stacksize = 2048 * 1024;
125         }
126         pthread_attr_setstacksize(&attr, stacksize);
127     }
128 
129     if (_policy != -1 || _priority != -1) {
130         int ret = -1;
131 
132         if (_policy != -1) {
133             ret = pthread_attr_setschedpolicy(&attr, _policy);
134             if (ret) {
135                 XCAM_LOG_WARNING ("Thread(%s) set sched policy failed.(%d, %s)",
136                         XCAM_STR(_name), ret, strerror(ret));
137             }
138         }
139 
140         if (_policy != -1 && _policy != SCHED_OTHER && _priority != -1) {
141             struct sched_param param;
142             param.sched_priority = _priority;
143             ret = pthread_attr_setschedparam(&attr, &param);
144             if (ret) {
145                 XCAM_LOG_WARNING ("Thread(%s) set sched priority failed.(%d, %s)",
146                         XCAM_STR(_name), ret, strerror(ret));
147             }
148         }
149 
150         ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
151         if (ret) {
152             XCAM_LOG_WARNING ("Thread(%s) set sched inherit failed.(%d, %s)",
153                     XCAM_STR(_name), ret, strerror(ret));
154         }
155     }
156 
157     if (pthread_create(&_thread_id, &attr, (void* (*)(void*))thread_func, this) != 0) {
158         pthread_attr_destroy(&attr);
159         return false;
160     }
161 
162     pthread_attr_destroy(&attr);
163     _started = true;
164     _stopped = false;
165 
166 #ifdef __USE_GNU
167     char thread_name[16];
168     xcam_mem_clear (thread_name);
169     snprintf (thread_name, sizeof (thread_name), "xc:%s", XCAM_STR(_name));
170     int ret = pthread_setname_np (_thread_id, thread_name);
171     if (ret != 0) {
172         XCAM_LOG_WARNING ("Thread(%s) set name to thread_id failed.(%d, %s)", XCAM_STR(_name), ret, strerror(ret));
173     }
174 #endif
175 
176     return true;
177 }
178 
179 bool
emit_stop()180 Thread::emit_stop ()
181 {
182     SmartLock locker(_mutex);
183     _started = false;
184     return true;
185 }
186 
stop()187 bool Thread::stop ()
188 {
189     XCAM_LOG_DEBUG ("stop thread(%s) _started: %d _stopped: %d",
190                     XCAM_STR(_name), _started, _stopped);
191 
192     emit_stop();
193 
194     SmartLock locker(_mutex);
195     while (!_stopped) {
196         _exit_cond.wait(_mutex);
197     }
198 
199     _policy = -1;
200     _priority = -1;
201 
202     return true;
203 }
204 
is_running()205 bool Thread::is_running ()
206 {
207     SmartLock locker(_mutex);
208     return _started;
209 }
210 
211 }
212