1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2004-2011 New Dream Network
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
15 #include "include/compat.h"
16 #include "common/Thread.h"
17 #include "common/code_environment.h"
18 #include "common/debug.h"
19 #include "common/signal.h"
20 #include "common/io_priority.h"
26 static int _set_affinity(int id
)
29 if (id
>= 0 && id
< CPU_SETSIZE
) {
35 if (sched_setaffinity(0, sizeof(cpuset
), &cpuset
) < 0)
37 /* guaranteed to take effect immediately */
58 void *Thread::_entry_func(void *arg
) {
59 void *r
= ((Thread
*)arg
)->entry_wrapper();
63 void *Thread::entry_wrapper()
65 int p
= ceph_gettid(); // may return -ENOSYS on other platforms
70 ioprio_priority
>= 0) {
71 ceph_ioprio_set(IOPRIO_WHO_PROCESS
,
73 IOPRIO_PRIO_VALUE(ioprio_class
, ioprio_priority
));
75 if (pid
&& cpuid
>= 0)
78 ceph_pthread_setname(pthread_self(), thread_name
);
82 const pthread_t
&Thread::get_thread_id() const
87 bool Thread::is_started() const
89 return thread_id
!= 0;
92 bool Thread::am_self() const
94 return (pthread_self() == thread_id
);
97 int Thread::kill(int signal
)
100 return pthread_kill(thread_id
, signal
);
105 int Thread::try_create(size_t stacksize
)
107 pthread_attr_t
*thread_attr
= NULL
;
108 pthread_attr_t thread_attr_loc
;
110 stacksize
&= CEPH_PAGE_MASK
; // must be multiple of page
112 thread_attr
= &thread_attr_loc
;
113 pthread_attr_init(thread_attr
);
114 pthread_attr_setstacksize(thread_attr
, stacksize
);
119 // The child thread will inherit our signal mask. Set our signal mask to
120 // the set of signals we want to block. (It's ok to block signals more
121 // signals than usual for a little while-- they will just be delivered to
122 // another thread or delieverd to this thread later.)
124 if (g_code_env
== CODE_ENVIRONMENT_LIBRARY
) {
125 block_signals(NULL
, &old_sigset
);
128 int to_block
[] = { SIGPIPE
, 0 };
129 block_signals(to_block
, &old_sigset
);
131 r
= pthread_create(&thread_id
, thread_attr
, _entry_func
, (void*)this);
132 restore_sigset(&old_sigset
);
135 pthread_attr_destroy(thread_attr
);
141 void Thread::create(const char *name
, size_t stacksize
)
143 assert(strlen(name
) < 16);
146 int ret
= try_create(stacksize
);
149 snprintf(buf
, sizeof(buf
), "Thread::try_create(): pthread_create "
150 "failed with error %d", ret
);
156 int Thread::join(void **prval
)
158 if (thread_id
== 0) {
159 assert("join on thread that was never started" == 0);
163 int status
= pthread_join(thread_id
, prval
);
166 snprintf(buf
, sizeof(buf
), "Thread::join(): pthread_join "
167 "failed with error %d\n", status
);
178 return pthread_detach(thread_id
);
181 int Thread::set_ioprio(int cls
, int prio
)
183 // fixme, maybe: this can race with create()
185 ioprio_priority
= prio
;
186 if (pid
&& cls
>= 0 && prio
>= 0)
187 return ceph_ioprio_set(IOPRIO_WHO_PROCESS
,
189 IOPRIO_PRIO_VALUE(cls
, prio
));
193 int Thread::set_affinity(int id
)
197 if (pid
&& ceph_gettid() == pid
)
198 r
= _set_affinity(id
);