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"
31 #include <sys/types.h>
36 static int _set_affinity(int id
)
39 if (id
>= 0 && id
< CPU_SETSIZE
) {
45 if (sched_setaffinity(0, sizeof(cpuset
), &cpuset
) < 0)
47 /* guaranteed to take effect immediately */
68 void *Thread::_entry_func(void *arg
) {
69 void *r
= ((Thread
*)arg
)->entry_wrapper();
73 void *Thread::entry_wrapper()
75 int p
= ceph_gettid(); // may return -ENOSYS on other platforms
80 ioprio_priority
>= 0) {
81 ceph_ioprio_set(IOPRIO_WHO_PROCESS
,
83 IOPRIO_PRIO_VALUE(ioprio_class
, ioprio_priority
));
85 if (pid
&& cpuid
>= 0)
88 ceph_pthread_setname(pthread_self(), thread_name
);
92 const pthread_t
&Thread::get_thread_id() const
97 bool Thread::is_started() const
99 return thread_id
!= 0;
102 bool Thread::am_self() const
104 return (pthread_self() == thread_id
);
107 int Thread::kill(int signal
)
110 return pthread_kill(thread_id
, signal
);
115 int Thread::try_create(size_t stacksize
)
117 pthread_attr_t
*thread_attr
= NULL
;
118 pthread_attr_t thread_attr_loc
;
120 stacksize
&= CEPH_PAGE_MASK
; // must be multiple of page
122 thread_attr
= &thread_attr_loc
;
123 pthread_attr_init(thread_attr
);
124 pthread_attr_setstacksize(thread_attr
, stacksize
);
129 // The child thread will inherit our signal mask. Set our signal mask to
130 // the set of signals we want to block. (It's ok to block signals more
131 // signals than usual for a little while-- they will just be delivered to
132 // another thread or delieverd to this thread later.)
134 if (g_code_env
== CODE_ENVIRONMENT_LIBRARY
) {
135 block_signals(NULL
, &old_sigset
);
138 int to_block
[] = { SIGPIPE
, 0 };
139 block_signals(to_block
, &old_sigset
);
141 r
= pthread_create(&thread_id
, thread_attr
, _entry_func
, (void*)this);
142 restore_sigset(&old_sigset
);
145 pthread_attr_destroy(thread_attr
);
151 void Thread::create(const char *name
, size_t stacksize
)
153 assert(strlen(name
) < 16);
156 int ret
= try_create(stacksize
);
159 snprintf(buf
, sizeof(buf
), "Thread::try_create(): pthread_create "
160 "failed with error %d", ret
);
166 int Thread::join(void **prval
)
168 if (thread_id
== 0) {
169 assert("join on thread that was never started" == 0);
173 int status
= pthread_join(thread_id
, prval
);
176 snprintf(buf
, sizeof(buf
), "Thread::join(): pthread_join "
177 "failed with error %d\n", status
);
188 return pthread_detach(thread_id
);
191 int Thread::set_ioprio(int cls
, int prio
)
193 // fixme, maybe: this can race with create()
195 ioprio_priority
= prio
;
196 if (pid
&& cls
>= 0 && prio
>= 0)
197 return ceph_ioprio_set(IOPRIO_WHO_PROCESS
,
199 IOPRIO_PRIO_VALUE(cls
, prio
));
203 int Thread::set_affinity(int id
)
207 if (pid
&& ceph_gettid() == pid
)
208 r
= _set_affinity(id
);