source: libcf/trunk/src/cf_thread.c@ 81

Last change on this file since 81 was 81, checked in by cheese, 11 years ago

#1 fix for r80

File size: 5.6 KB
Line 
1/**
2 * @file cf_thread.c
3 * @author myusgun <myusgun@gmail.com>
4 */
5#include "cf_thread.h"
6#include "cf_local.h"
7#include "cf_error.h"
8
9#include <stdlib.h>
10
11#if defined(_WIN32) || defined(_WIN64)
12# include <windows.h>
13# include <process.h>
14# define THREAD_TYPE HANDLE
15# define MUTEX_TYPE HANDLE
16# define THREAD_RETURN unsigned long /**< 스레드 워커 함수 반환 형 */
17# define THREAD_CALL __stdcall
18#else // #if defined(_WIN32) || defined(_WIN64)
19# include <pthread.h>
20# define THREAD_TYPE pthread_t
21# define MUTEX_TYPE pthread_mutex_t
22# define THREAD_RETURN void * /**< 스레드 워커 함수 반환 형 */
23# define THREAD_CALL
24#endif // #if defined(_WIN32) || defined(_WIN64)
25
26#define ASSERT_THREAD(__h) \
27 if (__h == NULL) \
28 return CF_ERROR_THREAD_INVALID_ARGS
29
30#define ASSERT_MUTEX(__h) \
31 if (__h == NULL) \
32 return CF_ERROR_MUTEX_INVALID_ARGS
33
34typedef THREAD_RETURN (THREAD_CALL * THREAD_WORKER) (void *);
35
36static int
37CF_Thread_Local_Close (void * ctx)
38{
39#if defined(_WIN32) || defined(_WIN64)
40 CloseHandle (ctx);
41#else
42 free (ctx);
43#endif
44
45 return CF_OK;
46}
47
48/**
49 * 스레드를 생성
50 *
51 * @return 성공 시, CF_OK; 실패 시, 오류 코드
52 *
53 * @param threadID 스레드 아이디 주소
54 * @param callback 스레드 워커 함수 이름
55 * @param arg 스레드 함수로 전달할 인자
56 *
57 * @remarks
58 * pthread(POSIX Thread)에서 지원되는 스케줄링 정책은 SCHED_OTHER, SCHED_FIFO, SCHED_RR 등이 존재 <br />
59 * 일반적으로 설정되는 스케줄링 정책의 기본값은 SCHED_OTHER이며, 솔라리스 환경에서 SCHED_OTHER는 TS(timesharing) 방식으로 명시되어 있음 <br />
60 * 그러나 개발 단계에서 테스트된 동작은 SCHED_FIFO와 동일하였으며, 때문에 솔라리스 환경에서는 스케줄링 정책을 SCHED_RR로 명시하도록 함 <br />
61 * <br />
62 * 참고 url <br />
63 * - http://kldp.org/node/18841 , "SCHED_OTHER, SCHED_FIFO, SCHED_RR에 대해..." <br />
64 * - http://blog.naver.com/popjunior/80021646476 , "AIX, CPU 모니터링과 튜닝" <br />
65 */
66int
67CF_Thread_Create (CF_Thread * threadID,
68 CF_Thread_Function callback,
69 void * arg)
70{
71 int result = 0;
72
73 THREAD_WORKER f = (THREAD_WORKER) callback;
74
75#if defined(_WIN32) || defined(_WIN64)
76 *threadID = (THREAD_TYPE) CreateThread (NULL, 0, f, arg, 0, NULL);
77 if (*threadID == NULL)
78 return CF_ERROR_THREAD_CREATE;
79#else
80
81 pthread_attr_t * attr = NULL;
82# if defined(_SOLARIS)
83 pthread_attr_t solarisAttr;
84 struct sched_param sched;
85
86 attr = &solarisAttr;
87
88 result = pthread_attr_init (attr);
89 if (result)
90 return CF_ERROR_THREAD_INIT_ATTR;
91
92 result = pthread_attr_setinheritsched (attr, PTHREAD_EXPLICIT_SCHED);
93 if (result)
94 return CF_ERROR_THREAD_SET_INHERIT_SCHED;
95
96 result = pthread_attr_setschedpolicy (attr, SCHED_RR);
97 if (result)
98 return CF_ERROR_THREAD_SET_SCHED_POLICY;
99
100 sched.sched_priority = 1;
101 result = pthread_attr_setschedparam (attr, &sched);
102 if (result)
103 return CF_ERROR_THREAD_SET_SCHED_PARAM;
104# endif // # if defined(_SOLARIS)
105
106 *threadID = (THREAD_TYPE *) calloc (sizeof (THREAD_TYPE), 1);
107 if (*threadID == NULL)
108 return CF_ERROR_THREAD_ALLOC;
109
110 result = pthread_create ((THREAD_TYPE *) *threadID, attr, f, arg);
111 if (result < 0)
112 {
113 CF_Thread_Release (threadID);
114 return CF_ERROR_THREAD_CREATE;
115 }
116
117#endif
118 return result;
119}
120
121/**
122 * 스레드 아이디를 해제
123 *
124 * @return 성공 시, CF_OK; 실패 시, 오류 코드
125 *
126 * @param threadID 스레드 아이디 주소
127 *
128 * @remark 스레드 아이디를 해제하는 것이며 워커 스레드가 종료되지 않음
129 */
130int
131CF_Thread_Release (CF_Thread * threadID)
132{
133 ASSERT_THREAD (*threadID);
134
135 return CF_Thread_Local_Close (*threadID);
136}
137
138/**
139 * 스레드가 종료될 때 까지 대기
140 *
141 * @return CF_OK 반환
142 *
143 * @param threadID 스레드 아이디 주소
144 */
145int
146CF_Thread_Join (CF_Thread * threadID)
147{
148 ASSERT_THREAD (*threadID);
149
150#if defined(_WIN32) || defined(_WIN64)
151 WaitForSingleObject ((THREAD_TYPE) *threadID, INFINITE);
152#else
153 char status[16] = {0x00,};
154 pthread_join (*((THREAD_TYPE *) *threadID), (void **)status);
155#endif
156
157 return CF_OK;
158}
159
160/**
161 * 뮤텍스 생성
162 *
163 * @return 성공 시, CF_OK; 실패 시, 오류 코드
164 *
165 * @param mutex 뮤텍스 아이디 주소
166 *
167 * @see CF_Thread_Create
168 */
169int
170CF_Mutex_Create (CF_Mutex * mutex)
171{
172 int result = 0;
173
174#if defined(_WIN32) || defined(_WIN64)
175 *mutex = (MUTEX_TYPE) CreateMutexA (NULL, FALSE, NULL);
176 if (*mutex == NULL)
177 return CF_ERROR_MUTEX_CREATE;
178#else
179 *mutex = (MUTEX_TYPE *) calloc (sizeof (MUTEX_TYPE), 1);
180 if (*mutex == NULL)
181 return CF_ERROR_MUTEX_CREATE;
182
183 result = pthread_mutex_init (*mutex, NULL);
184 if (result < 0)
185 return CF_ERROR_MUTEX_CREATE;
186#endif
187
188 return CF_OK;
189}
190
191/**
192 * 뮤텍스 해제
193 *
194 * @return 성공 시, CF_OK; 실패 시, 오류 코드
195 *
196 * @param mutex 뮤텍스 아이디 주소
197 */
198int
199CF_Mutex_Destory (CF_Mutex * mutex)
200{
201 ASSERT_MUTEX (*mutex);
202
203#if defined(_WIN32) || defined(_WIN64)
204#else
205 pthread_mutex_destroy (*mutex);
206#endif
207 return CF_Thread_Local_Close (*mutex);
208}
209
210/**
211 * 뮤텍스 잠금
212 *
213 * @return 성공 시, CF_OK; 실패 시, 오류 코드
214 *
215 * @param mutex 뮤텍스 아이디 주소
216 */
217int
218CF_Mutex_Lock (CF_Mutex * mutex)
219{
220 ASSERT_MUTEX (*mutex);
221
222#if defined(_WIN32) || defined(_WIN64)
223 WaitForSingleObject ((MUTEX_TYPE) *mutex, INFINITE);
224#else
225 pthread_mutex_lock ((MUTEX_TYPE *) *mutex);
226#endif
227
228 return CF_OK;
229}
230
231/**
232 * 뮤텍스 잠금 해제
233 *
234 * @return 성공 시, CF_OK; 실패 시, 오류 코드
235 *
236 * @param mutex 뮤텍스 아이디 주소
237 */
238int
239CF_Mutex_Unlock (CF_Mutex * mutex)
240{
241 ASSERT_MUTEX (*mutex);
242
243#if defined(_WIN32) || defined(_WIN64)
244 ReleaseMutex (*mutex);
245#else
246 pthread_mutex_unlock ((MUTEX_TYPE *) *mutex);
247#endif
248
249 return CF_OK;
250}
Note: See TracBrowser for help on using the repository browser.