<commit_before>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2013 <NAME>. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include <xenia/kernel/objects/xthread.h>

#include <poly/math.h>

#include <xenia/cpu/cpu.h>
#include <xenia/kernel/native_list.h>
#include <xenia/kernel/xboxkrnl_threading.h>
#include <xenia/kernel/objects/xevent.h>
#include <xenia/kernel/objects/xuser_module.h>


using namespace alloy;
using namespace xe;
using namespace xe::cpu;
using namespace xe::kernel;


namespace {
  static uint32_t next_xthread_id = 0;
  static uint32_t current_thread_tls = xeKeTlsAlloc();
  static xe_mutex_t* critical_region_ = xe_mutex_alloc(10000);
  static XThread* shared_kernel_thread_ = 0;
}


XThread::XThread(KernelState* kernel_state,
                 uint32_t stack_size,
                 uint32_t xapi_thread_startup,
                 uint32_t start_address, uint32_t start_context,
                 uint32_t creation_flags) :
    XObject(kernel_state, kTypeThread),
    thread_id_(++next_xthread_id),
    thread_handle_(0),
    thread_state_address_(0),
    thread_state_(0),
    event_(NULL),
    name_(0),
    irql_(0) {
  creation_params_.stack_size           = stack_size;
  creation_params_.xapi_thread_startup  = xapi_thread_startup;
  creation_params_.start_address        = start_address;
  creation_params_.start_context        = start_context;

  // top 8 bits = processor ID (or 0 for default)
  // bit 0 = 1 to create suspended
  creation_params_.creation_flags       = creation_flags;

  // Adjust stack size - min of 16k.
  if (creation_params_.stack_size < 16 * 1024 * 1024) {
    creation_params_.stack_size = 16 * 1024 * 1024;
  }

  apc_lock_ = xe_mutex_alloc();
  apc_list_ = new NativeList(kernel_state->memory());

  event_ = new XEvent(kernel_state);
  event_->Initialize(true, false);

  // The kernel does not take a reference. We must unregister in the dtor.
  kernel_state_->RegisterThread(this);
}

XThread::~XThread() {
  // Unregister first to prevent lookups while deleting.
  kernel_state_->UnregisterThread(this);

  delete apc_list_;
  xe_mutex_free(apc_lock_);

  event_->Release();

  PlatformDestroy();<commit_msg>Fixing overallocation of thread stacks (expending heap).<commit_after>/**
 ******************************************************************************
 * Xenia : Xbox 360 Emulator Research Project                                 *
 ******************************************************************************
 * Copyright 2013 <NAME>. All rights reserved.                             *
 * Released under the BSD license - see LICENSE in the root for more details. *
 ******************************************************************************
 */

#include <xenia/kernel/objects/xthread.h>

#include <poly/math.h>

#include <xenia/cpu/cpu.h>
#include <xenia/kernel/native_list.h>
#include <xenia/kernel/xboxkrnl_threading.h>
#include <xenia/kernel/objects/xevent.h>
#include <xenia/kernel/objects/xuser_module.h>


using namespace alloy;
using namespace xe;
using namespace xe::cpu;
using namespace xe::kernel;


namespace {
  static uint32_t next_xthread_id = 0;
  static uint32_t current_thread_tls = xeKeTlsAlloc();
  static xe_mutex_t* critical_region_ = xe_mutex_alloc(10000);
  static XThread* shared_kernel_thread_ = 0;
}


XThread::XThread(KernelState* kernel_state,
                 uint32_t stack_size,
                 uint32_t xapi_thread_startup,
                 uint32_t start_address, uint32_t start_context,
                 uint32_t creation_flags) :
    XObject(kernel_state, kTypeThread),
    thread_id_(++next_xthread_id),
    thread_handle_(0),
    thread_state_address_(0),
    thread_state_(0),
    event_(NULL),
    name_(0),
    irql_(0) {
  creation_params_.stack_size           = stack_size;
  creation_params_.xapi_thread_startup  = xapi_thread_startup;
  creation_params_.start_address        = start_address;
  creation_params_.start_context        = start_context;

  // top 8 bits = processor ID (or 0 for default)
  // bit 0 = 1 to create suspended
  creation_params_.creation_flags       = creation_flags;

  // Adjust stack size - min of 16k.
  if (creation_params_.stack_size < 16 * 1024) {
    creation_params_.stack_size = 16 * 1024;
  }

  apc_lock_ = xe_mutex_alloc();
  apc_list_ = new NativeList(kernel_state->memory());

  event_ = new XEvent(kernel_state);
  event_->Initialize(true, false);

  // The kernel does not take a reference. We must unregister in the dtor.
  kernel_state_->RegisterThread(this);
}

XThread::~XThread() {
  // Unregister first to prevent lookups while deleting.
  kernel_state_->UnregisterThread(this);

  delete apc_list_;
  xe_mutex_free(apc_lock_);

  event_->Release();

  PlatformDestroy();
{'fraction_non_alphanumeric': 0.1794571372778754, 'fraction_numerical': 0.021480179652411637, 'mean_word_length': 3.716390423572744, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2630639', 'n_tokens_mistral': 1646, 'n_tokens_neox': 1483, 'n_words': 339}