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

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

#1 fix interface and add util module

File size: 4.4 KB
Line 
1/**
2 * \file cf_thread.c
3 *
4 * \author myusgun <myusgun@gmail.com>
5 *
6 * \brief 멀티 스레드 구현
7 */
8#include "cf_thread.h"
9#include "cf_local.h"
10#include "cf_error.h"
11
12#include <stdlib.h>
13
14#if defined(_WIN32) || defined(_WIN64)
15# include <windows.h>
16# include <process.h>
17# define THREAD_TYPE HANDLE
18# define THREAD_RETURN unsigned long /**< 스레드 워커 함수 반환 형 */
19# define THREAD_CALL __stdcall
20#else // #if defined(_WIN32) || defined(_WIN64)
21# include <pthread.h>
22# define THREAD_TYPE pthread_t
23# define THREAD_RETURN void * /**< 스레드 워커 함수 반환 형 */
24# define THREAD_CALL
25#endif // #if defined(_WIN32) || defined(_WIN64)
26
27#define ASSERT_CTX(__ctx) \
28 if (__ctx == NULL) \
29 return CF_ERROR_THREAD_INVALID_CTX
30
31typedef THREAD_RETURN (THREAD_CALL * THREAD_WORKER) (void *);
32
33typedef struct __cf_thread_ctx__
34{
35 THREAD_TYPE tid;
36 THREAD_WORKER callback;
37 void * arg;
38} CF_THREAD_CONTEXT;
39
40/**
41 * 스레드 컨텍스트를 생성
42 *
43 * \return 성공 시, CF_OK; 실패 시, 오류 코드
44 *
45 * \param ctx 스레드 컨텍스트 주소
46 * \param callback 스레드 워커 함수 이름
47 * \param arg 스레드 함수로 전달할 인자
48 */
49int
50CF_Thread_Create (cf_ctx * ctx,
51 CF_Thread_Function callback,
52 void * arg)
53{
54 CF_THREAD_CONTEXT * context = NULL;
55
56 context = NEWCTX (CF_THREAD_CONTEXT);
57 if (context == NULL)
58 return CF_ERROR_THREAD_CREATE_CTX;
59
60 context->callback = (THREAD_WORKER) callback;
61 context->arg = arg;
62
63 *ctx = (cf_ctx) context;
64
65 return CF_OK;
66}
67
68/**
69 * 스레드를 실행
70 *
71 * \return 성공 시, CF_OK; 실패 시, 오류 코드
72 *
73 * \param ctx 스레드 컨텍스트
74 *
75 * \remarks
76 * pthread에서 지원되는 스케줄링 정책은 SCHED_OTHER, SCHED_FIFO, SCHED_RR 등이 존재 <br />
77 * 일반적으로 설정되는 스케줄링 정책의 기본값은 SCHED_OTHER이며,
78 * 솔라리스 환경에서 SCHED_OTHER는 TS(timesharing) 방식으로 명시되어 있음 <br />
79 * 그러나 개발 단계에서 테스트된 동작은 SCHED_FIFO와 동일하였으며,
80 * 때문에 솔라리스 환경에서는 스케줄링 정책을 SCHED_RR로 명시하도록 함 <br />
81 * <br />
82 * 참고 url <br />
83 * - http://kldp.org/node/18841 , "SCHED_OTHER, SCHED_FIFO, SCHED_RR에 대해..." <br />
84 * - http://blog.naver.com/popjunior/80021646476 , "AIX, CPU 모니터링과 튜닝" <br />
85 */
86int
87CF_Thread_Start (cf_ctx ctx)
88{
89 int result = 0;
90
91 CF_THREAD_CONTEXT * context = (CF_THREAD_CONTEXT *) ctx;
92
93 ASSERT_CTX (ctx);
94
95#if defined(_WIN32) || defined(_WIN64)
96 context->tid = CreateThread (NULL, 0, context->callback, context->arg, 0, NULL);
97 if (context->tid == NULL)
98 return CF_ERROR_THREAD_START;
99#else
100
101 pthread_attr_t * attr = NULL;
102# if defined(_SOLARIS)
103 pthread_attr_t solarisAttr;
104 struct sched_param sched;
105
106 attr = &solarisAttr;
107
108 result = pthread_attr_init (attr);
109 if (result)
110 return CF_ERROR_THREAD_INIT_ATTR;
111
112 result = pthread_attr_setinheritsched (attr, PTHREAD_EXPLICIT_SCHED);
113 if (result)
114 return CF_ERROR_THREAD_SET_INHERIT_SCHED;
115
116 result = pthread_attr_setschedpolicy (attr, SCHED_RR);
117 if (result)
118 return CF_ERROR_THREAD_SET_SCHED_POLICY;
119
120 sched.sched_priority = 1;
121 result = pthread_attr_setschedparam (attr, &sched);
122 if (result)
123 return CF_ERROR_THREAD_SET_SCHED_PARAM;
124# endif // # if defined(_SOLARIS)
125
126 result = pthread_create (&context->tid, attr, context->callback, context->arg);
127 if (result)
128 return CF_ERROR_THREAD_START;
129#endif
130 return result;
131}
132
133/**
134 * 스레드 컨텍스트를 해제
135 *
136 * \return 성공 시, CF_OK; 실패 시, 오류 코드
137 *
138 * \param ctx 스레드 컨텍스트
139 *
140 * \remarks 스레드 컨텍스트를 해제하는 것이며 워커 스레드가 종료되지 않음
141 */
142int
143CF_Thread_Destroy (cf_ctx ctx)
144{
145 CF_THREAD_CONTEXT * context = (CF_THREAD_CONTEXT *) ctx;
146
147 ASSERT_CTX (ctx);
148
149#if defined(_WIN32) || defined(_WIN64)
150 if (context->tid == NULL)
151 return CF_ERROR_THREAD_INVALID_ARGS;
152
153 CloseHandle (context->tid);
154#endif
155 free (context);
156
157 return CF_OK;
158}
159
160/**
161 * 스레드가 종료될 때 까지 대기
162 *
163 * \return CF_OK 반환
164 *
165 * \param ctx 스레드 컨텍스트
166 */
167int
168CF_Thread_Join (cf_ctx ctx)
169{
170 CF_THREAD_CONTEXT * context = (CF_THREAD_CONTEXT *) ctx;
171
172 char status[16] = {0x00,};
173
174 ASSERT_CTX (ctx);
175
176#if defined(_WIN32) || defined(_WIN64)
177 WaitForSingleObject (context->tid, INFINITE);
178#else
179 pthread_join (context->tid, (void **)status);
180#endif
181
182 return CF_OK;
183}
Note: See TracBrowser for help on using the repository browser.