<commit_before>#include "arguments.hpp"
#include "call_frame.hpp"
#include "on_stack.hpp"
#include "memory.hpp"
#include "metrics.hpp"
#include "raise_reason.hpp"
#include "thread_phase.hpp"

#include "class/array.hpp"
#include "class/class.hpp"
#include "class/exception.hpp"
#include "class/fiber.hpp"
#include "class/lookup_table.hpp"
#include "class/native_method.hpp"
#include "class/object.hpp"
#include "class/thread.hpp"
#include "class/thread_state.hpp"

#include "memory/gc.hpp"

#include "dtrace/dtrace.h"

#include "logger.hpp"

#include "missing/gettid.h"

#include <ostream>
#include <regex>
#include <string>

namespace rubinius {
  std::atomic<uint32_t> Fiber::fiber_ids_;

  void Fiber::bootstrap(STATE) {
    GO(fiber).set(state->memory()->new_class<Class, Fiber>(state, "Fiber"));

    fiber_ids_.store(0);
  }

  bool Fiber::root_p() {
    return vm()->fiber()->vm() == vm()->thread()->vm();
  }

  bool Fiber::canceled_p() {
    return !root_p() && vm()->thread_state()->raise_reason() == cFiberCancel;
  }

  void Fiber::unpack_arguments(STATE, Arguments& args) {
    switch(args.total()) {
      case 0:
        state->vm()->thread()->fiber_value(state, cNil);
        break;
      case 1:
        state->vm()->thread()->fiber_value(state, args.get_argument(0));
        break;
      default:
        state->vm()->thread()->fiber_value(state,  args.as_array(state));
        break;
    }
  }

  void Fiber::start(STATE, Arguments& args) {
    state->vm()->thread()->fiber_value(state, args.as_array(state));

    pthread_attr_t attrs;
    pthread_attr_init(&attrs);
    pthread_attr_setstacksize(&attrs, stack_size()->to_native());
    pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);

    int status = pthread_create(&vm()->os_thread(), &attrs,
        Fiber::run, (void*)vm());

    pthread_attr_destroy(&attrs);

    if(status != 0) {
      char buf[RBX_STRERROR_BUFSIZE];
      char* err = RBX_STRERROR(status, buf, RBX_STRERROR_BUFSIZE);
      Exception::raise_fiber_error(state, err);
    }

    // Wait for Fiber thread to start up and pause.
    while(!vm()->suspended_p()) {
      ; // spin wait
    }
  }

  void Fiber::restart(STATE) {
    UnmanagedPhase unmanaged(state);

    {
      std::lock_guard<std::mutex> guard(state->vm()->thread()->fiber_mutex());

      if(!vm()->suspended_p()) {
        std::ostringstream msg;
        msg << "attempt to restart non-suspended ("
          << vm()->fiber_transition_flag() << ") fiber";
        Exception::raise_fiber_error(state, msg.str().c_str());
      }

      state->vm()->set_suspending();

      restart_context(state->vm());
      wakeup();

      while(vm()->suspended_p()) {
        std::lock_guard<std::mutex> guard(vm()->fiber_wait_mutex());
        vm()->fiber_wait_condition().notify_one();
      }
    }

    while(!vm()->running_p()) {
      ; // spin wait
    }
  }

  void Fiber::cancel(STATE) {
    if(!vm()->zombie_p()) {
      vm()->thread_state()->raise_fiber_cancel();

      wakeup();

      while(vm()->suspended_p()) {
        std::lock_guard<std::mutex> guard(vm()->fiber_wait_mutex());
        vm()->fiber_wait_condition().notify_one();
      }
    }
  }

  void Fiber::suspend_and_continue(STATE) {
    UnmanagedPhase unmanaged(state);

    {
      std::unique_lock<std::mutex> lk(vm()->fiber_wait_mutex());

      vm()->set_suspended();
      while(!wakeup_p()) {
        vm()->fiber_wait_condition().wait(lk);
      }
      clear_wakeup();
      vm()->set_resuming();
    }

    if(!vm()->canceled_p()) {
      std::lock_guard<std::mutex> guard(state->vm()->thread()->fiber_mutex());

      vm()->set_running();

      while(!restart_context()->suspended_p()) {
        ; // spin wait
      }

      state->vm()->thread()->current_fiber(state, this);
    }
  }

  Object* Fiber::return_value(STATE) {
    if(vm()->thread()->nil_p()) {
      return nullptr;
    } else if(vm()->thread_state()->raise_reason() == cNone) {
      return state->vm()->thread()->fiber_value();
    } else if(canceled_p()) {
      return nullptr;
    } else {
      invoke_context()->thread_state()->set_state(vm()->thread_state());
      return nullptr;
    }
  }
<commit_msg>Don't trigger exception unwind for no exception.<commit_after>#include "arguments.hpp"
#include "call_frame.hpp"
#include "on_stack.hpp"
#include "memory.hpp"
#include "metrics.hpp"
#include "raise_reason.hpp"
#include "thread_phase.hpp"

#include "class/array.hpp"
#include "class/class.hpp"
#include "class/exception.hpp"
#include "class/fiber.hpp"
#include "class/lookup_table.hpp"
#include "class/native_method.hpp"
#include "class/object.hpp"
#include "class/thread.hpp"
#include "class/thread_state.hpp"

#include "memory/gc.hpp"

#include "dtrace/dtrace.h"

#include "logger.hpp"

#include "missing/gettid.h"

#include <ostream>
#include <regex>
#include <string>

namespace rubinius {
  std::atomic<uint32_t> Fiber::fiber_ids_;

  void Fiber::bootstrap(STATE) {
    GO(fiber).set(state->memory()->new_class<Class, Fiber>(state, "Fiber"));

    fiber_ids_.store(0);
  }

  bool Fiber::root_p() {
    return vm()->fiber()->vm() == vm()->thread()->vm();
  }

  bool Fiber::canceled_p() {
    return !root_p() && vm()->thread_state()->raise_reason() == cFiberCancel;
  }

  void Fiber::unpack_arguments(STATE, Arguments& args) {
    switch(args.total()) {
      case 0:
        state->vm()->thread()->fiber_value(state, cNil);
        break;
      case 1:
        state->vm()->thread()->fiber_value(state, args.get_argument(0));
        break;
      default:
        state->vm()->thread()->fiber_value(state,  args.as_array(state));
        break;
    }
  }

  void Fiber::start(STATE, Arguments& args) {
    state->vm()->thread()->fiber_value(state, args.as_array(state));

    pthread_attr_t attrs;
    pthread_attr_init(&attrs);
    pthread_attr_setstacksize(&attrs, stack_size()->to_native());
    pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);

    int status = pthread_create(&vm()->os_thread(), &attrs,
        Fiber::run, (void*)vm());

    pthread_attr_destroy(&attrs);

    if(status != 0) {
      char buf[RBX_STRERROR_BUFSIZE];
      char* err = RBX_STRERROR(status, buf, RBX_STRERROR_BUFSIZE);
      Exception::raise_fiber_error(state, err);
    }

    // Wait for Fiber thread to start up and pause.
    while(!vm()->suspended_p()) {
      ; // spin wait
    }
  }

  void Fiber::restart(STATE) {
    UnmanagedPhase unmanaged(state);

    {
      std::lock_guard<std::mutex> guard(state->vm()->thread()->fiber_mutex());

      if(!vm()->suspended_p()) {
        std::ostringstream msg;
        msg << "attempt to restart non-suspended ("
          << vm()->fiber_transition_flag() << ") fiber";
        Exception::raise_fiber_error(state, msg.str().c_str());
      }

      state->vm()->set_suspending();

      restart_context(state->vm());
      wakeup();

      while(vm()->suspended_p()) {
        std::lock_guard<std::mutex> guard(vm()->fiber_wait_mutex());
        vm()->fiber_wait_condition().notify_one();
      }
    }

    while(!vm()->running_p()) {
      ; // spin wait
    }
  }

  void Fiber::cancel(STATE) {
    if(!vm()->zombie_p()) {
      vm()->thread_state()->raise_fiber_cancel();

      wakeup();

      while(vm()->suspended_p()) {
        std::lock_guard<std::mutex> guard(vm()->fiber_wait_mutex());
        vm()->fiber_wait_condition().notify_one();
      }
    }
  }

  void Fiber::suspend_and_continue(STATE) {
    UnmanagedPhase unmanaged(state);

    {
      std::unique_lock<std::mutex> lk(vm()->fiber_wait_mutex());

      vm()->set_suspended();
      while(!wakeup_p()) {
        vm()->fiber_wait_condition().wait(lk);
      }
      clear_wakeup();
      vm()->set_resuming();
    }

    if(!vm()->canceled_p()) {
      std::lock_guard<std::mutex> guard(state->vm()->thread()->fiber_mutex());

      vm()->set_running();

      while(!restart_context()->suspended_p()) {
        ; // spin wait
      }

      state->vm()->thread()->current_fiber(state, this);
    }
  }

  Object* Fiber::return_value(STATE) {
    if(vm()->thread()->nil_p()) {
      return cNil;
    } else if(vm()->thread_state()->raise_reason() == cNone) {
      return state->vm()->thread()->fiber_value();
    } else if(canceled_p()) {
      return nullptr;
    } else {
      invoke_context()->thread_state()->set_state(vm()->thread_state());
      return nullptr;
    }
  }

{'fraction_non_alphanumeric': 0.18903456495828366, 'fraction_numerical': 0.00166865315852205, 'mean_word_length': 3.343167701863354, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 151, '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': '2723701', 'n_tokens_mistral': 2909, 'n_tokens_neox': 2827, 'n_words': 414}