// Copyright 2019 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "starboard/shared/pthread/thread_sampler_internal.h"

#if SB_API_VERSION >= 11

#include <semaphore.h>
#include <signal.h>

#include "starboard/common/log.h"
#include "starboard/common/mutex.h"
#include "starboard/shared/pthread/thread_context_internal.h"
#include "starboard/thread.h"

namespace {

class SignalHandler {
 public:
  static void AddSampler() {
    starboard::ScopedLock lock(GetMutex());
    if (++sampler_count_ == 1) {
      Install();
    }
  }

  static void RemoveSampler() {
    starboard::ScopedLock lock(GetMutex());
    if (--sampler_count_ == 0) {
      Restore();
    }
  }

  static SbThreadContext Freeze(SbThreadSampler sampler);
  static bool Thaw(SbThreadSampler sampler);

 private:
  // Getter with static local to lazily initialize the mutex once.
  static const starboard::Mutex& GetMutex() {
    static starboard::Mutex mutex;
    return mutex;
  }

  static void Install() {
    sem_init(&freeze_semaphore_, 0, 0);
    sem_init(&thaw_semaphore_, 0, 0);
    struct sigaction sa;
    sa.sa_sigaction = &HandleProfilerSignal;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART | SA_SIGINFO;
    signal_handler_installed_ =
        (sigaction(SIGPROF, &sa, &old_signal_handler_) == 0);
  }

  static void Restore() {
    if (signal_handler_installed_) {
      sigaction(SIGPROF, &old_signal_handler_, 0);
      signal_handler_installed_ = false;
    }
    sem_destroy(&freeze_semaphore_);
    sem_destroy(&thaw_semaphore_);
  }

  static void HandleProfilerSignal(int signal, siginfo_t* info, void* context);

  static int sampler_count_;
  static bool signal_handler_installed_;
  static struct sigaction old_signal_handler_;
  static SbThreadContextPrivate sb_context_;
  static SbThreadSampler frozen_sampler_;
  // POSIX semaphore can be used in signal handler. Other synchronization,
  // including mutex, condition variable and Starboard's semaphore can't.
  static sem_t freeze_semaphore_;
  static sem_t thaw_semaphore_;
};

int SignalHandler::sampler_count_ = 0;
bool SignalHandler::signal_handler_installed_ = false;
struct sigaction SignalHandler::old_signal_handler_;
SbThreadContextPrivate SignalHandler::sb_context_;
SbThreadSampler SignalHandler::frozen_sampler_ = kSbThreadSamplerInvalid;
sem_t SignalHandler::freeze_semaphore_;
sem_t SignalHandler::thaw_semaphore_;

SbThreadContext SignalHandler::Freeze(SbThreadSampler sampler) {
  starboard::ScopedLock lock(GetMutex());
  SB_DCHECK(frozen_sampler_ != sampler) << "SbThreadSampler frozen twice.";
  if (!signal_handler_installed_ || SbThreadSamplerIsValid(frozen_sampler_)) {
    return kSbThreadContextInvalid;
  }
  frozen_sampler_ = sampler;
  pthread_kill(sampler->thread(), SIGPROF);
  sem_wait(&freeze_semaphore_);
  return &sb_context_;
}

bool SignalHandler::Thaw(SbThreadSampler sampler) {
  starboard::ScopedLock lock(GetMutex());
  SB_DCHECK(frozen_sampler_ == sampler) << "SbThreadSampler didn't freeze.";
  if (frozen_sampler_ != sampler) return false;
  sb_context_ = SbThreadContextPrivate();
  sem_post(&thaw_semaphore_);
  frozen_sampler_ = kSbThreadSamplerInvalid;
  return true;
}

void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info,
                                         void* context) {
  SB_UNREFERENCED_PARAMETER(info);
  if (signal != SIGPROF) return;
  sb_context_ = SbThreadContextPrivate(reinterpret_cast<ucontext_t*>(context));
  // |Freeze| can return the context now.
  sem_post(&freeze_semaphore_);
  // Keep this thread frozen until |Thaw| is called.
  sem_wait(&thaw_semaphore_);
}

}  // namespace

SbThreadSamplerPrivate::SbThreadSamplerPrivate(SbThread thread)
    : thread_(thread) {
  SignalHandler::AddSampler();
}

SbThreadSamplerPrivate::~SbThreadSamplerPrivate() {
  SignalHandler::RemoveSampler();
}

SbThreadContext SbThreadSamplerPrivate::Freeze() {
  return SignalHandler::Freeze(this);
}

bool SbThreadSamplerPrivate::Thaw() { return SignalHandler::Thaw(this); }

#endif  // SB_API_VERSION >= 11
