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