18daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes/*
28daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Copyright (C) 2011 The Android Open Source Project
38daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes *
48daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
58daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * you may not use this file except in compliance with the License.
68daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * You may obtain a copy of the License at
78daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes *
88daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
98daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes *
108daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Unless required by applicable law or agreed to in writing, software
118daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
128daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * See the License for the specific language governing permissions and
148daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * limitations under the License.
158daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes */
168daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
178daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include "thread.h"
188daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
198daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughesnamespace art {
208daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
218daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughesvoid Thread::SetNativePriority(int) {
228daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  // Do nothing.
238daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes}
248daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
258daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughesint Thread::GetNativePriority() {
2634e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  return kNormThreadPriority;
278daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes}
288daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
29d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughesstatic void SigAltStack(stack_t* new_stack, stack_t* old_stack) {
30d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  if (sigaltstack(new_stack, old_stack) == -1) {
31d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes    PLOG(FATAL) << "sigaltstack failed";
32d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  }
33d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes}
34d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes
35b0f05b9654eb005bc8c8e15f615a7f5a312f640cDave Allison// The default SIGSTKSZ on linux is 8K.  If we do any logging in a signal
36cb7c0e9eb785a8d605da5d5b26ab265d4d635f1eIan Rogers// handler this is too small.  We allocate 16K instead or the minimum signal
37cb7c0e9eb785a8d605da5d5b26ab265d4d635f1eIan Rogers// stack size.
38cb7c0e9eb785a8d605da5d5b26ab265d4d635f1eIan Rogers// TODO: We shouldn't do logging (with locks) in signal handlers.
39cb7c0e9eb785a8d605da5d5b26ab265d4d635f1eIan Rogersstatic constexpr int kHostAltSigStackSize =
40cb7c0e9eb785a8d605da5d5b26ab265d4d635f1eIan Rogers    16 * KB < MINSIGSTKSZ ? MINSIGSTKSZ : 16 * KB;
41b0f05b9654eb005bc8c8e15f615a7f5a312f640cDave Allison
42d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughesvoid Thread::SetUpAlternateSignalStack() {
43d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  // Create and set an alternate signal stack.
44b0f05b9654eb005bc8c8e15f615a7f5a312f640cDave Allison#ifdef HAVE_ANDROID_OS
45b0f05b9654eb005bc8c8e15f615a7f5a312f640cDave Allison  LOG(FATAL) << "Invalid use of alternate signal stack on Android";
46b0f05b9654eb005bc8c8e15f615a7f5a312f640cDave Allison#endif
47d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  stack_t ss;
48b0f05b9654eb005bc8c8e15f615a7f5a312f640cDave Allison  ss.ss_sp = new uint8_t[kHostAltSigStackSize];
49b0f05b9654eb005bc8c8e15f615a7f5a312f640cDave Allison  ss.ss_size = kHostAltSigStackSize;
50d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  ss.ss_flags = 0;
51d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  CHECK(ss.ss_sp != NULL);
52d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  SigAltStack(&ss, NULL);
53d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes
54d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  // Double-check that it worked.
55d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  ss.ss_sp = NULL;
56d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  SigAltStack(NULL, &ss);
57d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  VLOG(threads) << "Alternate signal stack is " << PrettySize(ss.ss_size) << " at " << ss.ss_sp;
58d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes}
59d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes
60d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughesvoid Thread::TearDownAlternateSignalStack() {
61d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  // Get the pointer so we can free the memory.
62d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  stack_t ss;
63d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  SigAltStack(NULL, &ss);
64d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  uint8_t* allocated_signal_stack = reinterpret_cast<uint8_t*>(ss.ss_sp);
65d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes
66d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  // Tell the kernel to stop using it.
67d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  ss.ss_sp = NULL;
68d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  ss.ss_flags = SS_DISABLE;
69b0f05b9654eb005bc8c8e15f615a7f5a312f640cDave Allison  ss.ss_size = kHostAltSigStackSize;  // Avoid ENOMEM failure with Mac OS' buggy libc.
70d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  SigAltStack(&ss, NULL);
71d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes
72d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  // Free it.
73d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  delete[] allocated_signal_stack;
74d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes}
75d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes
768daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes}  // namespace art
77