move boilerplate overrun protect code into OverrunProtector

This was SVN commit r3046.
This commit is contained in:
janwas 2005-10-29 17:58:26 +00:00
parent abee717a26
commit bc78557f10
2 changed files with 71 additions and 54 deletions

View File

@ -124,4 +124,70 @@ extern void** matrix_alloc(uint cols, uint rows, size_t el_size);
// (e.g. int**); they must be cast to void**.
extern void matrix_free(void** matrix);
template<class T> class OverrunProtector
{
DynArray da;
T* cached_ptr;
uintptr_t initialized;
public:
OverrunProtector()
{
memset(&da, 0, sizeof(da));
cached_ptr = 0;
initialized = 0;
}
~OverrunProtector()
{
initialized = 2;
cached_ptr->~T(); // call dtor (since we used placement new)
cached_ptr = 0;
(void)da_free(&da);
}
void lock()
{
da_set_prot(&da, PROT_NONE);
}
private:
void unlock()
{
da_set_prot(&da, PROT_READ|PROT_WRITE);
}
void init()
{
const size_t size = 4096;
cassert(sizeof(T) <= size);
if(da_alloc(&da, size) < 0)
goto fail;
if(da_set_size(&da, size) < 0)
goto fail;
#include "nommgr.h"
cached_ptr = new(da.base) T();
#include "mmgr.h"
lock();
return; // success
fail:
debug_warn("OverrunProtector mem alloc failed");
}
public:
T* get()
{
if(CAS(&initialized, 0, 1))
init();
debug_assert(initialized != 2 && "OverrunProtector: used after dtor called:");
unlock();
return cached_ptr;
}
};
#endif // #ifndef ALLOCATORS_H__

View File

@ -339,60 +339,13 @@ static int free_idx(i32 idx)
typedef STL_HASH_MULTIMAP<uintptr_t, i32> Key2Idx;
typedef Key2Idx::iterator It;
static DynArray key2idx_da;
static Key2Idx* key2idx_;
static void key2idx_lock()
{
da_set_prot(&key2idx_da, PROT_NONE);
}
static void key2idx_unlock()
{
da_set_prot(&key2idx_da, PROT_READ|PROT_WRITE);
}
static void key2idx_init(void)
{
const size_t size = 4096;
cassert(sizeof(Key2Idx) <= size);
if(da_alloc(&key2idx_da, size) < 0)
goto fail;
if(da_set_size(&key2idx_da, size) < 0)
goto fail;
#include "nommgr.h"
key2idx_ = new(key2idx_da.base) Key2Idx;
#include "mmgr.h"
key2idx_lock();
return; // success
fail:
debug_warn("key2idx mem alloc failed");
}
static void key2idx_shutdown()
{
key2idx_ = 0;
(void)da_free(&key2idx_da);
}
static Key2Idx* key2idx_get()
{
static pthread_once_t key2idx_once = PTHREAD_ONCE_INIT;
pthread_once(&key2idx_once, key2idx_init);
key2idx_unlock();
return key2idx_;
}
static OverrunProtector<Key2Idx> key2idx_wrapper;
enum KeyRemoveFlag { KEY_NOREMOVE, KEY_REMOVE };
static Handle key_find(uintptr_t key, H_Type type, KeyRemoveFlag remove_option = KEY_NOREMOVE)
{
Key2Idx* key2idx = key2idx_get();
Key2Idx* key2idx = key2idx_wrapper.get();
if(!key2idx)
return ERR_NO_MEM;
@ -417,14 +370,14 @@ static Handle key_find(uintptr_t key, H_Type type, KeyRemoveFlag remove_option =
}
}
key2idx_lock();
key2idx_wrapper.lock();
return ret;
}
static void key_add(uintptr_t key, Handle h)
{
Key2Idx* key2idx = key2idx_get();
Key2Idx* key2idx = key2idx_wrapper.get();
if(!key2idx)
return;
@ -433,7 +386,7 @@ static void key_add(uintptr_t key, Handle h)
// there is no overload of insert() that returns pair<iterator, bool>.
(void)key2idx->insert(std::make_pair(key, idx));
key2idx_lock();
key2idx_wrapper.lock();
}
@ -1020,6 +973,4 @@ void h_mgr_shutdown()
}
fn_shutdown();
key2idx_shutdown();
}