1 /**
2  * @file lv_pthread.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 #include "lv_os.h"
10 
11 #if LV_USE_OS == LV_OS_PTHREAD
12 
13 #include <errno.h>
14 #include "../misc/lv_log.h"
15 
16 /*********************
17  *      DEFINES
18  *********************/
19 
20 /**********************
21  *      TYPEDEFS
22  **********************/
23 
24 /**********************
25  *  STATIC PROTOTYPES
26  **********************/
27 static void * generic_callback(void * user_data);
28 
29 /**********************
30  *  STATIC VARIABLES
31  **********************/
32 
33 /**********************
34  *      MACROS
35  **********************/
36 
37 /**********************
38  *   GLOBAL FUNCTIONS
39  **********************/
40 
lv_thread_init(lv_thread_t * thread,const char * const name,lv_thread_prio_t prio,void (* callback)(void *),size_t stack_size,void * user_data)41 lv_result_t lv_thread_init(lv_thread_t * thread, const char * const name, lv_thread_prio_t prio,
42                            void (*callback)(void *), size_t stack_size,
43                            void * user_data)
44 {
45     LV_UNUSED(name);
46     LV_UNUSED(prio);
47     pthread_attr_t attr;
48     pthread_attr_init(&attr);
49     pthread_attr_setstacksize(&attr, stack_size);
50     thread->callback = callback;
51     thread->user_data = user_data;
52     pthread_create(&thread->thread, &attr, generic_callback, thread);
53     pthread_attr_destroy(&attr);
54     return LV_RESULT_OK;
55 }
56 
lv_thread_delete(lv_thread_t * thread)57 lv_result_t lv_thread_delete(lv_thread_t * thread)
58 {
59     int ret = pthread_join(thread->thread, NULL);
60     if(ret != 0) {
61         LV_LOG_WARN("Error: %d", ret);
62         return LV_RESULT_INVALID;
63     }
64 
65     return LV_RESULT_OK;
66 }
67 
lv_mutex_init(lv_mutex_t * mutex)68 lv_result_t lv_mutex_init(lv_mutex_t * mutex)
69 {
70     pthread_mutexattr_t attr;
71 
72     pthread_mutexattr_init(&attr);
73     pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
74     int ret = pthread_mutex_init(mutex, &attr);
75     pthread_mutexattr_destroy(&attr);
76 
77     if(ret) {
78         LV_LOG_WARN("Error: %d", ret);
79         return LV_RESULT_INVALID;
80     }
81     else {
82         return LV_RESULT_OK;
83     }
84 }
85 
lv_mutex_lock(lv_mutex_t * mutex)86 lv_result_t lv_mutex_lock(lv_mutex_t * mutex)
87 {
88     int ret = pthread_mutex_lock(mutex);
89     if(ret) {
90         LV_LOG_WARN("Error: %d", ret);
91         return LV_RESULT_INVALID;
92     }
93     else {
94         return LV_RESULT_OK;
95     }
96 }
97 
lv_mutex_lock_isr(lv_mutex_t * mutex)98 lv_result_t lv_mutex_lock_isr(lv_mutex_t * mutex)
99 {
100     int ret = pthread_mutex_lock(mutex);
101     if(ret) {
102         LV_LOG_WARN("Error: %d", ret);
103         return LV_RESULT_INVALID;
104     }
105     else {
106         return LV_RESULT_OK;
107     }
108 }
109 
lv_mutex_unlock(lv_mutex_t * mutex)110 lv_result_t lv_mutex_unlock(lv_mutex_t * mutex)
111 {
112     int ret = pthread_mutex_unlock(mutex);
113     if(ret) {
114         LV_LOG_WARN("Error: %d", ret);
115         return LV_RESULT_INVALID;
116     }
117     else {
118         return LV_RESULT_OK;
119     }
120 }
121 
lv_mutex_delete(lv_mutex_t * mutex)122 lv_result_t lv_mutex_delete(lv_mutex_t * mutex)
123 {
124     pthread_mutex_destroy(mutex);
125     return LV_RESULT_OK;
126 }
127 
lv_thread_sync_init(lv_thread_sync_t * sync)128 lv_result_t lv_thread_sync_init(lv_thread_sync_t * sync)
129 {
130     pthread_mutex_init(&sync->mutex, 0);
131     pthread_cond_init(&sync->cond, 0);
132     sync->v = false;
133     return LV_RESULT_OK;
134 }
135 
lv_thread_sync_wait(lv_thread_sync_t * sync)136 lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync)
137 {
138     pthread_mutex_lock(&sync->mutex);
139     while(!sync->v) {
140         pthread_cond_wait(&sync->cond, &sync->mutex);
141     }
142     sync->v = false;
143     pthread_mutex_unlock(&sync->mutex);
144     return LV_RESULT_OK;
145 }
146 
lv_thread_sync_signal(lv_thread_sync_t * sync)147 lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync)
148 {
149     pthread_mutex_lock(&sync->mutex);
150     sync->v = true;
151     pthread_cond_signal(&sync->cond);
152     pthread_mutex_unlock(&sync->mutex);
153 
154     return LV_RESULT_OK;
155 }
156 
lv_thread_sync_delete(lv_thread_sync_t * sync)157 lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync)
158 {
159     pthread_mutex_destroy(&sync->mutex);
160     pthread_cond_destroy(&sync->cond);
161     return LV_RESULT_OK;
162 }
163 
lv_thread_sync_signal_isr(lv_thread_sync_t * sync)164 lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync)
165 {
166     LV_UNUSED(sync);
167     return LV_RESULT_INVALID;
168 }
169 
170 /**********************
171  *   STATIC FUNCTIONS
172  **********************/
173 
generic_callback(void * user_data)174 static void * generic_callback(void * user_data)
175 {
176     lv_thread_t * thread = user_data;
177     thread->callback(thread->user_data);
178     return NULL;
179 }
180 
181 #endif /*LV_USE_OS == LV_OS_PTHREAD*/
182