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
RevLine 
[4]1/**
[28]2 * @file cf_thread.c
3 * @author myusgun <myusgun@gmail.com>
[4]4 */
5#include "cf_thread.h"
6#include "cf_local.h"
[40]7#include "cf_error.h"
[4]8
9#include <stdlib.h>
10
[50]11#if defined(_WIN32) || defined(_WIN64)
[4]12# include <windows.h>
13# include <process.h>
14# define THREAD_TYPE HANDLE
15# define MUTEX_TYPE HANDLE
[57]16# define THREAD_RETURN unsigned long /**< 스레드 워커 함수 반환 형 */
17# define THREAD_CALL __stdcall
[50]18#else // #if defined(_WIN32) || defined(_WIN64)
[4]19# include <pthread.h>
20# define THREAD_TYPE pthread_t
21# define MUTEX_TYPE pthread_mutex_t
[57]22# define THREAD_RETURN void * /**< 스레드 워커 함수 반환 형 */
23# define THREAD_CALL
[50]24#endif // #if defined(_WIN32) || defined(_WIN64)
[4]25
[55]26#define ASSERT_THREAD(__h) \
[4]27 if (__h == NULL) \
28 return CF_ERROR_THREAD_INVALID_ARGS
29
[55]30#define ASSERT_MUTEX(__h) \
[4]31 if (__h == NULL) \
32 return CF_ERROR_MUTEX_INVALID_ARGS
33
[65]34typedef THREAD_RETURN (THREAD_CALL * THREAD_WORKER) (void *);
[60]35
[23]36static int
[21]37CF_Thread_Local_Close (void * ctx)
[4]38{
[50]39#if defined(_WIN32) || defined(_WIN64)
[4]40 CloseHandle (ctx);
41#else
42 free (ctx);
43#endif
44
45 return CF_OK;
46}
47
[35]48/**
49 * 스레드를 생성
50 *
51 * @return 성공 시, CF_OK; 실패 시, 오류 코드
52 *
53 * @param threadID 스레드 아이디 주소
54 * @param callback 스레드 워커 함수 이름
55 * @param arg 스레드 함수로 전달할 인자
[80]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 />
[35]65 */
[4]66int
[5]67CF_Thread_Create (CF_Thread * threadID,
68 CF_Thread_Function callback,
69 void * arg)
[4]70{
71 int result = 0;
72
[65]73 THREAD_WORKER f = (THREAD_WORKER) callback;
[57]74
[50]75#if defined(_WIN32) || defined(_WIN64)
[81]76 *threadID = (THREAD_TYPE) CreateThread (NULL, 0, f, arg, 0, NULL);
77 if (*threadID == NULL)
78 return CF_ERROR_THREAD_CREATE;
79#else
[57]80
[81]81 pthread_attr_t * attr = NULL;
[80]82# if defined(_SOLARIS)
[81]83 pthread_attr_t solarisAttr;
84 struct sched_param sched;
[4]85
[81]86 attr = &solarisAttr;
[80]87
[81]88 result = pthread_attr_init (attr);
89 if (result)
90 return CF_ERROR_THREAD_INIT_ATTR;
[80]91
[81]92 result = pthread_attr_setinheritsched (attr, PTHREAD_EXPLICIT_SCHED);
93 if (result)
94 return CF_ERROR_THREAD_SET_INHERIT_SCHED;
[80]95
[81]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;
[80]104# endif // # if defined(_SOLARIS)
105
[81]106 *threadID = (THREAD_TYPE *) calloc (sizeof (THREAD_TYPE), 1);
107 if (*threadID == NULL)
108 return CF_ERROR_THREAD_ALLOC;
[80]109
[81]110 result = pthread_create ((THREAD_TYPE *) *threadID, attr, f, arg);
111 if (result < 0)
[80]112 {
[81]113 CF_Thread_Release (threadID);
114 return CF_ERROR_THREAD_CREATE;
[80]115 }
[4]116
[81]117#endif
[80]118 return result;
[4]119}
120
[35]121/**
122 * 스레드 아이디를 해제
123 *
124 * @return 성공 시, CF_OK; 실패 시, 오류 코드
125 *
126 * @param threadID 스레드 아이디 주소
127 *
128 * @remark 스레드 아이디를 해제하는 것이며 워커 스레드가 종료되지 않음
129 */
[4]130int
131CF_Thread_Release (CF_Thread * threadID)
132{
[55]133 ASSERT_THREAD (*threadID);
[4]134
[81]135 return CF_Thread_Local_Close (*threadID);
[4]136}
137
[35]138/**
139 * 스레드가 종료될 때 까지 대기
140 *
141 * @return CF_OK 반환
142 *
143 * @param threadID 스레드 아이디 주소
144 */
[4]145int
146CF_Thread_Join (CF_Thread * threadID)
147{
[55]148 ASSERT_THREAD (*threadID);
[4]149
[50]150#if defined(_WIN32) || defined(_WIN64)
[5]151 WaitForSingleObject ((THREAD_TYPE) *threadID, INFINITE);
[4]152#else
[22]153 char status[16] = {0x00,};
154 pthread_join (*((THREAD_TYPE *) *threadID), (void **)status);
[4]155#endif
156
157 return CF_OK;
158}
159
[35]160/**
161 * 뮤텍스 생성
162 *
163 * @return 성공 시, CF_OK; 실패 시, 오류 코드
164 *
165 * @param mutex 뮤텍스 아이디 주소
166 *
167 * @see CF_Thread_Create
168 */
[4]169int
170CF_Mutex_Create (CF_Mutex * mutex)
171{
172 int result = 0;
173
[50]174#if defined(_WIN32) || defined(_WIN64)
[8]175 *mutex = (MUTEX_TYPE) CreateMutexA (NULL, FALSE, NULL);
176 if (*mutex == NULL)
177 return CF_ERROR_MUTEX_CREATE;
[4]178#else
[8]179 *mutex = (MUTEX_TYPE *) calloc (sizeof (MUTEX_TYPE), 1);
180 if (*mutex == NULL)
181 return CF_ERROR_MUTEX_CREATE;
[4]182
[8]183 result = pthread_mutex_init (*mutex, NULL);
184 if (result < 0)
185 return CF_ERROR_MUTEX_CREATE;
[4]186#endif
187
188 return CF_OK;
189}
190
[35]191/**
192 * 뮤텍스 해제
193 *
194 * @return 성공 시, CF_OK; 실패 시, 오류 코드
195 *
196 * @param mutex 뮤텍스 아이디 주소
197 */
[4]198int
199CF_Mutex_Destory (CF_Mutex * mutex)
200{
[55]201 ASSERT_MUTEX (*mutex);
[4]202
[79]203#if defined(_WIN32) || defined(_WIN64)
204#else
205 pthread_mutex_destroy (*mutex);
206#endif
[81]207 return CF_Thread_Local_Close (*mutex);
[4]208}
209
[35]210/**
211 * 뮤텍스 잠금
212 *
213 * @return 성공 시, CF_OK; 실패 시, 오류 코드
214 *
215 * @param mutex 뮤텍스 아이디 주소
216 */
[4]217int
218CF_Mutex_Lock (CF_Mutex * mutex)
219{
[55]220 ASSERT_MUTEX (*mutex);
[4]221
[50]222#if defined(_WIN32) || defined(_WIN64)
[4]223 WaitForSingleObject ((MUTEX_TYPE) *mutex, INFINITE);
224#else
225 pthread_mutex_lock ((MUTEX_TYPE *) *mutex);
226#endif
227
228 return CF_OK;
229}
230
[35]231/**
232 * 뮤텍스 잠금 해제
233 *
234 * @return 성공 시, CF_OK; 실패 시, 오류 코드
235 *
236 * @param mutex 뮤텍스 아이디 주소
237 */
[4]238int
239CF_Mutex_Unlock (CF_Mutex * mutex)
240{
[55]241 ASSERT_MUTEX (*mutex);
[4]242
[50]243#if defined(_WIN32) || defined(_WIN64)
[4]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.