Unify cmutex class
[platform/core/api/sensor.git] / src / shared / cmutex.cpp
1 /*
2  * sensord
3  *
4  * Copyright (c) 2013 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
20 #include <pthread.h>
21 #include <stdio.h>
22 #include <sys/time.h>
23 #include <cmutex.h>
24 #include <sensor-log-private.h>
25
26 using namespace sensor;
27
28 cmutex::cmutex()
29 {
30         pthread_mutexattr_t mutex_attr;
31         pthread_mutexattr_init(&mutex_attr);
32         pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_RECURSIVE);
33         pthread_mutex_init(&m_mutex, &mutex_attr);
34         pthread_mutexattr_destroy(&mutex_attr);
35 }
36
37 cmutex::~cmutex()
38 {
39         pthread_mutex_destroy(&m_mutex);
40 }
41
42 void cmutex::lock(void)
43 {
44 #ifdef _LOCK_DEBUG
45         lock("mutex", __MODULE__, __func__, __LINE__);
46 #else
47         lock_impl();
48 #endif
49 }
50
51 void cmutex::lock(const char* expr, const char *module, const char *func, int line)
52 {
53         int ret = 0;
54         char m_curent_info[OWNER_INFO_LEN];
55         struct timeval sv;
56         unsigned long long lock_waiting_start_time = 0;
57         unsigned long long lock_acquired_time = 0;
58         unsigned long long waiting_time = 0;
59
60         snprintf(m_curent_info, OWNER_INFO_LEN, "%s:%s(%d)", module, func, line);
61
62         ret = try_lock_impl();
63
64         if (ret == 0) {
65                 pthread_mutex_lock(&m_mutex);
66                 snprintf(m_owner_info, OWNER_INFO_LEN, "%s", m_curent_info);
67                 pthread_mutex_unlock(&m_mutex);
68                 return;
69         }
70
71         gettimeofday(&sv, NULL);
72         lock_waiting_start_time = MICROSECONDS(sv);
73
74         pthread_mutex_lock(&m_mutex);
75         _I("%s is waiting for getting %s(%p) owned in %s",
76                 m_curent_info, expr, this, m_owner_info);
77         pthread_mutex_unlock(&m_mutex);
78
79         lock_impl();
80
81         gettimeofday(&sv, NULL);
82         lock_acquired_time = MICROSECONDS(sv);
83
84         waiting_time = lock_acquired_time - lock_waiting_start_time;
85
86         pthread_mutex_lock(&m_mutex);
87         _I("%s acquires lock after waiting %lluus, %s(%p) was previously owned in %s",
88                 m_curent_info, waiting_time, expr, this, m_owner_info);
89         snprintf(m_owner_info, OWNER_INFO_LEN, "%s", m_curent_info);
90         pthread_mutex_unlock(&m_mutex);
91 }
92
93 void cmutex::unlock(void)
94 {
95         unlock_impl();
96 }
97
98 int cmutex::try_lock(void)
99 {
100         return try_lock_impl();
101 }
102
103 int cmutex::lock_impl(void)
104 {
105         return pthread_mutex_lock(&m_mutex);
106 }
107
108 int cmutex::try_lock_impl(void)
109 {
110         return pthread_mutex_trylock(&m_mutex);
111 }
112
113 int cmutex::unlock_impl(void)
114 {
115         return pthread_mutex_unlock(&m_mutex);
116 }
117
118 Autolock::Autolock(cmutex &m, const char* expr, const char *module, const char *func, int line)
119 : m_lock(m)
120 {
121         m_lock.lock(expr, module, func, line);
122 }
123
124 Autolock::Autolock(cmutex &m)
125 : m_lock(m)
126 {
127         m_lock.lock();
128 }
129
130 Autolock::~Autolock()
131 {
132         m_lock.unlock();
133 }