Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef _INK_THREAD_H
00030 #define _INK_THREAD_H
00031
00032
00033 #include "ink_hrtime.h"
00034 #include "ink_defs.h"
00035 #include <sched.h>
00036
00037
00038
00039
00040
00041
00042
00043
00044 #if defined(POSIX_THREAD)
00045 #include <pthread.h>
00046 #include <signal.h>
00047 #include <semaphore.h>
00048
00049 #if HAVE_PTHREAD_NP_H
00050 #include <pthread_np.h>
00051 #endif
00052
00053 #define INK_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
00054
00055 typedef pthread_t ink_thread;
00056 typedef pthread_cond_t ink_cond;
00057 typedef pthread_key_t ink_thread_key;
00058
00059
00060
00061 #if defined(darwin)
00062 #define TS_EMULATE_ANON_SEMAPHORES 1
00063 #endif
00064
00065 struct ink_semaphore {
00066 #if TS_EMULATE_ANON_SEMAPHORES
00067 sem_t * sema;
00068 int64_t semid;
00069 #else
00070 sem_t sema;
00071 #endif
00072
00073 sem_t * get() {
00074 #if TS_EMULATE_ANON_SEMAPHORES
00075 return sema;
00076 #else
00077 return &sema;
00078 #endif
00079 }
00080 };
00081
00082 #endif
00083
00084
00085
00086
00087
00088 #ifdef POSIX_THREAD_10031c
00089 typedef struct timespec ink_timestruc;
00090 #else
00091 typedef timestruc_t ink_timestruc;
00092 #endif
00093
00094 #include "ink_mutex.h"
00095 #include <errno.h>
00096 #include "ink_assert.h"
00097
00098
00099
00100
00101
00102
00103 #if defined(POSIX_THREAD)
00104
00105 static inline void
00106 ink_thread_key_create(ink_thread_key * key, void (*destructor) (void *value))
00107 {
00108 ink_assert(!pthread_key_create(key, destructor));
00109 }
00110
00111 static inline void
00112 ink_thread_setspecific(ink_thread_key key, void *value)
00113 {
00114 ink_assert(!pthread_setspecific(key, value));
00115 }
00116
00117 static inline void *
00118 ink_thread_getspecific(ink_thread_key key)
00119 {
00120 return pthread_getspecific(key);
00121 }
00122
00123 static inline void
00124 ink_thread_key_delete(ink_thread_key key)
00125 {
00126 ink_assert(!pthread_key_delete(key));
00127 }
00128
00129
00130 static inline ink_thread
00131 ink_thread_create(void *(*f) (void *), void *a, int detached = 0, size_t stacksize = 0)
00132 {
00133 ink_thread t;
00134 int ret;
00135 pthread_attr_t attr;
00136
00137 pthread_attr_init(&attr);
00138 pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
00139
00140 if (stacksize) {
00141 pthread_attr_setstacksize(&attr, stacksize);
00142 }
00143
00144 if (detached) {
00145 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
00146 }
00147
00148 ret = pthread_create(&t, &attr, f, a);
00149 ink_assert(ret == 0);
00150 pthread_attr_destroy(&attr);
00151
00152
00153
00154
00155
00156 return ret ? (ink_thread) 0 : t;
00157 }
00158
00159 static inline void
00160 ink_thread_cancel(ink_thread who)
00161 {
00162 #if defined(freebsd)
00163 (void) who;
00164 ink_assert(!"not supported");
00165 #else
00166 int ret = pthread_cancel(who);
00167 ink_assert(ret == 0);
00168 #endif
00169 }
00170
00171 static inline void *
00172 ink_thread_join(ink_thread t)
00173 {
00174 void *r;
00175 ink_assert(!pthread_join(t, &r));
00176 return r;
00177 }
00178
00179 static inline ink_thread
00180 ink_thread_self()
00181 {
00182 return (pthread_self());
00183 }
00184
00185 static inline int
00186 ink_thread_get_priority(ink_thread t, int *priority)
00187 {
00188 #if defined(freebsd)
00189 (void) t;
00190 (void) priority;
00191 ink_assert(!"not supported");
00192 return -1;
00193 #else
00194 int policy;
00195 struct sched_param param;
00196 int res = pthread_getschedparam(t, &policy, ¶m);
00197 *priority = param.sched_priority;
00198 return res;
00199 #endif
00200 }
00201
00202 static inline int
00203 ink_thread_sigsetmask(int how, const sigset_t * set, sigset_t * oset)
00204 {
00205 return (pthread_sigmask(how, set, oset));
00206 }
00207
00208
00209
00210
00211
00212 void ink_sem_init(ink_semaphore * sp, unsigned int count);
00213 void ink_sem_destroy(ink_semaphore * sp);
00214 void ink_sem_wait(ink_semaphore * sp);
00215 bool ink_sem_trywait(ink_semaphore * sp);
00216 void ink_sem_post(ink_semaphore * sp);
00217
00218
00219
00220
00221
00222 static inline void
00223 ink_cond_init(ink_cond * cp)
00224 {
00225 ink_assert(pthread_cond_init(cp, NULL) == 0);
00226 }
00227
00228 static inline void
00229 ink_cond_destroy(ink_cond * cp)
00230 {
00231 ink_assert(pthread_cond_destroy(cp) == 0);
00232 }
00233
00234 static inline void
00235 ink_cond_wait(ink_cond * cp, ink_mutex * mp)
00236 {
00237 ink_assert(pthread_cond_wait(cp, mp) == 0);
00238 }
00239 static inline int
00240 ink_cond_timedwait(ink_cond * cp, ink_mutex * mp, ink_timestruc * t)
00241 {
00242 int err;
00243 while (EINTR == (err = pthread_cond_timedwait(cp, mp, t)));
00244 #if defined(freebsd) || defined(openbsd)
00245 ink_assert((err == 0) || (err == ETIMEDOUT));
00246 #else
00247 ink_assert((err == 0) || (err == ETIME) || (err == ETIMEDOUT));
00248 #endif
00249 return err;
00250 }
00251
00252 static inline void
00253 ink_cond_signal(ink_cond * cp)
00254 {
00255 ink_assert(pthread_cond_signal(cp) == 0);
00256 }
00257
00258 static inline void
00259 ink_cond_broadcast(ink_cond * cp)
00260 {
00261 ink_assert(pthread_cond_broadcast(cp) == 0);
00262 }
00263
00264 static inline void
00265 ink_thr_yield()
00266 {
00267 ink_assert(!sched_yield());
00268 }
00269
00270 static inline void
00271 ink_thread_exit(void *status)
00272 {
00273 pthread_exit(status);
00274 }
00275
00276
00277
00278
00279 static inline void
00280 ink_set_thread_name(const char* name ATS_UNUSED)
00281 {
00282 #if defined(HAVE_PTHREAD_SETNAME_NP_1)
00283 pthread_setname_np(name);
00284 #elif defined(HAVE_PTHREAD_SETNAME_NP_2)
00285 pthread_setname_np(pthread_self(), name);
00286 #elif defined(HAVE_PTHREAD_SET_NAME_NP_2)
00287 pthread_set_name_np(pthread_self(), name);
00288 #elif defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_NAME)
00289 prctl(PR_SET_NAME, name, 0, 0, 0);
00290 #endif
00291 }
00292
00293 #endif
00294
00295 #endif