13614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko//===-- sanitizer_stoptheworld.h --------------------------------*- C++ -*-===//
23614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko//
33614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko//                     The LLVM Compiler Infrastructure
43614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko//
53614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// This file is distributed under the University of Illinois Open Source
63614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// License. See LICENSE.TXT for details.
73614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko//
83614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko//===----------------------------------------------------------------------===//
93614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko//
103614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// Defines the StopTheWorld function which suspends the execution of the current
113614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// process and runs the user-supplied callback in the same address space.
123614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko//
133614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko//===----------------------------------------------------------------------===//
143614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#ifndef SANITIZER_STOPTHEWORLD_H
153614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#define SANITIZER_STOPTHEWORLD_H
163614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko
173614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#include "sanitizer_internal_defs.h"
183614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#include "sanitizer_common.h"
193614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko
203614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkonamespace __sanitizer {
213614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkotypedef int SuspendedThreadID;
223614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko
2353c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko// Holds the list of suspended threads and provides an interface to dump their
2453c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko// register contexts.
253614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkoclass SuspendedThreadsList {
263614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko public:
273614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko  SuspendedThreadsList()
283614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko    : thread_ids_(1024) {}
2953c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko  SuspendedThreadID GetThreadID(uptr index) const {
303614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko    CHECK_LT(index, thread_ids_.size());
313614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko    return thread_ids_[index];
323614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko  }
3353c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko  int GetRegistersAndSP(uptr index, uptr *buffer, uptr *sp) const;
3453c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko  // The buffer in GetRegistersAndSP should be at least this big.
3553c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko  static uptr RegisterCount();
3653c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko  uptr thread_count() const { return thread_ids_.size(); }
3753c18d7e051c7dfe3cc8a2351e6ee67a264dbb51Alexander Potapenko  bool Contains(SuspendedThreadID thread_id) const {
383614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko    for (uptr i = 0; i < thread_ids_.size(); i++) {
393614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko      if (thread_ids_[i] == thread_id)
403614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko        return true;
413614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko    }
423614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko    return false;
433614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko  }
443614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko  void Append(SuspendedThreadID thread_id) {
453614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko    thread_ids_.push_back(thread_id);
463614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko  }
473614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko
483614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko private:
49a64d4359902f1f64992aedfe10d8882ae7c66f40Alexey Samsonov  InternalMmapVector<SuspendedThreadID> thread_ids_;
503614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko
513614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko  // Prohibit copy and assign.
523614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko  SuspendedThreadsList(const SuspendedThreadsList&);
533614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko  void operator=(const SuspendedThreadsList&);
543614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko};
553614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko
563614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkotypedef void (*StopTheWorldCallback)(
573614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko    const SuspendedThreadsList &suspended_threads_list,
583614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko    void *argument);
593614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko
603614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// Suspend all threads in the current process and run the callback on the list
613614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// of suspended threads. This function will resume the threads before returning.
623614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko// The callback should not call any libc functions.
636d036065e2ba85d9ad2a141596693b026f7ebbccAlexey Samsonov// This function should NOT be called from multiple threads simultaneously.
643614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenkovoid StopTheWorld(StopTheWorldCallback callback, void *argument);
653614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko
663614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko}  // namespace __sanitizer
673614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko
683614c16084e8a0dc8ae3418402a2d0c6f8107e39Alexander Potapenko#endif  // SANITIZER_STOPTHEWORLD_H
69