Move ke_ headers to new public/amtl folder.
authorDavid Anderson <dvander@alliedmods.net>
Thu Aug 22 16:30:44 2013 -0700 (2013-08-22)
changeset 4030eb4df1f7ff3c
parent 4029 cf8bdfcf6503
child 4031 852cf4415d12
Move ke_ headers to new public/amtl folder.
AMBuildScript
core/logic/AMBuilder
extensions/clientprefs/extension.h
public/amtl/ke_allocator_policies.h
public/amtl/ke_inline_list.h
public/amtl/ke_thread_posix.h
public/amtl/ke_thread_utils.h
public/amtl/ke_thread_windows.h
public/amtl/ke_utility.h
public/amtl/ke_vector.h
public/sourcepawn/ke_allocator_policies.h
public/sourcepawn/ke_inline_list.h
public/sourcepawn/ke_thread_posix.h
public/sourcepawn/ke_thread_utils.h
public/sourcepawn/ke_thread_windows.h
public/sourcepawn/ke_utility.h
public/sourcepawn/ke_vector.h
sourcepawn/jit/AMBuilder
     1.1 --- a/AMBuildScript	Thu Aug 22 14:05:44 2013 -0700
     1.2 +++ b/AMBuildScript	Thu Aug 22 16:30:44 2013 -0700
     1.3 @@ -300,6 +300,7 @@
     1.4  		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public'))
     1.5  		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'extensions'))
     1.6  		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'sourcepawn'))
     1.7 +		compiler['CXXINCLUDES'].append(os.path.join(AMBuild.sourceFolder, 'public', 'amtl'))
     1.8  		return compiler
     1.9  
    1.10  	def AutoVersion(self, folder, binary):
     2.1 --- a/core/logic/AMBuilder	Thu Aug 22 14:05:44 2013 -0700
     2.2 +++ b/core/logic/AMBuilder	Thu Aug 22 16:30:44 2013 -0700
     2.3 @@ -7,6 +7,7 @@
     2.4  compiler['CXXINCLUDES'].append(os.path.join(base, 'core', 'logic'))
     2.5  compiler['CXXINCLUDES'].append(os.path.join(base, 'public'))
     2.6  compiler['CXXINCLUDES'].append(os.path.join(base, 'public', 'sourcepawn'))
     2.7 +compiler['CXXINCLUDES'].append(os.path.join(base, 'public', 'amtl'))
     2.8  compiler['CDEFINES'].append('SM_DEFAULT_THREADER')
     2.9  compiler['CDEFINES'].append('SM_LOGIC')
    2.10  
     3.1 --- a/extensions/clientprefs/extension.h	Thu Aug 22 14:05:44 2013 -0700
     3.2 +++ b/extensions/clientprefs/extension.h	Thu Aug 22 16:30:44 2013 -0700
     3.3 @@ -156,7 +156,6 @@
     3.4  	IPhraseCollection *phrases;
     3.5  	const DatabaseInfo *DBInfo;
     3.6  
     3.7 -	IMutex *cookieMutex;
     3.8  	bool databaseLoading;
     3.9  
    3.10  private:
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/public/amtl/ke_allocator_policies.h	Thu Aug 22 16:30:44 2013 -0700
     4.3 @@ -0,0 +1,53 @@
     4.4 +/* vim: set ts=2 sw=2 tw=99 et:
     4.5 + *
     4.6 + * Copyright (C) 2012 David Anderson
     4.7 + *
     4.8 + * This file is part of SourcePawn.
     4.9 + *
    4.10 + * SourcePawn is free software: you can redistribute it and/or modify it under
    4.11 + * the terms of the GNU General Public License as published by the Free
    4.12 + * Software Foundation, either version 3 of the License, or (at your option)
    4.13 + * any later version.
    4.14 + * 
    4.15 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
    4.16 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    4.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    4.18 + *
    4.19 + * You should have received a copy of the GNU General Public License along with
    4.20 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
    4.21 + */
    4.22 +#ifndef _include_sourcepawn_allocatorpolicies_h_
    4.23 +#define _include_sourcepawn_allocatorpolicies_h_
    4.24 +
    4.25 +#include <stdio.h>
    4.26 +#include <stdlib.h>
    4.27 +
    4.28 +namespace ke {
    4.29 +
    4.30 +class SystemAllocatorPolicy
    4.31 +{
    4.32 +  protected:
    4.33 +    void reportOutOfMemory() {
    4.34 +      fprintf(stderr, "OUT OF MEMORY\n");
    4.35 +      abort();
    4.36 +    }
    4.37 +    void reportAllocationOverflow() {
    4.38 +      fprintf(stderr, "OUT OF MEMORY\n");
    4.39 +      abort();
    4.40 +    }
    4.41 +
    4.42 +  public:
    4.43 +    void free(void *memory) {
    4.44 +      ::free(memory);
    4.45 +    }
    4.46 +    void *malloc(size_t bytes) {
    4.47 +      void *ptr = ::malloc(bytes);
    4.48 +      if (!ptr)
    4.49 +        reportOutOfMemory();
    4.50 +      return ptr;
    4.51 +    }
    4.52 +};
    4.53 +
    4.54 +}
    4.55 +
    4.56 +#endif // _include_sourcepawn_allocatorpolicies_h_
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/public/amtl/ke_inline_list.h	Thu Aug 22 16:30:44 2013 -0700
     5.3 @@ -0,0 +1,137 @@
     5.4 +/**
     5.5 + * vim: set sts=2 ts=8 sw=2 tw=99 noet :
     5.6 + * =============================================================================
     5.7 + * SourcePawn
     5.8 + * Copyright (C) 2004-2009 AlliedModders LLC.  All rights reserved.
     5.9 + * =============================================================================
    5.10 + *
    5.11 + * This program is free software; you can redistribute it and/or modify it under
    5.12 + * the terms of the GNU General Public License, version 3.0, as published by the
    5.13 + * Free Software Foundation.
    5.14 + * 
    5.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
    5.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    5.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    5.18 + * details.
    5.19 + *
    5.20 + * You should have received a copy of the GNU General Public License along with
    5.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
    5.22 + *
    5.23 + * As a special exception, AlliedModders LLC gives you permission to link the
    5.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
    5.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    5.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
    5.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
    5.28 + * this exception to all derivative works.  AlliedModders LLC defines further
    5.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    5.30 + * or <http://www.sourcemod.net/license.php>.
    5.31 + */
    5.32 +#ifndef _include_sourcepawn_inline_list_h_
    5.33 +#define _include_sourcepawn_inline_list_h_
    5.34 +
    5.35 +#include <stddef.h>
    5.36 +
    5.37 +template <typename T> class InlineList;
    5.38 +
    5.39 +template <typename T>
    5.40 +class InlineListNode
    5.41 +{
    5.42 +  friend class InlineList<T>;
    5.43 +
    5.44 +  public:
    5.45 +  InlineListNode()
    5.46 +    : next_(NULL),
    5.47 +    prev_(NULL)
    5.48 +  {
    5.49 +  }
    5.50 +
    5.51 +  InlineListNode(InlineListNode *next, InlineListNode *prev)
    5.52 +    : next_(next),
    5.53 +    prev_(prev)
    5.54 +  {
    5.55 +  }
    5.56 +
    5.57 +  protected:
    5.58 +  InlineListNode *next_;
    5.59 +  InlineListNode *prev_;
    5.60 +};
    5.61 +
    5.62 +template <typename T>
    5.63 +class InlineList
    5.64 +{
    5.65 +  typedef InlineListNode<T> Node;
    5.66 +
    5.67 +  Node head_;
    5.68 +
    5.69 + public:
    5.70 +  InlineList()
    5.71 +    : head_(&head_, &head_)
    5.72 +  {
    5.73 +  }
    5.74 +
    5.75 + public:
    5.76 +  class iterator
    5.77 +  {
    5.78 +    friend class InlineList;
    5.79 +    Node *iter_;
    5.80 +
    5.81 +   public:
    5.82 +    iterator(Node *iter)
    5.83 +      : iter_(iter)
    5.84 +    {
    5.85 +    }
    5.86 +
    5.87 +    iterator & operator ++() {
    5.88 +      iter_ = iter_->next;
    5.89 +      return *iter_;
    5.90 +    }
    5.91 +    iterator operator ++(int) {
    5.92 +      iterator old(*this);
    5.93 +      iter_ = iter_->next_;
    5.94 +      return old;
    5.95 +    }
    5.96 +    T * operator *() {
    5.97 +      return static_cast<T *>(iter_);
    5.98 +    }
    5.99 +    T * operator ->() {
   5.100 +      return static_cast<T *>(iter_);
   5.101 +    }
   5.102 +    bool operator !=(const iterator &where) const {
   5.103 +      return iter_ != where.iter_;
   5.104 +    }
   5.105 +    bool operator ==(const iterator &where) const {
   5.106 +      return iter_ == where.iter_;
   5.107 +    }
   5.108 +    iterator prev() const {
   5.109 +      iterator p(iter_->prev_);
   5.110 +      return p;
   5.111 +    }
   5.112 +    iterator next() const {
   5.113 +      iterator p(iter_->next_);
   5.114 +      return p;
   5.115 +    }
   5.116 +  };
   5.117 +
   5.118 +  iterator begin() {
   5.119 +    return iterator(head_.next_);
   5.120 +  }
   5.121 +
   5.122 +  iterator end() {
   5.123 +    return iterator(&head_);
   5.124 +  }
   5.125 +
   5.126 +  void erase(Node *t) {
   5.127 +    t->prev_->next_ = t->next_;
   5.128 +    t->next_->prev_ = t->prev_;
   5.129 +  }
   5.130 +
   5.131 +  void insert(Node *t) {
   5.132 +    t->prev_ = head_.prev_;
   5.133 +    t->next_ = &head_;
   5.134 +    head_.prev_->next_ = t;
   5.135 +    head_.prev_ = t;
   5.136 +  }
   5.137 +};
   5.138 +
   5.139 +#endif // _include_sourcepawn_inline_list_h_
   5.140 +
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/public/amtl/ke_thread_posix.h	Thu Aug 22 16:30:44 2013 -0700
     6.3 @@ -0,0 +1,200 @@
     6.4 +// vim: set ts=8 sts=2 sw=2 tw=99 et:
     6.5 +//
     6.6 +// This file is part of SourcePawn.
     6.7 +// 
     6.8 +// SourcePawn is free software: you can redistribute it and/or modify
     6.9 +// it under the terms of the GNU General Public License as published by
    6.10 +// the Free Software Foundation, either version 3 of the License, or
    6.11 +// (at your option) any later version.
    6.12 +// 
    6.13 +// SourcePawn is distributed in the hope that it will be useful,
    6.14 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.15 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.16 +// GNU General Public License for more details.
    6.17 +// 
    6.18 +// You should have received a copy of the GNU General Public License
    6.19 +// along with SourcePawn.  If not, see <http://www.gnu.org/licenses/>.
    6.20 +#ifndef _include_sourcepawn_thread_posix_h_
    6.21 +#define _include_sourcepawn_thread_posix_h_
    6.22 +
    6.23 +#include <pthread.h>
    6.24 +#include <sys/time.h>
    6.25 +#include <errno.h>
    6.26 +#include <stdio.h>
    6.27 +#if defined(__linux__)
    6.28 +# include <sys/prctl.h>
    6.29 +#endif
    6.30 +#if defined(__APPLE__)
    6.31 +# include <dlfcn.h>
    6.32 +#endif
    6.33 +
    6.34 +namespace ke {
    6.35 +
    6.36 +class Mutex : public Lockable
    6.37 +{
    6.38 + public:
    6.39 +  Mutex() {
    6.40 +#if !defined(NDEBUG)
    6.41 +    int rv =
    6.42 +#endif
    6.43 +      pthread_mutex_init(&mutex_, NULL);
    6.44 +    assert(rv == 0);
    6.45 +  }
    6.46 +  ~Mutex() {
    6.47 +    pthread_mutex_destroy(&mutex_);
    6.48 +  }
    6.49 +
    6.50 +  bool DoTryLock() {
    6.51 +    return pthread_mutex_trylock(&mutex_) == 0;
    6.52 +  }
    6.53 +
    6.54 +  void DoLock() {
    6.55 +    pthread_mutex_lock(&mutex_);
    6.56 +  }
    6.57 +
    6.58 +  void DoUnlock() {
    6.59 +    pthread_mutex_unlock(&mutex_);
    6.60 +  }
    6.61 +  
    6.62 +  pthread_mutex_t *raw() {
    6.63 +    return &mutex_;
    6.64 +  }
    6.65 +
    6.66 + private:
    6.67 +  pthread_mutex_t mutex_;
    6.68 +};
    6.69 +
    6.70 +// Currently, this class only supports single-listener CVs.
    6.71 +class ConditionVariable : public Lockable
    6.72 +{
    6.73 + public:
    6.74 +  ConditionVariable() {
    6.75 +#if !defined(NDEBUG)
    6.76 +    int rv =
    6.77 +#endif
    6.78 +      pthread_cond_init(&cv_, NULL);
    6.79 +    assert(rv == 0);
    6.80 +  }
    6.81 +  ~ConditionVariable() {
    6.82 +    pthread_cond_destroy(&cv_);
    6.83 +  }
    6.84 +
    6.85 +  bool DoTryLock() {
    6.86 +    return mutex_.DoTryLock();
    6.87 +  }
    6.88 +  void DoLock() {
    6.89 +    mutex_.DoLock();
    6.90 +  }
    6.91 +  void DoUnlock() {
    6.92 +    mutex_.DoUnlock();
    6.93 +  }
    6.94 +
    6.95 +  void Notify() {
    6.96 +    AssertCurrentThreadOwns();
    6.97 +    pthread_cond_signal(&cv_);
    6.98 +  }
    6.99 +
   6.100 +  WaitResult Wait(size_t timeout_ms) {
   6.101 +    AssertCurrentThreadOwns();
   6.102 +
   6.103 +#if defined(__linux__)
   6.104 +    struct timespec ts;
   6.105 +    if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
   6.106 +      return Wait_Error;
   6.107 +#else
   6.108 +    struct timeval tv;
   6.109 +    gettimeofday(&tv, NULL);
   6.110 +
   6.111 +    struct timespec ts;
   6.112 +    ts.tv_sec = tv.tv_sec;
   6.113 +    ts.tv_nsec = tv.tv_usec * 1000;
   6.114 +#endif
   6.115 +
   6.116 +    ts.tv_sec += timeout_ms / 1000;
   6.117 +    ts.tv_nsec += (timeout_ms % 1000) * 1000000;
   6.118 +    if (ts.tv_nsec >= 1000000000) {
   6.119 +      ts.tv_sec++;
   6.120 +      ts.tv_nsec -= 1000000000;
   6.121 +    }
   6.122 +
   6.123 +    DebugSetUnlocked();
   6.124 +    int rv = pthread_cond_timedwait(&cv_, mutex_.raw(), &ts);
   6.125 +    DebugSetLocked();
   6.126 +
   6.127 +    if (rv == ETIMEDOUT)
   6.128 +      return Wait_Timeout;
   6.129 +    if (rv == 0)
   6.130 +      return Wait_Signaled;
   6.131 +    return Wait_Error;
   6.132 +  }
   6.133 +
   6.134 +  WaitResult Wait() {
   6.135 +    AssertCurrentThreadOwns();
   6.136 +
   6.137 +    DebugSetUnlocked();
   6.138 +    int rv = pthread_cond_wait(&cv_, mutex_.raw());
   6.139 +    DebugSetLocked();
   6.140 +
   6.141 +    if (rv == 0)
   6.142 +      return Wait_Signaled;
   6.143 +    return Wait_Error;
   6.144 +  }
   6.145 +
   6.146 + private:
   6.147 +  Mutex mutex_;
   6.148 +  pthread_cond_t cv_;
   6.149 +};
   6.150 +
   6.151 +class Thread
   6.152 +{
   6.153 +  struct ThreadData {
   6.154 +    IRunnable *run;
   6.155 +    char name[17];
   6.156 +  };
   6.157 + public:
   6.158 +  Thread(IRunnable *run, const char *name = NULL) {
   6.159 +    ThreadData *data = new ThreadData;
   6.160 +    data->run = run;
   6.161 +    snprintf(data->name, sizeof(data->name), "%s", name ? name : "");
   6.162 +
   6.163 +    initialized_ = (pthread_create(&thread_, NULL, Main, data) == 0);
   6.164 +    if (!initialized_)
   6.165 +      delete data;
   6.166 +  }
   6.167 +
   6.168 +  bool Succeeded() const {
   6.169 +    return initialized_;
   6.170 +  }
   6.171 +
   6.172 +  void Join() {
   6.173 +    if (!Succeeded())
   6.174 +      return;
   6.175 +    pthread_join(thread_, NULL);
   6.176 +  }
   6.177 +
   6.178 + private:
   6.179 +  static void *Main(void *arg) {
   6.180 +    AutoPtr<ThreadData> data((ThreadData *)arg);
   6.181 +
   6.182 +    if (data->name[0]) {
   6.183 +#if defined(__linux__)
   6.184 +      prctl(PR_SET_NAME, (unsigned long)data->name);
   6.185 +#elif defined(__APPLE__)
   6.186 +      int (*fn)(const char *) = (int (*)(const char *))dlsym(RTLD_DEFAULT, "pthread_setname_np");
   6.187 +      if (fn)
   6.188 +        fn(data->name);
   6.189 +#endif
   6.190 +    }
   6.191 +    data->run->Run();
   6.192 +    return NULL;
   6.193 +  }
   6.194 +
   6.195 + private:
   6.196 +  bool initialized_;
   6.197 +  pthread_t thread_;
   6.198 +};
   6.199 +
   6.200 +} // namespace ke
   6.201 +
   6.202 +#endif // _include_sourcepawn_thread_posix_h_
   6.203 +
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/public/amtl/ke_thread_utils.h	Thu Aug 22 16:30:44 2013 -0700
     7.3 @@ -0,0 +1,246 @@
     7.4 +// vim: set ts=8 sts=2 sw=2 tw=99 et:
     7.5 +//
     7.6 +// This file is part of SourcePawn.
     7.7 +// 
     7.8 +// SourcePawn is free software: you can redistribute it and/or modify
     7.9 +// it under the terms of the GNU General Public License as published by
    7.10 +// the Free Software Foundation, either version 3 of the License, or
    7.11 +// (at your option) any later version.
    7.12 +// 
    7.13 +// SourcePawn is distributed in the hope that it will be useful,
    7.14 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.15 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    7.16 +// GNU General Public License for more details.
    7.17 +// 
    7.18 +// You should have received a copy of the GNU General Public License
    7.19 +// along with SourcePawn.  If not, see <http://www.gnu.org/licenses/>.
    7.20 +#ifndef _include_sourcepawn_threads_
    7.21 +#define _include_sourcepawn_threads_
    7.22 +
    7.23 +#include <assert.h>
    7.24 +#if defined(_MSC_VER)
    7.25 +# include <windows.h>
    7.26 +# include <WinBase.h>
    7.27 +#else
    7.28 +# include <pthread.h>
    7.29 +#endif
    7.30 +#include <ke_utility.h>
    7.31 +
    7.32 +// Thread primitives for SourcePawn.
    7.33 +//
    7.34 +// -- Mutexes --
    7.35 +//
    7.36 +// A Lockable is a mutual exclusion primitive. It can be owned by at most one
    7.37 +// thread at a time, and ownership blocks any other thread from taking taking
    7.38 +// ownership. Ownership must be acquired and released on the same thread.
    7.39 +// Lockables are not re-entrant.
    7.40 +//
    7.41 +// While a few classes support the Lockable interface, the simplest Lockable
    7.42 +// object that can be instantiated is a Mutex.
    7.43 +//
    7.44 +// -- Condition Variables --
    7.45 +//
    7.46 +// A ConditionVariable provides mutually exclusive access based on a
    7.47 +// condition ocurring. CVs provide two capabilities: Wait(), which will block
    7.48 +// until the condition is triggered, and Notify(), which signals any blocking
    7.49 +// thread that the condition has occurred.
    7.50 +//
    7.51 +// Condition variables have an underlying mutex lock. This lock must be
    7.52 +// acquired before calling Wait() or Notify(). It is automatically released
    7.53 +// once Wait begins blocking. This operation is atomic with respect to other
    7.54 +// threads and the mutex. For example, it is not possible for the lock to be
    7.55 +// acquired by another thread in between unlocking and blocking. Since Notify
    7.56 +// also requires the lock to be acquired, there is no risk of an event
    7.57 +// accidentally dissipating into thin air because it was sent before the other
    7.58 +// thread began blocking.
    7.59 +//
    7.60 +// When Wait() returns, the lock is automatically re-acquired. This operation
    7.61 +// is NOT atomic. In between waking up and re-acquiring the lock, another
    7.62 +// thread may steal the lock and issue another event. Applications must
    7.63 +// account for this. For example, a message pump should check that there are
    7.64 +// no messages left to process before blocking again.
    7.65 +//
    7.66 +// Likewise, it is also not defined whether a Signal() will have any effect
    7.67 +// while a thread is not waiting on the monitor. This is yet another reason
    7.68 +// the above paragraph is so important - applications should, under a lock of
    7.69 +// the condition variable - check for state changes before waiting.
    7.70 +//
    7.71 +// -- Threads --
    7.72 +//
    7.73 +// A Thread object, when created, spawns a new thread with the given callback
    7.74 +// (the callbacks must implement IRunnable). Threads have one method of
    7.75 +// interest, Join(), which will block until the thread's execution finishes.
    7.76 +// Deleting a thread object will free any operating system resources associated
    7.77 +// with that thread, if the thread has finished executing.
    7.78 +//
    7.79 +// Threads can fail to spawn; make sure to check Succeeded().
    7.80 +//
    7.81 +
    7.82 +namespace ke {
    7.83 +
    7.84 +// Abstraction for getting a unique thread identifier. Debug-only.
    7.85 +#if defined(_MSC_VER)
    7.86 +typedef DWORD ThreadId;
    7.87 +
    7.88 +static inline ThreadId GetCurrentThreadId()
    7.89 +{
    7.90 +  return ::GetCurrentThreadId();
    7.91 +}
    7.92 +#else
    7.93 +typedef pthread_t ThreadId;
    7.94 +
    7.95 +static inline ThreadId GetCurrentThreadId()
    7.96 +{
    7.97 +  return pthread_self();
    7.98 +}
    7.99 +#endif
   7.100 +
   7.101 +// Classes which use non-reentrant, same-thread lock/unlock semantics should
   7.102 +// inherit from this and implement DoLock/DoUnlock.
   7.103 +class Lockable
   7.104 +{
   7.105 + public:
   7.106 +  Lockable()
   7.107 +  {
   7.108 +#if !defined(NDEBUG)
   7.109 +    owner_ = 0;
   7.110 +#endif
   7.111 +  }
   7.112 +  virtual ~Lockable() {
   7.113 +  }
   7.114 +
   7.115 +  bool TryLock() {
   7.116 +    if (DoTryLock()) {
   7.117 +      DebugSetLocked();
   7.118 +      return true;
   7.119 +    }
   7.120 +    return false;
   7.121 +  }
   7.122 +
   7.123 +  void Lock() {
   7.124 +    assert(Owner() != GetCurrentThreadId());
   7.125 +    DoLock();
   7.126 +    DebugSetLocked();
   7.127 +  }
   7.128 +
   7.129 +  void Unlock() {
   7.130 +    assert(Owner() == GetCurrentThreadId());
   7.131 +    DebugSetUnlocked();
   7.132 +    DoUnlock();
   7.133 +  }
   7.134 +
   7.135 +  void AssertCurrentThreadOwns() const {
   7.136 +    assert(Owner() == GetCurrentThreadId());
   7.137 +  }
   7.138 +#if !defined(NDEBUG)
   7.139 +  bool Locked() const {
   7.140 +    return owner_ != 0;
   7.141 +  }
   7.142 +  ThreadId Owner() const {
   7.143 +    return owner_;
   7.144 +  }
   7.145 +#endif
   7.146 +
   7.147 +  virtual bool DoTryLock() = 0;
   7.148 +  virtual void DoLock() = 0;
   7.149 +  virtual void DoUnlock() = 0;
   7.150 +
   7.151 + protected:
   7.152 +  void DebugSetUnlocked() {
   7.153 +#if !defined(NDEBUG)
   7.154 +    owner_ = 0;
   7.155 +#endif
   7.156 +  }
   7.157 +  void DebugSetLocked() {
   7.158 +#if !defined(NDEBUG)
   7.159 +    owner_ = GetCurrentThreadId();
   7.160 +#endif
   7.161 +  }
   7.162 +
   7.163 + protected:
   7.164 +#if !defined(NDEBUG)
   7.165 +  ThreadId owner_;
   7.166 +#endif
   7.167 +};
   7.168 +
   7.169 +// RAII for automatically locking and unlocking an object.
   7.170 +class AutoLock
   7.171 +{
   7.172 + public:
   7.173 +  AutoLock(Lockable *lock)
   7.174 +   : lock_(lock)
   7.175 +  {
   7.176 +    lock_->Lock();
   7.177 +  }
   7.178 +  ~AutoLock() {
   7.179 +    lock_->Unlock();
   7.180 +  }
   7.181 +
   7.182 + private:
   7.183 +  Lockable *lock_;
   7.184 +};
   7.185 +
   7.186 +class AutoTryLock
   7.187 +{
   7.188 + public:
   7.189 +  AutoTryLock(Lockable *lock)
   7.190 +  {
   7.191 +    lock_ = lock->TryLock() ? lock : NULL;
   7.192 +  }
   7.193 +  ~AutoTryLock() {
   7.194 +    if (lock_)
   7.195 +      lock_->Unlock();
   7.196 +  }
   7.197 +
   7.198 + private:
   7.199 +  Lockable *lock_;
   7.200 +};
   7.201 +
   7.202 +// RAII for automatically unlocking and relocking an object.
   7.203 +class AutoUnlock
   7.204 +{
   7.205 + public:
   7.206 +  AutoUnlock(Lockable *lock)
   7.207 +   : lock_(lock)
   7.208 +  {
   7.209 +    lock_->Unlock();
   7.210 +  }
   7.211 +  ~AutoUnlock() {
   7.212 +    lock_->Lock();
   7.213 +  }
   7.214 +
   7.215 + private:
   7.216 +  Lockable *lock_;
   7.217 +};
   7.218 +
   7.219 +enum WaitResult {
   7.220 +  // Woke up because something happened.
   7.221 +  Wait_Signaled,
   7.222 +
   7.223 +  // Woke up because nothing happened and a timeout was specified.
   7.224 +  Wait_Timeout,
   7.225 +
   7.226 +  // Woke up, but because of an error.
   7.227 +  Wait_Error
   7.228 +};
   7.229 +
   7.230 +// This must be implemented in order to spawn a new thread.
   7.231 +class IRunnable
   7.232 +{
   7.233 + public:
   7.234 +  virtual ~IRunnable() {
   7.235 +  }
   7.236 +
   7.237 +  virtual void Run() = 0;
   7.238 +};
   7.239 +
   7.240 +} // namespace ke
   7.241 +
   7.242 +// Include the actual thread implementations.
   7.243 +#if defined(_MSC_VER)
   7.244 +# include "ke_thread_windows.h"
   7.245 +#else
   7.246 +# include "ke_thread_posix.h"
   7.247 +#endif
   7.248 +
   7.249 +#endif // _include_sourcepawn_threads_
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/public/amtl/ke_thread_windows.h	Thu Aug 22 16:30:44 2013 -0700
     8.3 @@ -0,0 +1,148 @@
     8.4 +// vim: set ts=8 sts=2 sw=2 tw=99 et:
     8.5 +//
     8.6 +// This file is part of SourcePawn.
     8.7 +// 
     8.8 +// SourcePawn is free software: you can redistribute it and/or modify
     8.9 +// it under the terms of the GNU General Public License as published by
    8.10 +// the Free Software Foundation, either version 3 of the License, or
    8.11 +// (at your option) any later version.
    8.12 +// 
    8.13 +// SourcePawn is distributed in the hope that it will be useful,
    8.14 +// but WITHOUT ANY WARRANTY; without even the implied warranty of
    8.15 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    8.16 +// GNU General Public License for more details.
    8.17 +// 
    8.18 +// You should have received a copy of the GNU General Public License
    8.19 +// along with SourcePawn.  If not, see <http://www.gnu.org/licenses/>.
    8.20 +#ifndef _include_sourcepawn_thread_windows_h_
    8.21 +#define _include_sourcepawn_thread_windows_h_
    8.22 +
    8.23 +#include <windows.h>
    8.24 +
    8.25 +namespace ke {
    8.26 +
    8.27 +class CriticalSection : public Lockable
    8.28 +{
    8.29 + public:
    8.30 +  CriticalSection() {
    8.31 +    InitializeCriticalSection(&cs_);
    8.32 +  }
    8.33 +  ~CriticalSection() {
    8.34 +    DeleteCriticalSection(&cs_);
    8.35 +  }
    8.36 +
    8.37 +  bool DoTryLock() {
    8.38 +    return !!TryEnterCriticalSection(&cs_);
    8.39 +  }
    8.40 +  void DoLock() {
    8.41 +    EnterCriticalSection(&cs_);
    8.42 +  }
    8.43 +
    8.44 +  void DoUnlock() {
    8.45 +    LeaveCriticalSection(&cs_);
    8.46 +  }
    8.47 +
    8.48 + private:
    8.49 +  CRITICAL_SECTION cs_;
    8.50 +};
    8.51 +
    8.52 +typedef CriticalSection Mutex;
    8.53 +
    8.54 +// Currently, this class only supports single-listener CVs.
    8.55 +class ConditionVariable : public Lockable
    8.56 +{
    8.57 + public:
    8.58 +  ConditionVariable() {
    8.59 +    event_ = CreateEvent(NULL, FALSE, FALSE, NULL);
    8.60 +  }
    8.61 +  ~ConditionVariable() {
    8.62 +    CloseHandle(event_);
    8.63 +  }
    8.64 +
    8.65 +  bool DoTryLock() {
    8.66 +    return cs_.DoTryLock();
    8.67 +  }
    8.68 +  void DoLock() {
    8.69 +    cs_.DoLock();
    8.70 +  }
    8.71 +  void DoUnlock() {
    8.72 +    cs_.DoUnlock();
    8.73 +  }
    8.74 +
    8.75 +  void Notify() {
    8.76 +    AssertCurrentThreadOwns();
    8.77 +    SetEvent(event_);
    8.78 +  }
    8.79 +
    8.80 +  WaitResult Wait(size_t timeout_ms) {
    8.81 +    // This will assert if the lock has not been acquired. We don't need to be
    8.82 +    // atomic here, like pthread_cond_wait, because the event bit will stick
    8.83 +    // until reset by a wait function.
    8.84 +    Unlock();
    8.85 +    DWORD rv = WaitForSingleObject(event_, timeout_ms);
    8.86 +    Lock();
    8.87 +
    8.88 +    if (rv == WAIT_TIMEOUT)
    8.89 +      return Wait_Timeout;
    8.90 +    if (rv == WAIT_FAILED)
    8.91 +      return Wait_Error;
    8.92 +    return Wait_Signaled;
    8.93 +  }
    8.94 +
    8.95 +  WaitResult Wait() {
    8.96 +    return Wait(INFINITE);
    8.97 +  }
    8.98 +
    8.99 + private:
   8.100 +  CriticalSection cs_;
   8.101 +  HANDLE event_;
   8.102 +};
   8.103 +
   8.104 +class Thread
   8.105 +{
   8.106 + public:
   8.107 +  Thread(IRunnable *run, const char *name = NULL) {
   8.108 +    thread_ = CreateThread(NULL, 0, Main, run, 0, NULL);
   8.109 +  }
   8.110 +  ~Thread() {
   8.111 +    if (!thread_)
   8.112 +      return;
   8.113 +    CloseHandle(thread_);
   8.114 +  }
   8.115 +
   8.116 +  bool Succeeded() const {
   8.117 +    return !!thread_;
   8.118 +  }
   8.119 +
   8.120 +  void Join() {
   8.121 +    if (!Succeeded())
   8.122 +      return;
   8.123 +    WaitForSingleObject(thread_, INFINITE);
   8.124 +  }
   8.125 +
   8.126 +  HANDLE handle() const {
   8.127 +	  return thread_;
   8.128 +  }
   8.129 +
   8.130 + private:
   8.131 +  static DWORD WINAPI Main(LPVOID arg) {
   8.132 +    ((IRunnable *)arg)->Run();
   8.133 +    return 0;
   8.134 +  }
   8.135 +
   8.136 +#pragma pack(push, 8)
   8.137 +  struct ThreadNameInfo {
   8.138 +    DWORD dwType;
   8.139 +    LPCSTR szName;
   8.140 +    DWORD dwThreadID;
   8.141 +    DWORD dwFlags;
   8.142 +  };
   8.143 +#pragma pack(pop)
   8.144 +
   8.145 + private:
   8.146 +  HANDLE thread_;
   8.147 +};
   8.148 +
   8.149 +} // namespace ke
   8.150 +
   8.151 +#endif // _include_sourcepawn_thread_windows_h_
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/public/amtl/ke_utility.h	Thu Aug 22 16:30:44 2013 -0700
     9.3 @@ -0,0 +1,327 @@
     9.4 +/* vim: set ts=4 sw=4 tw=99 et:
     9.5 + *
     9.6 + * Copyright (C) 2012-2013 David Anderson
     9.7 + *
     9.8 + * This file is part of SourcePawn.
     9.9 + *
    9.10 + * SourcePawn is free software: you can redistribute it and/or modify it under
    9.11 + * the terms of the GNU General Public License as published by the Free
    9.12 + * Software Foundation, either version 3 of the License, or (at your option)
    9.13 + * any later version.
    9.14 + * 
    9.15 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
    9.16 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    9.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    9.18 + *
    9.19 + * You should have received a copy of the GNU General Public License along with
    9.20 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
    9.21 + */
    9.22 +#ifndef _include_jitcraft_utility_h_
    9.23 +#define _include_jitcraft_utility_h_
    9.24 +
    9.25 +#include <assert.h>
    9.26 +#include <stddef.h>
    9.27 +#include <stdlib.h>
    9.28 +#include <stdint.h>
    9.29 +#if defined(_MSC_VER)
    9.30 +# include <intrin.h>
    9.31 +#endif
    9.32 +
    9.33 +#define KE_32BIT
    9.34 +
    9.35 +#if defined(_MSC_VER)
    9.36 +# pragma warning(disable:4355)
    9.37 +#endif
    9.38 +
    9.39 +namespace ke {
    9.40 +
    9.41 +static const size_t kMallocAlignment = sizeof(void *) * 2;
    9.42 +
    9.43 +typedef uint8_t uint8;
    9.44 +typedef int32_t int32;
    9.45 +typedef uint32_t uint32;
    9.46 +typedef int64_t int64;
    9.47 +typedef uint64_t uint64;
    9.48 +
    9.49 +typedef uint8 * Address;
    9.50 +
    9.51 +static const size_t kKB = 1024;
    9.52 +static const size_t kMB = 1024 * kKB;
    9.53 +static const size_t kGB = 1024 * kMB;
    9.54 +
    9.55 +template <typename T> T
    9.56 +ReturnAndVoid(T &t)
    9.57 +{
    9.58 +    T saved = t;
    9.59 +    t = T();
    9.60 +    return saved;
    9.61 +}
    9.62 +
    9.63 +// Wrapper that automatically deletes its contents. The pointer can be taken
    9.64 +// to avoid destruction.
    9.65 +template <typename T>
    9.66 +class AutoPtr
    9.67 +{
    9.68 +    T *t_;
    9.69 +
    9.70 +  public:
    9.71 +    AutoPtr()
    9.72 +      : t_(NULL)
    9.73 +    {
    9.74 +    }
    9.75 +    explicit AutoPtr(T *t)
    9.76 +      : t_(t)
    9.77 +    {
    9.78 +    }
    9.79 +    ~AutoPtr() {
    9.80 +        delete t_;
    9.81 +    }
    9.82 +    T *take() {
    9.83 +        return ReturnAndVoid(t_);
    9.84 +    }
    9.85 +    T *operator *() const {
    9.86 +        return t_;
    9.87 +    }
    9.88 +    T *operator ->() const {
    9.89 +        return t_;
    9.90 +    }
    9.91 +    operator T *() const {
    9.92 +        return t_;
    9.93 +    }
    9.94 +    void operator =(T *t) {
    9.95 +        delete t_;
    9.96 +        t_ = t;
    9.97 +    }
    9.98 +    bool operator !() const {
    9.99 +        return !t_;
   9.100 +    }
   9.101 +};
   9.102 +
   9.103 +// Bob Jenkin's one-at-a-time hash function[1].
   9.104 +//
   9.105 +// [1] http://burtleburtle.net/bob/hash/doobs.html
   9.106 +class CharacterStreamHasher
   9.107 +{
   9.108 +    uint32 hash;
   9.109 +
   9.110 +  public:
   9.111 +    CharacterStreamHasher()
   9.112 +      : hash(0)
   9.113 +    { }
   9.114 +
   9.115 +    void add(char c) {
   9.116 +        hash += c;
   9.117 +        hash += (hash << 10);
   9.118 +        hash ^= (hash >> 6);
   9.119 +    }
   9.120 +
   9.121 +    void add(const char *s, size_t length) {
   9.122 +        for (size_t i = 0; i < length; i++)
   9.123 +            add(s[i]);
   9.124 +    }
   9.125 +
   9.126 +    uint32 result() {
   9.127 +        hash += (hash << 3);
   9.128 +        hash ^= (hash >> 11);
   9.129 +        hash += (hash << 15);
   9.130 +        return hash;
   9.131 +    }
   9.132 +};
   9.133 +
   9.134 +static inline uint32
   9.135 +HashCharSequence(const char *s, size_t length)
   9.136 +{
   9.137 +    CharacterStreamHasher hasher;
   9.138 +    hasher.add(s, length);
   9.139 +    return hasher.result();
   9.140 +}
   9.141 +
   9.142 +// From http://burtleburtle.net/bob/hash/integer.html
   9.143 +static inline uint32
   9.144 +HashInt32(int32 a)
   9.145 +{
   9.146 +    a = (a ^ 61) ^ (a >> 16);
   9.147 +    a = a + (a << 3);
   9.148 +    a = a ^ (a >> 4);
   9.149 +    a = a * 0x27d4eb2d;
   9.150 +    a = a ^ (a >> 15);
   9.151 +    return a;
   9.152 +}
   9.153 +
   9.154 +// From http://www.cris.com/~Ttwang/tech/inthash.htm
   9.155 +static inline uint32
   9.156 +HashInt64(int64 key)
   9.157 +{
   9.158 +  key = (~key) + (key << 18); // key = (key << 18) - key - 1;
   9.159 +  key = key ^ (uint64(key) >> 31);
   9.160 +  key = key * 21; // key = (key + (key << 2)) + (key << 4);
   9.161 +  key = key ^ (uint64(key) >> 11);
   9.162 +  key = key + (key << 6);
   9.163 +  key = key ^ (uint64(key) >> 22);
   9.164 +  return uint32(key);
   9.165 +}
   9.166 +
   9.167 +static inline uint32
   9.168 +HashPointer(void *p)
   9.169 +{
   9.170 +#if defined(KE_32BIT)
   9.171 +    return HashInt32(reinterpret_cast<int32>(p));
   9.172 +#elif defined(KE_64BIT)
   9.173 +    return HashInt64(reinterpret_cast<int64>(p));
   9.174 +#endif
   9.175 +}
   9.176 +
   9.177 +static inline size_t
   9.178 +Log2(size_t number)
   9.179 +{
   9.180 +    assert(number != 0);
   9.181 +
   9.182 +#ifdef _MSC_VER
   9.183 +    unsigned long rval;
   9.184 +# ifdef _M_IX86
   9.185 +    _BitScanReverse(&rval, number);
   9.186 +# elif _M_X64
   9.187 +    _BitScanReverse64(&rval, number);
   9.188 +# endif
   9.189 +    return rval;
   9.190 +#else
   9.191 +    size_t bit;
   9.192 +    asm("bsr %1, %0\n"
   9.193 +        : "=r" (bit)
   9.194 +        : "rm" (number));
   9.195 +    return bit;
   9.196 +#endif
   9.197 +}
   9.198 +
   9.199 +static inline size_t
   9.200 +FindRightmostBit(size_t number)
   9.201 +{
   9.202 +    assert(number != 0);
   9.203 +
   9.204 +#ifdef _MSC_VER
   9.205 +    unsigned long rval;
   9.206 +# ifdef _M_IX86
   9.207 +    _BitScanForward(&rval, number);
   9.208 +# elif _M_X64
   9.209 +    _BitScanForward64(&rval, number);
   9.210 +# endif
   9.211 +    return rval;
   9.212 +#else
   9.213 +    size_t bit;
   9.214 +    asm("bsf %1, %0\n"
   9.215 +        : "=r" (bit)
   9.216 +        : "rm" (number));
   9.217 +    return bit;
   9.218 +#endif
   9.219 +}
   9.220 +
   9.221 +static inline bool
   9.222 +IsPowerOfTwo(size_t value)
   9.223 +{
   9.224 +    if (value == 0)
   9.225 +        return false;
   9.226 +    return !(value & (value - 1));
   9.227 +}
   9.228 +
   9.229 +static inline size_t
   9.230 +Align(size_t count, size_t alignment)
   9.231 +{
   9.232 +    assert(IsPowerOfTwo(alignment));
   9.233 +    return count + (alignment - (count % alignment)) % alignment;
   9.234 +}
   9.235 +
   9.236 +static inline bool
   9.237 +IsUint32AddSafe(unsigned a, unsigned b)
   9.238 +{
   9.239 +    if (!a || !b)
   9.240 +        return true;
   9.241 +    size_t log2_a = Log2(a);
   9.242 +    size_t log2_b = Log2(b);
   9.243 +    return (log2_a < sizeof(unsigned) * 8) &&
   9.244 +           (log2_b < sizeof(unsigned) * 8);
   9.245 +}
   9.246 +
   9.247 +static inline bool
   9.248 +IsUintPtrAddSafe(size_t a, size_t b)
   9.249 +{
   9.250 +    if (!a || !b)
   9.251 +        return true;
   9.252 +    size_t log2_a = Log2(a);
   9.253 +    size_t log2_b = Log2(b);
   9.254 +    return (log2_a < sizeof(size_t) * 8) &&
   9.255 +           (log2_b < sizeof(size_t) * 8);
   9.256 +}
   9.257 +
   9.258 +static inline bool
   9.259 +IsUint32MultiplySafe(unsigned a, unsigned b)
   9.260 +{
   9.261 +    if (a <= 1 || b <= 1)
   9.262 +        return true;
   9.263 +
   9.264 +    size_t log2_a = Log2(a);
   9.265 +    size_t log2_b = Log2(b);
   9.266 +    return log2_a + log2_b <= sizeof(unsigned) * 8;
   9.267 +}
   9.268 +
   9.269 +static inline bool
   9.270 +IsUintPtrMultiplySafe(size_t a, size_t b)
   9.271 +{
   9.272 +    if (a <= 1 || b <= 1)
   9.273 +        return true;
   9.274 +
   9.275 +    size_t log2_a = Log2(a);
   9.276 +    size_t log2_b = Log2(b);
   9.277 +    return log2_a + log2_b <= sizeof(size_t) * 8;
   9.278 +}
   9.279 +
   9.280 +#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(array[0]))
   9.281 +#define STATIC_ASSERT(cond) extern int static_assert_f(int a[(cond) ? 1 : -1])
   9.282 +
   9.283 +#define IS_ALIGNED(addr, alignment)    (!(uintptr_t(addr) & ((alignment) - 1)))
   9.284 +
   9.285 +template <typename T>
   9.286 +static inline bool
   9.287 +IsAligned(T addr, size_t alignment)
   9.288 +{
   9.289 +    assert(IsPowerOfTwo(alignment));
   9.290 +    return !(uintptr_t(addr) & (alignment - 1));
   9.291 +}
   9.292 +
   9.293 +static inline Address
   9.294 +AlignedBase(Address addr, size_t alignment)
   9.295 +{
   9.296 +    assert(IsPowerOfTwo(alignment));
   9.297 +    return Address(uintptr_t(addr) & ~(alignment - 1));
   9.298 +}
   9.299 +
   9.300 +template <typename T> static inline T
   9.301 +Min(const T &t1, const T &t2)
   9.302 +{
   9.303 +    return t1 < t2 ? t1 : t2;
   9.304 +}
   9.305 +
   9.306 +template <typename T> static inline T
   9.307 +Max(const T &t1, const T &t2)
   9.308 +{
   9.309 +    return t1 > t2 ? t1 : t2;
   9.310 +}
   9.311 +
   9.312 +#define OFFSETOF(Class, Member) reinterpret_cast<size_t>(&((Class *)NULL)->Member)
   9.313 +
   9.314 +#if defined(_MSC_VER)
   9.315 +# define KE_SIZET_FMT           "%Iu"
   9.316 +#elif defined(__GNUC__)
   9.317 +# define KE_SIZET_FMT           "%zu"
   9.318 +#else
   9.319 +# error "Implement format specifier string"
   9.320 +#endif
   9.321 +
   9.322 +#if defined(__GNUC__)
   9.323 +# define KE_CRITICAL_LIKELY(x)  __builtin_expect(!!(x), 1)
   9.324 +#else
   9.325 +# define KE_CRITICAL_LIKELY(x)  x
   9.326 +#endif
   9.327 +
   9.328 +}
   9.329 +
   9.330 +#endif // _include_jitcraft_utility_h_
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/public/amtl/ke_vector.h	Thu Aug 22 16:30:44 2013 -0700
    10.3 @@ -0,0 +1,166 @@
    10.4 +/* vim: set ts=2 sw=2 tw=99 et:
    10.5 + *
    10.6 + * Copyright (C) 2012 David Anderson
    10.7 + *
    10.8 + * This file is part of SourcePawn.
    10.9 + *
   10.10 + * SourcePawn is free software: you can redistribute it and/or modify it under
   10.11 + * the terms of the GNU General Public License as published by the Free
   10.12 + * Software Foundation, either version 3 of the License, or (at your option)
   10.13 + * any later version.
   10.14 + * 
   10.15 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
   10.16 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   10.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   10.18 + *
   10.19 + * You should have received a copy of the GNU General Public License along with
   10.20 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
   10.21 + */
   10.22 +#ifndef _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_
   10.23 +#define _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_
   10.24 +
   10.25 +#include <new>
   10.26 +#include <stdlib.h>
   10.27 +#include <ke_allocator_policies.h>
   10.28 +#include <ke_utility.h>
   10.29 +
   10.30 +namespace ke {
   10.31 +
   10.32 +template <typename T, typename AllocPolicy = SystemAllocatorPolicy>
   10.33 +class Vector : public AllocPolicy
   10.34 +{
   10.35 + public:
   10.36 +  Vector(AllocPolicy = AllocPolicy())
   10.37 +  : data(NULL),
   10.38 +    nitems(0),
   10.39 +    maxsize(0)
   10.40 +  {
   10.41 +  }
   10.42 +
   10.43 +  ~Vector()
   10.44 +  {
   10.45 +    zap();
   10.46 +  }
   10.47 +
   10.48 +  void steal(Vector &other) {
   10.49 +    zap();
   10.50 +    data = other.data;
   10.51 +    nitems = other.nitems;
   10.52 +    maxsize = other.maxsize;
   10.53 +    other.reset();
   10.54 +  }
   10.55 +
   10.56 +  bool append(const T& item) {
   10.57 +    if (!growIfNeeded(1))
   10.58 +      return false;
   10.59 +    new (&data[nitems]) T(item);
   10.60 +    nitems++;
   10.61 +    return true;
   10.62 +  }
   10.63 +  void infallibleAppend(const T &item) {
   10.64 +    assert(growIfNeeded(1));
   10.65 +    new (&data[nitems]) T(item);
   10.66 +    nitems++;
   10.67 +  }
   10.68 +  T popCopy() {
   10.69 +    T t = at(length() - 1);
   10.70 +    pop();
   10.71 +    return t;
   10.72 +  }
   10.73 +  void pop() {
   10.74 +    assert(nitems);
   10.75 +    data[nitems - 1].~T();
   10.76 +    nitems--;
   10.77 +  }
   10.78 +  bool empty() const {
   10.79 +    return length() == 0;
   10.80 +  }
   10.81 +  size_t length() const {
   10.82 +    return nitems;
   10.83 +  }
   10.84 +  T& at(size_t i) {
   10.85 +    assert(i < length());
   10.86 +    return data[i];
   10.87 +  }
   10.88 +  const T& at(size_t i) const {
   10.89 +    assert(i < length());
   10.90 +    return data[i];
   10.91 +  }
   10.92 +  T& operator [](size_t i) {
   10.93 +    return at(i);
   10.94 +  }
   10.95 +  const T& operator [](size_t i) const {
   10.96 +    return at(i);
   10.97 +  }
   10.98 +  void clear() {
   10.99 +    nitems = 0;
  10.100 +  }
  10.101 +  const T &back() const {
  10.102 +    return at(length() - 1);
  10.103 +  }
  10.104 +  T &back() {
  10.105 +    return at(length() - 1);
  10.106 +  }
  10.107 +
  10.108 +  T *buffer() const {
  10.109 +    return data;
  10.110 +  }
  10.111 +
  10.112 +  bool ensure(size_t desired) {
  10.113 +    if (desired <= length())
  10.114 +      return true;
  10.115 +
  10.116 +    return growIfNeeded(desired - length());
  10.117 +  }
  10.118 +
  10.119 + private:
  10.120 +  void zap() {
  10.121 +    for (size_t i = 0; i < nitems; i++)
  10.122 +      data[i].~T();
  10.123 +    this->free(data);
  10.124 +  }
  10.125 +  void reset() {
  10.126 +    data = NULL;
  10.127 +    nitems = 0;
  10.128 +    maxsize = 0;
  10.129 +  }
  10.130 +
  10.131 +  bool growIfNeeded(size_t needed)
  10.132 +  {
  10.133 +    if (!IsUintPtrAddSafe(nitems, needed)) {
  10.134 +      this->reportAllocationOverflow();
  10.135 +      return false;
  10.136 +    }
  10.137 +    if (nitems + needed < maxsize)
  10.138 +      return true;
  10.139 +    if (maxsize == 0)
  10.140 +      maxsize = 8;
  10.141 +    while (nitems + needed > maxsize) {
  10.142 +      if (!IsUintPtrMultiplySafe(maxsize, 2)) {
  10.143 +        this->reportAllocationOverflow();
  10.144 +        return false;
  10.145 +      }
  10.146 +      maxsize *= 2;
  10.147 +    }
  10.148 +    T* newdata = (T*)this->malloc(sizeof(T) * maxsize);
  10.149 +    if (newdata == NULL)
  10.150 +      return false;
  10.151 +    for (size_t i = 0; i < nitems; i++) {
  10.152 +      new (&newdata[i]) T(data[i]);
  10.153 +      data[i].~T();
  10.154 +    }
  10.155 +    this->free(data);
  10.156 +    data = newdata;
  10.157 +    return true;
  10.158 +  }
  10.159 +
  10.160 + private:
  10.161 +  T* data;
  10.162 +  size_t nitems;
  10.163 +  size_t maxsize;
  10.164 +};
  10.165 +
  10.166 +}
  10.167 +
  10.168 +#endif /* _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_ */
  10.169 +
    11.1 --- a/public/sourcepawn/ke_allocator_policies.h	Thu Aug 22 14:05:44 2013 -0700
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,53 +0,0 @@
    11.4 -/* vim: set ts=2 sw=2 tw=99 et:
    11.5 - *
    11.6 - * Copyright (C) 2012 David Anderson
    11.7 - *
    11.8 - * This file is part of SourcePawn.
    11.9 - *
   11.10 - * SourcePawn is free software: you can redistribute it and/or modify it under
   11.11 - * the terms of the GNU General Public License as published by the Free
   11.12 - * Software Foundation, either version 3 of the License, or (at your option)
   11.13 - * any later version.
   11.14 - * 
   11.15 - * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
   11.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   11.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   11.18 - *
   11.19 - * You should have received a copy of the GNU General Public License along with
   11.20 - * SourcePawn. If not, see http://www.gnu.org/licenses/.
   11.21 - */
   11.22 -#ifndef _include_sourcepawn_allocatorpolicies_h_
   11.23 -#define _include_sourcepawn_allocatorpolicies_h_
   11.24 -
   11.25 -#include <stdio.h>
   11.26 -#include <stdlib.h>
   11.27 -
   11.28 -namespace ke {
   11.29 -
   11.30 -class SystemAllocatorPolicy
   11.31 -{
   11.32 -  protected:
   11.33 -    void reportOutOfMemory() {
   11.34 -      fprintf(stderr, "OUT OF MEMORY\n");
   11.35 -      abort();
   11.36 -    }
   11.37 -    void reportAllocationOverflow() {
   11.38 -      fprintf(stderr, "OUT OF MEMORY\n");
   11.39 -      abort();
   11.40 -    }
   11.41 -
   11.42 -  public:
   11.43 -    void free(void *memory) {
   11.44 -      ::free(memory);
   11.45 -    }
   11.46 -    void *malloc(size_t bytes) {
   11.47 -      void *ptr = ::malloc(bytes);
   11.48 -      if (!ptr)
   11.49 -        reportOutOfMemory();
   11.50 -      return ptr;
   11.51 -    }
   11.52 -};
   11.53 -
   11.54 -}
   11.55 -
   11.56 -#endif // _include_sourcepawn_allocatorpolicies_h_
    12.1 --- a/public/sourcepawn/ke_inline_list.h	Thu Aug 22 14:05:44 2013 -0700
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,137 +0,0 @@
    12.4 -/**
    12.5 - * vim: set sts=2 ts=8 sw=2 tw=99 noet :
    12.6 - * =============================================================================
    12.7 - * SourcePawn
    12.8 - * Copyright (C) 2004-2009 AlliedModders LLC.  All rights reserved.
    12.9 - * =============================================================================
   12.10 - *
   12.11 - * This program is free software; you can redistribute it and/or modify it under
   12.12 - * the terms of the GNU General Public License, version 3.0, as published by the
   12.13 - * Free Software Foundation.
   12.14 - * 
   12.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
   12.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   12.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   12.18 - * details.
   12.19 - *
   12.20 - * You should have received a copy of the GNU General Public License along with
   12.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
   12.22 - *
   12.23 - * As a special exception, AlliedModders LLC gives you permission to link the
   12.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
   12.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   12.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
   12.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
   12.28 - * this exception to all derivative works.  AlliedModders LLC defines further
   12.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   12.30 - * or <http://www.sourcemod.net/license.php>.
   12.31 - */
   12.32 -#ifndef _include_sourcepawn_inline_list_h_
   12.33 -#define _include_sourcepawn_inline_list_h_
   12.34 -
   12.35 -#include <stddef.h>
   12.36 -
   12.37 -template <typename T> class InlineList;
   12.38 -
   12.39 -template <typename T>
   12.40 -class InlineListNode
   12.41 -{
   12.42 -  friend class InlineList<T>;
   12.43 -
   12.44 -  public:
   12.45 -  InlineListNode()
   12.46 -    : next_(NULL),
   12.47 -    prev_(NULL)
   12.48 -  {
   12.49 -  }
   12.50 -
   12.51 -  InlineListNode(InlineListNode *next, InlineListNode *prev)
   12.52 -    : next_(next),
   12.53 -    prev_(prev)
   12.54 -  {
   12.55 -  }
   12.56 -
   12.57 -  protected:
   12.58 -  InlineListNode *next_;
   12.59 -  InlineListNode *prev_;
   12.60 -};
   12.61 -
   12.62 -template <typename T>
   12.63 -class InlineList
   12.64 -{
   12.65 -  typedef InlineListNode<T> Node;
   12.66 -
   12.67 -  Node head_;
   12.68 -
   12.69 - public:
   12.70 -  InlineList()
   12.71 -    : head_(&head_, &head_)
   12.72 -  {
   12.73 -  }
   12.74 -
   12.75 - public:
   12.76 -  class iterator
   12.77 -  {
   12.78 -    friend class InlineList;
   12.79 -    Node *iter_;
   12.80 -
   12.81 -   public:
   12.82 -    iterator(Node *iter)
   12.83 -      : iter_(iter)
   12.84 -    {
   12.85 -    }
   12.86 -
   12.87 -    iterator & operator ++() {
   12.88 -      iter_ = iter_->next;
   12.89 -      return *iter_;
   12.90 -    }
   12.91 -    iterator operator ++(int) {
   12.92 -      iterator old(*this);
   12.93 -      iter_ = iter_->next_;
   12.94 -      return old;
   12.95 -    }
   12.96 -    T * operator *() {
   12.97 -      return static_cast<T *>(iter_);
   12.98 -    }
   12.99 -    T * operator ->() {
  12.100 -      return static_cast<T *>(iter_);
  12.101 -    }
  12.102 -    bool operator !=(const iterator &where) const {
  12.103 -      return iter_ != where.iter_;
  12.104 -    }
  12.105 -    bool operator ==(const iterator &where) const {
  12.106 -      return iter_ == where.iter_;
  12.107 -    }
  12.108 -    iterator prev() const {
  12.109 -      iterator p(iter_->prev_);
  12.110 -      return p;
  12.111 -    }
  12.112 -    iterator next() const {
  12.113 -      iterator p(iter_->next_);
  12.114 -      return p;
  12.115 -    }
  12.116 -  };
  12.117 -
  12.118 -  iterator begin() {
  12.119 -    return iterator(head_.next_);
  12.120 -  }
  12.121 -
  12.122 -  iterator end() {
  12.123 -    return iterator(&head_);
  12.124 -  }
  12.125 -
  12.126 -  void erase(Node *t) {
  12.127 -    t->prev_->next_ = t->next_;
  12.128 -    t->next_->prev_ = t->prev_;
  12.129 -  }
  12.130 -
  12.131 -  void insert(Node *t) {
  12.132 -    t->prev_ = head_.prev_;
  12.133 -    t->next_ = &head_;
  12.134 -    head_.prev_->next_ = t;
  12.135 -    head_.prev_ = t;
  12.136 -  }
  12.137 -};
  12.138 -
  12.139 -#endif // _include_sourcepawn_inline_list_h_
  12.140 -
    13.1 --- a/public/sourcepawn/ke_thread_posix.h	Thu Aug 22 14:05:44 2013 -0700
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,200 +0,0 @@
    13.4 -// vim: set ts=8 sts=2 sw=2 tw=99 et:
    13.5 -//
    13.6 -// This file is part of SourcePawn.
    13.7 -// 
    13.8 -// SourcePawn is free software: you can redistribute it and/or modify
    13.9 -// it under the terms of the GNU General Public License as published by
   13.10 -// the Free Software Foundation, either version 3 of the License, or
   13.11 -// (at your option) any later version.
   13.12 -// 
   13.13 -// SourcePawn is distributed in the hope that it will be useful,
   13.14 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.15 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13.16 -// GNU General Public License for more details.
   13.17 -// 
   13.18 -// You should have received a copy of the GNU General Public License
   13.19 -// along with SourcePawn.  If not, see <http://www.gnu.org/licenses/>.
   13.20 -#ifndef _include_sourcepawn_thread_posix_h_
   13.21 -#define _include_sourcepawn_thread_posix_h_
   13.22 -
   13.23 -#include <pthread.h>
   13.24 -#include <sys/time.h>
   13.25 -#include <errno.h>
   13.26 -#include <stdio.h>
   13.27 -#if defined(__linux__)
   13.28 -# include <sys/prctl.h>
   13.29 -#endif
   13.30 -#if defined(__APPLE__)
   13.31 -# include <dlfcn.h>
   13.32 -#endif
   13.33 -
   13.34 -namespace ke {
   13.35 -
   13.36 -class Mutex : public Lockable
   13.37 -{
   13.38 - public:
   13.39 -  Mutex() {
   13.40 -#if !defined(NDEBUG)
   13.41 -    int rv =
   13.42 -#endif
   13.43 -      pthread_mutex_init(&mutex_, NULL);
   13.44 -    assert(rv == 0);
   13.45 -  }
   13.46 -  ~Mutex() {
   13.47 -    pthread_mutex_destroy(&mutex_);
   13.48 -  }
   13.49 -
   13.50 -  bool DoTryLock() {
   13.51 -    return pthread_mutex_trylock(&mutex_) == 0;
   13.52 -  }
   13.53 -
   13.54 -  void DoLock() {
   13.55 -    pthread_mutex_lock(&mutex_);
   13.56 -  }
   13.57 -
   13.58 -  void DoUnlock() {
   13.59 -    pthread_mutex_unlock(&mutex_);
   13.60 -  }
   13.61 -  
   13.62 -  pthread_mutex_t *raw() {
   13.63 -    return &mutex_;
   13.64 -  }
   13.65 -
   13.66 - private:
   13.67 -  pthread_mutex_t mutex_;
   13.68 -};
   13.69 -
   13.70 -// Currently, this class only supports single-listener CVs.
   13.71 -class ConditionVariable : public Lockable
   13.72 -{
   13.73 - public:
   13.74 -  ConditionVariable() {
   13.75 -#if !defined(NDEBUG)
   13.76 -    int rv =
   13.77 -#endif
   13.78 -      pthread_cond_init(&cv_, NULL);
   13.79 -    assert(rv == 0);
   13.80 -  }
   13.81 -  ~ConditionVariable() {
   13.82 -    pthread_cond_destroy(&cv_);
   13.83 -  }
   13.84 -
   13.85 -  bool DoTryLock() {
   13.86 -    return mutex_.DoTryLock();
   13.87 -  }
   13.88 -  void DoLock() {
   13.89 -    mutex_.DoLock();
   13.90 -  }
   13.91 -  void DoUnlock() {
   13.92 -    mutex_.DoUnlock();
   13.93 -  }
   13.94 -
   13.95 -  void Notify() {
   13.96 -    AssertCurrentThreadOwns();
   13.97 -    pthread_cond_signal(&cv_);
   13.98 -  }
   13.99 -
  13.100 -  WaitResult Wait(size_t timeout_ms) {
  13.101 -    AssertCurrentThreadOwns();
  13.102 -
  13.103 -#if defined(__linux__)
  13.104 -    struct timespec ts;
  13.105 -    if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
  13.106 -      return Wait_Error;
  13.107 -#else
  13.108 -    struct timeval tv;
  13.109 -    gettimeofday(&tv, NULL);
  13.110 -
  13.111 -    struct timespec ts;
  13.112 -    ts.tv_sec = tv.tv_sec;
  13.113 -    ts.tv_nsec = tv.tv_usec * 1000;
  13.114 -#endif
  13.115 -
  13.116 -    ts.tv_sec += timeout_ms / 1000;
  13.117 -    ts.tv_nsec += (timeout_ms % 1000) * 1000000;
  13.118 -    if (ts.tv_nsec >= 1000000000) {
  13.119 -      ts.tv_sec++;
  13.120 -      ts.tv_nsec -= 1000000000;
  13.121 -    }
  13.122 -
  13.123 -    DebugSetUnlocked();
  13.124 -    int rv = pthread_cond_timedwait(&cv_, mutex_.raw(), &ts);
  13.125 -    DebugSetLocked();
  13.126 -
  13.127 -    if (rv == ETIMEDOUT)
  13.128 -      return Wait_Timeout;
  13.129 -    if (rv == 0)
  13.130 -      return Wait_Signaled;
  13.131 -    return Wait_Error;
  13.132 -  }
  13.133 -
  13.134 -  WaitResult Wait() {
  13.135 -    AssertCurrentThreadOwns();
  13.136 -
  13.137 -    DebugSetUnlocked();
  13.138 -    int rv = pthread_cond_wait(&cv_, mutex_.raw());
  13.139 -    DebugSetLocked();
  13.140 -
  13.141 -    if (rv == 0)
  13.142 -      return Wait_Signaled;
  13.143 -    return Wait_Error;
  13.144 -  }
  13.145 -
  13.146 - private:
  13.147 -  Mutex mutex_;
  13.148 -  pthread_cond_t cv_;
  13.149 -};
  13.150 -
  13.151 -class Thread
  13.152 -{
  13.153 -  struct ThreadData {
  13.154 -    IRunnable *run;
  13.155 -    char name[17];
  13.156 -  };
  13.157 - public:
  13.158 -  Thread(IRunnable *run, const char *name = NULL) {
  13.159 -    ThreadData *data = new ThreadData;
  13.160 -    data->run = run;
  13.161 -    snprintf(data->name, sizeof(data->name), "%s", name ? name : "");
  13.162 -
  13.163 -    initialized_ = (pthread_create(&thread_, NULL, Main, data) == 0);
  13.164 -    if (!initialized_)
  13.165 -      delete data;
  13.166 -  }
  13.167 -
  13.168 -  bool Succeeded() const {
  13.169 -    return initialized_;
  13.170 -  }
  13.171 -
  13.172 -  void Join() {
  13.173 -    if (!Succeeded())
  13.174 -      return;
  13.175 -    pthread_join(thread_, NULL);
  13.176 -  }
  13.177 -
  13.178 - private:
  13.179 -  static void *Main(void *arg) {
  13.180 -    AutoPtr<ThreadData> data((ThreadData *)arg);
  13.181 -
  13.182 -    if (data->name[0]) {
  13.183 -#if defined(__linux__)
  13.184 -      prctl(PR_SET_NAME, (unsigned long)data->name);
  13.185 -#elif defined(__APPLE__)
  13.186 -      int (*fn)(const char *) = (int (*)(const char *))dlsym(RTLD_DEFAULT, "pthread_setname_np");
  13.187 -      if (fn)
  13.188 -        fn(data->name);
  13.189 -#endif
  13.190 -    }
  13.191 -    data->run->Run();
  13.192 -    return NULL;
  13.193 -  }
  13.194 -
  13.195 - private:
  13.196 -  bool initialized_;
  13.197 -  pthread_t thread_;
  13.198 -};
  13.199 -
  13.200 -} // namespace ke
  13.201 -
  13.202 -#endif // _include_sourcepawn_thread_posix_h_
  13.203 -
    14.1 --- a/public/sourcepawn/ke_thread_utils.h	Thu Aug 22 14:05:44 2013 -0700
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,246 +0,0 @@
    14.4 -// vim: set ts=8 sts=2 sw=2 tw=99 et:
    14.5 -//
    14.6 -// This file is part of SourcePawn.
    14.7 -// 
    14.8 -// SourcePawn is free software: you can redistribute it and/or modify
    14.9 -// it under the terms of the GNU General Public License as published by
   14.10 -// the Free Software Foundation, either version 3 of the License, or
   14.11 -// (at your option) any later version.
   14.12 -// 
   14.13 -// SourcePawn is distributed in the hope that it will be useful,
   14.14 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
   14.15 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14.16 -// GNU General Public License for more details.
   14.17 -// 
   14.18 -// You should have received a copy of the GNU General Public License
   14.19 -// along with SourcePawn.  If not, see <http://www.gnu.org/licenses/>.
   14.20 -#ifndef _include_sourcepawn_threads_
   14.21 -#define _include_sourcepawn_threads_
   14.22 -
   14.23 -#include <assert.h>
   14.24 -#if defined(_MSC_VER)
   14.25 -# include <windows.h>
   14.26 -# include <WinBase.h>
   14.27 -#else
   14.28 -# include <pthread.h>
   14.29 -#endif
   14.30 -#include <ke_utility.h>
   14.31 -
   14.32 -// Thread primitives for SourcePawn.
   14.33 -//
   14.34 -// -- Mutexes --
   14.35 -//
   14.36 -// A Lockable is a mutual exclusion primitive. It can be owned by at most one
   14.37 -// thread at a time, and ownership blocks any other thread from taking taking
   14.38 -// ownership. Ownership must be acquired and released on the same thread.
   14.39 -// Lockables are not re-entrant.
   14.40 -//
   14.41 -// While a few classes support the Lockable interface, the simplest Lockable
   14.42 -// object that can be instantiated is a Mutex.
   14.43 -//
   14.44 -// -- Condition Variables --
   14.45 -//
   14.46 -// A ConditionVariable provides mutually exclusive access based on a
   14.47 -// condition ocurring. CVs provide two capabilities: Wait(), which will block
   14.48 -// until the condition is triggered, and Notify(), which signals any blocking
   14.49 -// thread that the condition has occurred.
   14.50 -//
   14.51 -// Condition variables have an underlying mutex lock. This lock must be
   14.52 -// acquired before calling Wait() or Notify(). It is automatically released
   14.53 -// once Wait begins blocking. This operation is atomic with respect to other
   14.54 -// threads and the mutex. For example, it is not possible for the lock to be
   14.55 -// acquired by another thread in between unlocking and blocking. Since Notify
   14.56 -// also requires the lock to be acquired, there is no risk of an event
   14.57 -// accidentally dissipating into thin air because it was sent before the other
   14.58 -// thread began blocking.
   14.59 -//
   14.60 -// When Wait() returns, the lock is automatically re-acquired. This operation
   14.61 -// is NOT atomic. In between waking up and re-acquiring the lock, another
   14.62 -// thread may steal the lock and issue another event. Applications must
   14.63 -// account for this. For example, a message pump should check that there are
   14.64 -// no messages left to process before blocking again.
   14.65 -//
   14.66 -// Likewise, it is also not defined whether a Signal() will have any effect
   14.67 -// while a thread is not waiting on the monitor. This is yet another reason
   14.68 -// the above paragraph is so important - applications should, under a lock of
   14.69 -// the condition variable - check for state changes before waiting.
   14.70 -//
   14.71 -// -- Threads --
   14.72 -//
   14.73 -// A Thread object, when created, spawns a new thread with the given callback
   14.74 -// (the callbacks must implement IRunnable). Threads have one method of
   14.75 -// interest, Join(), which will block until the thread's execution finishes.
   14.76 -// Deleting a thread object will free any operating system resources associated
   14.77 -// with that thread, if the thread has finished executing.
   14.78 -//
   14.79 -// Threads can fail to spawn; make sure to check Succeeded().
   14.80 -//
   14.81 -
   14.82 -namespace ke {
   14.83 -
   14.84 -// Abstraction for getting a unique thread identifier. Debug-only.
   14.85 -#if defined(_MSC_VER)
   14.86 -typedef DWORD ThreadId;
   14.87 -
   14.88 -static inline ThreadId GetCurrentThreadId()
   14.89 -{
   14.90 -  return ::GetCurrentThreadId();
   14.91 -}
   14.92 -#else
   14.93 -typedef pthread_t ThreadId;
   14.94 -
   14.95 -static inline ThreadId GetCurrentThreadId()
   14.96 -{
   14.97 -  return pthread_self();
   14.98 -}
   14.99 -#endif
  14.100 -
  14.101 -// Classes which use non-reentrant, same-thread lock/unlock semantics should
  14.102 -// inherit from this and implement DoLock/DoUnlock.
  14.103 -class Lockable
  14.104 -{
  14.105 - public:
  14.106 -  Lockable()
  14.107 -  {
  14.108 -#if !defined(NDEBUG)
  14.109 -    owner_ = 0;
  14.110 -#endif
  14.111 -  }
  14.112 -  virtual ~Lockable() {
  14.113 -  }
  14.114 -
  14.115 -  bool TryLock() {
  14.116 -    if (DoTryLock()) {
  14.117 -      DebugSetLocked();
  14.118 -      return true;
  14.119 -    }
  14.120 -    return false;
  14.121 -  }
  14.122 -
  14.123 -  void Lock() {
  14.124 -    assert(Owner() != GetCurrentThreadId());
  14.125 -    DoLock();
  14.126 -    DebugSetLocked();
  14.127 -  }
  14.128 -
  14.129 -  void Unlock() {
  14.130 -    assert(Owner() == GetCurrentThreadId());
  14.131 -    DebugSetUnlocked();
  14.132 -    DoUnlock();
  14.133 -  }
  14.134 -
  14.135 -  void AssertCurrentThreadOwns() const {
  14.136 -    assert(Owner() == GetCurrentThreadId());
  14.137 -  }
  14.138 -#if !defined(NDEBUG)
  14.139 -  bool Locked() const {
  14.140 -    return owner_ != 0;
  14.141 -  }
  14.142 -  ThreadId Owner() const {
  14.143 -    return owner_;
  14.144 -  }
  14.145 -#endif
  14.146 -
  14.147 -  virtual bool DoTryLock() = 0;
  14.148 -  virtual void DoLock() = 0;
  14.149 -  virtual void DoUnlock() = 0;
  14.150 -
  14.151 - protected:
  14.152 -  void DebugSetUnlocked() {
  14.153 -#if !defined(NDEBUG)
  14.154 -    owner_ = 0;
  14.155 -#endif
  14.156 -  }
  14.157 -  void DebugSetLocked() {
  14.158 -#if !defined(NDEBUG)
  14.159 -    owner_ = GetCurrentThreadId();
  14.160 -#endif
  14.161 -  }
  14.162 -
  14.163 - protected:
  14.164 -#if !defined(NDEBUG)
  14.165 -  ThreadId owner_;
  14.166 -#endif
  14.167 -};
  14.168 -
  14.169 -// RAII for automatically locking and unlocking an object.
  14.170 -class AutoLock
  14.171 -{
  14.172 - public:
  14.173 -  AutoLock(Lockable *lock)
  14.174 -   : lock_(lock)
  14.175 -  {
  14.176 -    lock_->Lock();
  14.177 -  }
  14.178 -  ~AutoLock() {
  14.179 -    lock_->Unlock();
  14.180 -  }
  14.181 -
  14.182 - private:
  14.183 -  Lockable *lock_;
  14.184 -};
  14.185 -
  14.186 -class AutoTryLock
  14.187 -{
  14.188 - public:
  14.189 -  AutoTryLock(Lockable *lock)
  14.190 -  {
  14.191 -    lock_ = lock->TryLock() ? lock : NULL;
  14.192 -  }
  14.193 -  ~AutoTryLock() {
  14.194 -    if (lock_)
  14.195 -      lock_->Unlock();
  14.196 -  }
  14.197 -
  14.198 - private:
  14.199 -  Lockable *lock_;
  14.200 -};
  14.201 -
  14.202 -// RAII for automatically unlocking and relocking an object.
  14.203 -class AutoUnlock
  14.204 -{
  14.205 - public:
  14.206 -  AutoUnlock(Lockable *lock)
  14.207 -   : lock_(lock)
  14.208 -  {
  14.209 -    lock_->Unlock();
  14.210 -  }
  14.211 -  ~AutoUnlock() {
  14.212 -    lock_->Lock();
  14.213 -  }
  14.214 -
  14.215 - private:
  14.216 -  Lockable *lock_;
  14.217 -};
  14.218 -
  14.219 -enum WaitResult {
  14.220 -  // Woke up because something happened.
  14.221 -  Wait_Signaled,
  14.222 -
  14.223 -  // Woke up because nothing happened and a timeout was specified.
  14.224 -  Wait_Timeout,
  14.225 -
  14.226 -  // Woke up, but because of an error.
  14.227 -  Wait_Error
  14.228 -};
  14.229 -
  14.230 -// This must be implemented in order to spawn a new thread.
  14.231 -class IRunnable
  14.232 -{
  14.233 - public:
  14.234 -  virtual ~IRunnable() {
  14.235 -  }
  14.236 -
  14.237 -  virtual void Run() = 0;
  14.238 -};
  14.239 -
  14.240 -} // namespace ke
  14.241 -
  14.242 -// Include the actual thread implementations.
  14.243 -#if defined(_MSC_VER)
  14.244 -# include "ke_thread_windows.h"
  14.245 -#else
  14.246 -# include "ke_thread_posix.h"
  14.247 -#endif
  14.248 -
  14.249 -#endif // _include_sourcepawn_threads_
    15.1 --- a/public/sourcepawn/ke_thread_windows.h	Thu Aug 22 14:05:44 2013 -0700
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,148 +0,0 @@
    15.4 -// vim: set ts=8 sts=2 sw=2 tw=99 et:
    15.5 -//
    15.6 -// This file is part of SourcePawn.
    15.7 -// 
    15.8 -// SourcePawn is free software: you can redistribute it and/or modify
    15.9 -// it under the terms of the GNU General Public License as published by
   15.10 -// the Free Software Foundation, either version 3 of the License, or
   15.11 -// (at your option) any later version.
   15.12 -// 
   15.13 -// SourcePawn is distributed in the hope that it will be useful,
   15.14 -// but WITHOUT ANY WARRANTY; without even the implied warranty of
   15.15 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15.16 -// GNU General Public License for more details.
   15.17 -// 
   15.18 -// You should have received a copy of the GNU General Public License
   15.19 -// along with SourcePawn.  If not, see <http://www.gnu.org/licenses/>.
   15.20 -#ifndef _include_sourcepawn_thread_windows_h_
   15.21 -#define _include_sourcepawn_thread_windows_h_
   15.22 -
   15.23 -#include <windows.h>
   15.24 -
   15.25 -namespace ke {
   15.26 -
   15.27 -class CriticalSection : public Lockable
   15.28 -{
   15.29 - public:
   15.30 -  CriticalSection() {
   15.31 -    InitializeCriticalSection(&cs_);
   15.32 -  }
   15.33 -  ~CriticalSection() {
   15.34 -    DeleteCriticalSection(&cs_);
   15.35 -  }
   15.36 -
   15.37 -  bool DoTryLock() {
   15.38 -    return !!TryEnterCriticalSection(&cs_);
   15.39 -  }
   15.40 -  void DoLock() {
   15.41 -    EnterCriticalSection(&cs_);
   15.42 -  }
   15.43 -
   15.44 -  void DoUnlock() {
   15.45 -    LeaveCriticalSection(&cs_);
   15.46 -  }
   15.47 -
   15.48 - private:
   15.49 -  CRITICAL_SECTION cs_;
   15.50 -};
   15.51 -
   15.52 -typedef CriticalSection Mutex;
   15.53 -
   15.54 -// Currently, this class only supports single-listener CVs.
   15.55 -class ConditionVariable : public Lockable
   15.56 -{
   15.57 - public:
   15.58 -  ConditionVariable() {
   15.59 -    event_ = CreateEvent(NULL, FALSE, FALSE, NULL);
   15.60 -  }
   15.61 -  ~ConditionVariable() {
   15.62 -    CloseHandle(event_);
   15.63 -  }
   15.64 -
   15.65 -  bool DoTryLock() {
   15.66 -    return cs_.DoTryLock();
   15.67 -  }
   15.68 -  void DoLock() {
   15.69 -    cs_.DoLock();
   15.70 -  }
   15.71 -  void DoUnlock() {
   15.72 -    cs_.DoUnlock();
   15.73 -  }
   15.74 -
   15.75 -  void Notify() {
   15.76 -    AssertCurrentThreadOwns();
   15.77 -    SetEvent(event_);
   15.78 -  }
   15.79 -
   15.80 -  WaitResult Wait(size_t timeout_ms) {
   15.81 -    // This will assert if the lock has not been acquired. We don't need to be
   15.82 -    // atomic here, like pthread_cond_wait, because the event bit will stick
   15.83 -    // until reset by a wait function.
   15.84 -    Unlock();
   15.85 -    DWORD rv = WaitForSingleObject(event_, timeout_ms);
   15.86 -    Lock();
   15.87 -
   15.88 -    if (rv == WAIT_TIMEOUT)
   15.89 -      return Wait_Timeout;
   15.90 -    if (rv == WAIT_FAILED)
   15.91 -      return Wait_Error;
   15.92 -    return Wait_Signaled;
   15.93 -  }
   15.94 -
   15.95 -  WaitResult Wait() {
   15.96 -    return Wait(INFINITE);
   15.97 -  }
   15.98 -
   15.99 - private:
  15.100 -  CriticalSection cs_;
  15.101 -  HANDLE event_;
  15.102 -};
  15.103 -
  15.104 -class Thread
  15.105 -{
  15.106 - public:
  15.107 -  Thread(IRunnable *run, const char *name = NULL) {
  15.108 -    thread_ = CreateThread(NULL, 0, Main, run, 0, NULL);
  15.109 -  }
  15.110 -  ~Thread() {
  15.111 -    if (!thread_)
  15.112 -      return;
  15.113 -    CloseHandle(thread_);
  15.114 -  }
  15.115 -
  15.116 -  bool Succeeded() const {
  15.117 -    return !!thread_;
  15.118 -  }
  15.119 -
  15.120 -  void Join() {
  15.121 -    if (!Succeeded())
  15.122 -      return;
  15.123 -    WaitForSingleObject(thread_, INFINITE);
  15.124 -  }
  15.125 -
  15.126 -  HANDLE handle() const {
  15.127 -	  return thread_;
  15.128 -  }
  15.129 -
  15.130 - private:
  15.131 -  static DWORD WINAPI Main(LPVOID arg) {
  15.132 -    ((IRunnable *)arg)->Run();
  15.133 -    return 0;
  15.134 -  }
  15.135 -
  15.136 -#pragma pack(push, 8)
  15.137 -  struct ThreadNameInfo {
  15.138 -    DWORD dwType;
  15.139 -    LPCSTR szName;
  15.140 -    DWORD dwThreadID;
  15.141 -    DWORD dwFlags;
  15.142 -  };
  15.143 -#pragma pack(pop)
  15.144 -
  15.145 - private:
  15.146 -  HANDLE thread_;
  15.147 -};
  15.148 -
  15.149 -} // namespace ke
  15.150 -
  15.151 -#endif // _include_sourcepawn_thread_windows_h_
    16.1 --- a/public/sourcepawn/ke_utility.h	Thu Aug 22 14:05:44 2013 -0700
    16.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3 @@ -1,327 +0,0 @@
    16.4 -/* vim: set ts=4 sw=4 tw=99 et:
    16.5 - *
    16.6 - * Copyright (C) 2012-2013 David Anderson
    16.7 - *
    16.8 - * This file is part of SourcePawn.
    16.9 - *
   16.10 - * SourcePawn is free software: you can redistribute it and/or modify it under
   16.11 - * the terms of the GNU General Public License as published by the Free
   16.12 - * Software Foundation, either version 3 of the License, or (at your option)
   16.13 - * any later version.
   16.14 - * 
   16.15 - * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
   16.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   16.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   16.18 - *
   16.19 - * You should have received a copy of the GNU General Public License along with
   16.20 - * SourcePawn. If not, see http://www.gnu.org/licenses/.
   16.21 - */
   16.22 -#ifndef _include_jitcraft_utility_h_
   16.23 -#define _include_jitcraft_utility_h_
   16.24 -
   16.25 -#include <assert.h>
   16.26 -#include <stddef.h>
   16.27 -#include <stdlib.h>
   16.28 -#include <stdint.h>
   16.29 -#if defined(_MSC_VER)
   16.30 -# include <intrin.h>
   16.31 -#endif
   16.32 -
   16.33 -#define KE_32BIT
   16.34 -
   16.35 -#if defined(_MSC_VER)
   16.36 -# pragma warning(disable:4355)
   16.37 -#endif
   16.38 -
   16.39 -namespace ke {
   16.40 -
   16.41 -static const size_t kMallocAlignment = sizeof(void *) * 2;
   16.42 -
   16.43 -typedef uint8_t uint8;
   16.44 -typedef int32_t int32;
   16.45 -typedef uint32_t uint32;
   16.46 -typedef int64_t int64;
   16.47 -typedef uint64_t uint64;
   16.48 -
   16.49 -typedef uint8 * Address;
   16.50 -
   16.51 -static const size_t kKB = 1024;
   16.52 -static const size_t kMB = 1024 * kKB;
   16.53 -static const size_t kGB = 1024 * kMB;
   16.54 -
   16.55 -template <typename T> T
   16.56 -ReturnAndVoid(T &t)
   16.57 -{
   16.58 -    T saved = t;
   16.59 -    t = T();
   16.60 -    return saved;
   16.61 -}
   16.62 -
   16.63 -// Wrapper that automatically deletes its contents. The pointer can be taken
   16.64 -// to avoid destruction.
   16.65 -template <typename T>
   16.66 -class AutoPtr
   16.67 -{
   16.68 -    T *t_;
   16.69 -
   16.70 -  public:
   16.71 -    AutoPtr()
   16.72 -      : t_(NULL)
   16.73 -    {
   16.74 -    }
   16.75 -    explicit AutoPtr(T *t)
   16.76 -      : t_(t)
   16.77 -    {
   16.78 -    }
   16.79 -    ~AutoPtr() {
   16.80 -        delete t_;
   16.81 -    }
   16.82 -    T *take() {
   16.83 -        return ReturnAndVoid(t_);
   16.84 -    }
   16.85 -    T *operator *() const {
   16.86 -        return t_;
   16.87 -    }
   16.88 -    T *operator ->() const {
   16.89 -        return t_;
   16.90 -    }
   16.91 -    operator T *() const {
   16.92 -        return t_;
   16.93 -    }
   16.94 -    void operator =(T *t) {
   16.95 -        delete t_;
   16.96 -        t_ = t;
   16.97 -    }
   16.98 -    bool operator !() const {
   16.99 -        return !t_;
  16.100 -    }
  16.101 -};
  16.102 -
  16.103 -// Bob Jenkin's one-at-a-time hash function[1].
  16.104 -//
  16.105 -// [1] http://burtleburtle.net/bob/hash/doobs.html
  16.106 -class CharacterStreamHasher
  16.107 -{
  16.108 -    uint32 hash;
  16.109 -
  16.110 -  public:
  16.111 -    CharacterStreamHasher()
  16.112 -      : hash(0)
  16.113 -    { }
  16.114 -
  16.115 -    void add(char c) {
  16.116 -        hash += c;
  16.117 -        hash += (hash << 10);
  16.118 -        hash ^= (hash >> 6);
  16.119 -    }
  16.120 -
  16.121 -    void add(const char *s, size_t length) {
  16.122 -        for (size_t i = 0; i < length; i++)
  16.123 -            add(s[i]);
  16.124 -    }
  16.125 -
  16.126 -    uint32 result() {
  16.127 -        hash += (hash << 3);
  16.128 -        hash ^= (hash >> 11);
  16.129 -        hash += (hash << 15);
  16.130 -        return hash;
  16.131 -    }
  16.132 -};
  16.133 -
  16.134 -static inline uint32
  16.135 -HashCharSequence(const char *s, size_t length)
  16.136 -{
  16.137 -    CharacterStreamHasher hasher;
  16.138 -    hasher.add(s, length);
  16.139 -    return hasher.result();
  16.140 -}
  16.141 -
  16.142 -// From http://burtleburtle.net/bob/hash/integer.html
  16.143 -static inline uint32
  16.144 -HashInt32(int32 a)
  16.145 -{
  16.146 -    a = (a ^ 61) ^ (a >> 16);
  16.147 -    a = a + (a << 3);
  16.148 -    a = a ^ (a >> 4);
  16.149 -    a = a * 0x27d4eb2d;
  16.150 -    a = a ^ (a >> 15);
  16.151 -    return a;
  16.152 -}
  16.153 -
  16.154 -// From http://www.cris.com/~Ttwang/tech/inthash.htm
  16.155 -static inline uint32
  16.156 -HashInt64(int64 key)
  16.157 -{
  16.158 -  key = (~key) + (key << 18); // key = (key << 18) - key - 1;
  16.159 -  key = key ^ (uint64(key) >> 31);
  16.160 -  key = key * 21; // key = (key + (key << 2)) + (key << 4);
  16.161 -  key = key ^ (uint64(key) >> 11);
  16.162 -  key = key + (key << 6);
  16.163 -  key = key ^ (uint64(key) >> 22);
  16.164 -  return uint32(key);
  16.165 -}
  16.166 -
  16.167 -static inline uint32
  16.168 -HashPointer(void *p)
  16.169 -{
  16.170 -#if defined(KE_32BIT)
  16.171 -    return HashInt32(reinterpret_cast<int32>(p));
  16.172 -#elif defined(KE_64BIT)
  16.173 -    return HashInt64(reinterpret_cast<int64>(p));
  16.174 -#endif
  16.175 -}
  16.176 -
  16.177 -static inline size_t
  16.178 -Log2(size_t number)
  16.179 -{
  16.180 -    assert(number != 0);
  16.181 -
  16.182 -#ifdef _MSC_VER
  16.183 -    unsigned long rval;
  16.184 -# ifdef _M_IX86
  16.185 -    _BitScanReverse(&rval, number);
  16.186 -# elif _M_X64
  16.187 -    _BitScanReverse64(&rval, number);
  16.188 -# endif
  16.189 -    return rval;
  16.190 -#else
  16.191 -    size_t bit;
  16.192 -    asm("bsr %1, %0\n"
  16.193 -        : "=r" (bit)
  16.194 -        : "rm" (number));
  16.195 -    return bit;
  16.196 -#endif
  16.197 -}
  16.198 -
  16.199 -static inline size_t
  16.200 -FindRightmostBit(size_t number)
  16.201 -{
  16.202 -    assert(number != 0);
  16.203 -
  16.204 -#ifdef _MSC_VER
  16.205 -    unsigned long rval;
  16.206 -# ifdef _M_IX86
  16.207 -    _BitScanForward(&rval, number);
  16.208 -# elif _M_X64
  16.209 -    _BitScanForward64(&rval, number);
  16.210 -# endif
  16.211 -    return rval;
  16.212 -#else
  16.213 -    size_t bit;
  16.214 -    asm("bsf %1, %0\n"
  16.215 -        : "=r" (bit)
  16.216 -        : "rm" (number));
  16.217 -    return bit;
  16.218 -#endif
  16.219 -}
  16.220 -
  16.221 -static inline bool
  16.222 -IsPowerOfTwo(size_t value)
  16.223 -{
  16.224 -    if (value == 0)
  16.225 -        return false;
  16.226 -    return !(value & (value - 1));
  16.227 -}
  16.228 -
  16.229 -static inline size_t
  16.230 -Align(size_t count, size_t alignment)
  16.231 -{
  16.232 -    assert(IsPowerOfTwo(alignment));
  16.233 -    return count + (alignment - (count % alignment)) % alignment;
  16.234 -}
  16.235 -
  16.236 -static inline bool
  16.237 -IsUint32AddSafe(unsigned a, unsigned b)
  16.238 -{
  16.239 -    if (!a || !b)
  16.240 -        return true;
  16.241 -    size_t log2_a = Log2(a);
  16.242 -    size_t log2_b = Log2(b);
  16.243 -    return (log2_a < sizeof(unsigned) * 8) &&
  16.244 -           (log2_b < sizeof(unsigned) * 8);
  16.245 -}
  16.246 -
  16.247 -static inline bool
  16.248 -IsUintPtrAddSafe(size_t a, size_t b)
  16.249 -{
  16.250 -    if (!a || !b)
  16.251 -        return true;
  16.252 -    size_t log2_a = Log2(a);
  16.253 -    size_t log2_b = Log2(b);
  16.254 -    return (log2_a < sizeof(size_t) * 8) &&
  16.255 -           (log2_b < sizeof(size_t) * 8);
  16.256 -}
  16.257 -
  16.258 -static inline bool
  16.259 -IsUint32MultiplySafe(unsigned a, unsigned b)
  16.260 -{
  16.261 -    if (a <= 1 || b <= 1)
  16.262 -        return true;
  16.263 -
  16.264 -    size_t log2_a = Log2(a);
  16.265 -    size_t log2_b = Log2(b);
  16.266 -    return log2_a + log2_b <= sizeof(unsigned) * 8;
  16.267 -}
  16.268 -
  16.269 -static inline bool
  16.270 -IsUintPtrMultiplySafe(size_t a, size_t b)
  16.271 -{
  16.272 -    if (a <= 1 || b <= 1)
  16.273 -        return true;
  16.274 -
  16.275 -    size_t log2_a = Log2(a);
  16.276 -    size_t log2_b = Log2(b);
  16.277 -    return log2_a + log2_b <= sizeof(size_t) * 8;
  16.278 -}
  16.279 -
  16.280 -#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(array[0]))
  16.281 -#define STATIC_ASSERT(cond) extern int static_assert_f(int a[(cond) ? 1 : -1])
  16.282 -
  16.283 -#define IS_ALIGNED(addr, alignment)    (!(uintptr_t(addr) & ((alignment) - 1)))
  16.284 -
  16.285 -template <typename T>
  16.286 -static inline bool
  16.287 -IsAligned(T addr, size_t alignment)
  16.288 -{
  16.289 -    assert(IsPowerOfTwo(alignment));
  16.290 -    return !(uintptr_t(addr) & (alignment - 1));
  16.291 -}
  16.292 -
  16.293 -static inline Address
  16.294 -AlignedBase(Address addr, size_t alignment)
  16.295 -{
  16.296 -    assert(IsPowerOfTwo(alignment));
  16.297 -    return Address(uintptr_t(addr) & ~(alignment - 1));
  16.298 -}
  16.299 -
  16.300 -template <typename T> static inline T
  16.301 -Min(const T &t1, const T &t2)
  16.302 -{
  16.303 -    return t1 < t2 ? t1 : t2;
  16.304 -}
  16.305 -
  16.306 -template <typename T> static inline T
  16.307 -Max(const T &t1, const T &t2)
  16.308 -{
  16.309 -    return t1 > t2 ? t1 : t2;
  16.310 -}
  16.311 -
  16.312 -#define OFFSETOF(Class, Member) reinterpret_cast<size_t>(&((Class *)NULL)->Member)
  16.313 -
  16.314 -#if defined(_MSC_VER)
  16.315 -# define KE_SIZET_FMT           "%Iu"
  16.316 -#elif defined(__GNUC__)
  16.317 -# define KE_SIZET_FMT           "%zu"
  16.318 -#else
  16.319 -# error "Implement format specifier string"
  16.320 -#endif
  16.321 -
  16.322 -#if defined(__GNUC__)
  16.323 -# define KE_CRITICAL_LIKELY(x)  __builtin_expect(!!(x), 1)
  16.324 -#else
  16.325 -# define KE_CRITICAL_LIKELY(x)  x
  16.326 -#endif
  16.327 -
  16.328 -}
  16.329 -
  16.330 -#endif // _include_jitcraft_utility_h_
    17.1 --- a/public/sourcepawn/ke_vector.h	Thu Aug 22 14:05:44 2013 -0700
    17.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.3 @@ -1,166 +0,0 @@
    17.4 -/* vim: set ts=2 sw=2 tw=99 et:
    17.5 - *
    17.6 - * Copyright (C) 2012 David Anderson
    17.7 - *
    17.8 - * This file is part of SourcePawn.
    17.9 - *
   17.10 - * SourcePawn is free software: you can redistribute it and/or modify it under
   17.11 - * the terms of the GNU General Public License as published by the Free
   17.12 - * Software Foundation, either version 3 of the License, or (at your option)
   17.13 - * any later version.
   17.14 - * 
   17.15 - * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
   17.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   17.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   17.18 - *
   17.19 - * You should have received a copy of the GNU General Public License along with
   17.20 - * SourcePawn. If not, see http://www.gnu.org/licenses/.
   17.21 - */
   17.22 -#ifndef _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_
   17.23 -#define _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_
   17.24 -
   17.25 -#include <new>
   17.26 -#include <stdlib.h>
   17.27 -#include <ke_allocator_policies.h>
   17.28 -#include <ke_utility.h>
   17.29 -
   17.30 -namespace ke {
   17.31 -
   17.32 -template <typename T, typename AllocPolicy = SystemAllocatorPolicy>
   17.33 -class Vector : public AllocPolicy
   17.34 -{
   17.35 - public:
   17.36 -  Vector(AllocPolicy = AllocPolicy())
   17.37 -  : data(NULL),
   17.38 -    nitems(0),
   17.39 -    maxsize(0)
   17.40 -  {
   17.41 -  }
   17.42 -
   17.43 -  ~Vector()
   17.44 -  {
   17.45 -    zap();
   17.46 -  }
   17.47 -
   17.48 -  void steal(Vector &other) {
   17.49 -    zap();
   17.50 -    data = other.data;
   17.51 -    nitems = other.nitems;
   17.52 -    maxsize = other.maxsize;
   17.53 -    other.reset();
   17.54 -  }
   17.55 -
   17.56 -  bool append(const T& item) {
   17.57 -    if (!growIfNeeded(1))
   17.58 -      return false;
   17.59 -    new (&data[nitems]) T(item);
   17.60 -    nitems++;
   17.61 -    return true;
   17.62 -  }
   17.63 -  void infallibleAppend(const T &item) {
   17.64 -    assert(growIfNeeded(1));
   17.65 -    new (&data[nitems]) T(item);
   17.66 -    nitems++;
   17.67 -  }
   17.68 -  T popCopy() {
   17.69 -    T t = at(length() - 1);
   17.70 -    pop();
   17.71 -    return t;
   17.72 -  }
   17.73 -  void pop() {
   17.74 -    assert(nitems);
   17.75 -    data[nitems - 1].~T();
   17.76 -    nitems--;
   17.77 -  }
   17.78 -  bool empty() const {
   17.79 -    return length() == 0;
   17.80 -  }
   17.81 -  size_t length() const {
   17.82 -    return nitems;
   17.83 -  }
   17.84 -  T& at(size_t i) {
   17.85 -    assert(i < length());
   17.86 -    return data[i];
   17.87 -  }
   17.88 -  const T& at(size_t i) const {
   17.89 -    assert(i < length());
   17.90 -    return data[i];
   17.91 -  }
   17.92 -  T& operator [](size_t i) {
   17.93 -    return at(i);
   17.94 -  }
   17.95 -  const T& operator [](size_t i) const {
   17.96 -    return at(i);
   17.97 -  }
   17.98 -  void clear() {
   17.99 -    nitems = 0;
  17.100 -  }
  17.101 -  const T &back() const {
  17.102 -    return at(length() - 1);
  17.103 -  }
  17.104 -  T &back() {
  17.105 -    return at(length() - 1);
  17.106 -  }
  17.107 -
  17.108 -  T *buffer() const {
  17.109 -    return data;
  17.110 -  }
  17.111 -
  17.112 -  bool ensure(size_t desired) {
  17.113 -    if (desired <= length())
  17.114 -      return true;
  17.115 -
  17.116 -    return growIfNeeded(desired - length());
  17.117 -  }
  17.118 -
  17.119 - private:
  17.120 -  void zap() {
  17.121 -    for (size_t i = 0; i < nitems; i++)
  17.122 -      data[i].~T();
  17.123 -    this->free(data);
  17.124 -  }
  17.125 -  void reset() {
  17.126 -    data = NULL;
  17.127 -    nitems = 0;
  17.128 -    maxsize = 0;
  17.129 -  }
  17.130 -
  17.131 -  bool growIfNeeded(size_t needed)
  17.132 -  {
  17.133 -    if (!IsUintPtrAddSafe(nitems, needed)) {
  17.134 -      this->reportAllocationOverflow();
  17.135 -      return false;
  17.136 -    }
  17.137 -    if (nitems + needed < maxsize)
  17.138 -      return true;
  17.139 -    if (maxsize == 0)
  17.140 -      maxsize = 8;
  17.141 -    while (nitems + needed > maxsize) {
  17.142 -      if (!IsUintPtrMultiplySafe(maxsize, 2)) {
  17.143 -        this->reportAllocationOverflow();
  17.144 -        return false;
  17.145 -      }
  17.146 -      maxsize *= 2;
  17.147 -    }
  17.148 -    T* newdata = (T*)this->malloc(sizeof(T) * maxsize);
  17.149 -    if (newdata == NULL)
  17.150 -      return false;
  17.151 -    for (size_t i = 0; i < nitems; i++) {
  17.152 -      new (&newdata[i]) T(data[i]);
  17.153 -      data[i].~T();
  17.154 -    }
  17.155 -    this->free(data);
  17.156 -    data = newdata;
  17.157 -    return true;
  17.158 -  }
  17.159 -
  17.160 - private:
  17.161 -  T* data;
  17.162 -  size_t nitems;
  17.163 -  size_t maxsize;
  17.164 -};
  17.165 -
  17.166 -}
  17.167 -
  17.168 -#endif /* _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_ */
  17.169 -
    18.1 --- a/sourcepawn/jit/AMBuilder	Thu Aug 22 14:05:44 2013 -0700
    18.2 +++ b/sourcepawn/jit/AMBuilder	Thu Aug 22 16:30:44 2013 -0700
    18.3 @@ -8,6 +8,7 @@
    18.4  compiler['CXXINCLUDES'].append(os.path.join(base, 'sourcepawn', 'jit', 'x86'))
    18.5  compiler['CXXINCLUDES'].append(os.path.join(base, 'public'))
    18.6  compiler['CXXINCLUDES'].append(os.path.join(base, 'public', 'sourcepawn'))
    18.7 +compiler['CXXINCLUDES'].append(os.path.join(base, 'public', 'amtl'))
    18.8  compiler['CXXINCLUDES'].append(os.path.join(base, 'public', 'jit'))
    18.9  compiler['CXXINCLUDES'].append(os.path.join(base, 'public', 'jit', 'x86'))
   18.10  compiler['CXXINCLUDES'].append(os.path.join(base, 'knight', 'shared'))