diff --git a/include/chaiscript/chaiscript_threading.hpp b/include/chaiscript/chaiscript_threading.hpp index baf000d..9d837bc 100644 --- a/include/chaiscript/chaiscript_threading.hpp +++ b/include/chaiscript/chaiscript_threading.hpp @@ -64,8 +64,7 @@ namespace chaiscript using std::recursive_mutex; - - +#ifdef CHAISCRIPT_HAS_THREAD_LOCAL /// Typesafe thread specific storage. If threading is enabled, this class uses a mutex protected map. If /// threading is not enabled, the class always returns the same data, regardless of which thread it is called from. /// @@ -74,6 +73,52 @@ namespace chaiscript class Thread_Storage { public: + + Thread_Storage(void *t_key) + : m_key(t_key) + { + } + + ~Thread_Storage() + { + t().erase(m_key); + } + + inline T *operator->() const + { + return &(t()[m_key]); + } + + inline T &operator*() const + { + return t()[m_key]; + } + + void *m_key; + + private: + static std::unordered_map &t() + { + thread_local static std::unordered_map my_t; + return my_t; + } + }; + +#else + + /// Typesafe thread specific storage. If threading is enabled, this class uses a mutex protected map. If + /// threading is not enabled, the class always returns the same data, regardless of which thread it is called from. + /// + /// This version is used if the compiler does not support thread_local + template + class Thread_Storage + { + public: + + Thread_Storage(void *) + { + } + inline T *operator->() const { return get_tls().get(); @@ -88,35 +133,26 @@ namespace chaiscript private: std::shared_ptr get_tls() const { - unique_lock lock(m_mutex); - + auto itr = m_instances.find(std::this_thread::get_id()); if (itr != m_instances.end()) { return itr->second; } - + std::shared_ptr new_instance(new T()); m_instances.insert(std::make_pair(std::this_thread::get_id(), new_instance)); return new_instance; - - - /* - static __thread std::shared_ptr *m_data = 0; - - if (!m_data) { m_data = new std::shared_ptr(new T()); } - - return *m_data; - */ } mutable mutex m_mutex; mutable std::unordered_map > m_instances; }; +#endif // threading enabled but no tls -#else +#else // threading disabled template class unique_lock { diff --git a/include/chaiscript/dispatchkit/dispatchkit.hpp b/include/chaiscript/dispatchkit/dispatchkit.hpp index 93ed1fb..610055d 100644 --- a/include/chaiscript/dispatchkit/dispatchkit.hpp +++ b/include/chaiscript/dispatchkit/dispatchkit.hpp @@ -411,7 +411,9 @@ namespace chaiscript }; Dispatch_Engine() - : m_place_holder(std::shared_ptr(new dispatch::Placeholder_Object())) + : m_stack_holder(this), + m_place_holder(std::shared_ptr(new dispatch::Placeholder_Object())) + { } @@ -745,8 +747,10 @@ namespace chaiscript /// std::map get_scripting_objects() const { + Stack_Holder &s = *m_stack_holder; + // We don't want the current context, but one up if it exists - StackData &stack = (m_stack_holder->stacks.size()==1)?(*(m_stack_holder->stacks.back())):(*m_stack_holder->stacks[m_stack_holder->stacks.size()-2]); + StackData &stack = (s.stacks.size()==1)?(*(s.stacks.back())):(*s.stacks[s.stacks.size()-2]); std::map retval; @@ -991,7 +995,8 @@ namespace chaiscript void save_function_params(const std::vector &t_params) { - m_stack_holder->call_params.insert(m_stack_holder->call_params.begin(), t_params.begin(), t_params.end()); + Stack_Holder &s = *m_stack_holder; + s.call_params.insert(s.call_params.begin(), t_params.begin(), t_params.end()); } void new_function_call() @@ -1001,15 +1006,16 @@ namespace chaiscript void pop_function_call() { - --m_stack_holder->call_depth; + Stack_Holder &s = *m_stack_holder; + --s.call_depth; - assert(m_stack_holder->call_depth >= 0); + assert(s.call_depth >= 0); - if (m_stack_holder->call_depth == 0) + if (s.call_depth == 0) { /// \todo Critical: this needs to be smarter, memory can expand quickly /// in tight loops involving function calls - m_stack_holder->call_params.clear(); + s.call_params.clear(); } } diff --git a/releasenotes.txt b/releasenotes.md similarity index 100% rename from releasenotes.txt rename to releasenotes.md