Index: third_party/smartany/shared_any.cc |
diff --git a/third_party/smartany/shared_any.cc b/third_party/smartany/shared_any.cc |
deleted file mode 100644 |
index 064001d5422dd3b0c78292d6896b1eb8130b04f6..0000000000000000000000000000000000000000 |
--- a/third_party/smartany/shared_any.cc |
+++ /dev/null |
@@ -1,246 +0,0 @@ |
-//+--------------------------------------------------------------------------- |
-// |
-// Copyright ( C ) Microsoft, 2002. |
-// |
-// File: shared_any.cpp |
-// |
-// Contents: pool allocator for reference counts |
-// |
-// Classes: ref_count_allocator and helpers |
-// |
-// Functions: |
-// |
-// Author: Eric Niebler ( ericne@microsoft.com ) |
-// |
-//---------------------------------------------------------------------------- |
- |
-#ifdef _MT |
-# ifndef _WIN32_WINNT |
-# define _WIN32_WINNT 0x0403 |
-# endif |
-# include <windows.h> |
-# include <unknwn.h> |
-#endif |
- |
-#include <cassert> |
-#include <functional> // for std::less |
-#include <algorithm> // for std::swap |
- |
-#pragma warning(push) |
-// C4640: construction of local static object is not thread-safe |
-#pragma warning(disable : 4640) |
-#include "shared_any.h" |
-#include "scoped_any.h" |
-#pragma warning(pop) |
- |
-namespace detail |
-{ |
- struct critsec |
- { |
-#ifdef _MT |
- CRITICAL_SECTION m_cs; |
- |
- critsec() |
- { |
- InitializeCriticalSectionAndSpinCount( &m_cs, 4000 ); |
- } |
- ~critsec() |
- { |
- DeleteCriticalSection( &m_cs ); |
- } |
- void enter() |
- { |
- EnterCriticalSection( &m_cs ); |
- } |
- void leave() |
- { |
- LeaveCriticalSection( &m_cs ); |
- } |
-#endif |
- }; |
- |
- namespace |
- { |
- critsec g_critsec; |
- } |
- |
- struct lock |
- { |
-#ifdef _MT |
- critsec & m_cs; |
- |
- explicit lock( critsec & cs ) |
- : m_cs(cs) |
- { |
- m_cs.enter(); |
- } |
- ~lock() |
- { |
- m_cs.leave(); |
- } |
-#else |
- explicit lock( critsec & ) |
- { |
- } |
-#endif |
- private: |
- lock( lock const & ); |
- lock & operator=( lock const & ); |
- }; |
- |
- struct ref_count_block |
- { |
- static long const s_sizeBlock = 256; |
- |
- short m_free_list; // offset to start of freelist |
- short m_available; // count of refcounts in this block that are available |
- long m_refcounts[ s_sizeBlock ]; |
- |
- ref_count_block() |
- : m_free_list(0), m_available(s_sizeBlock) |
- { |
- for( long l=0; l<s_sizeBlock; ++l ) |
- m_refcounts[l] = l+1; |
- } |
- |
- bool empty() const // throw() |
- { |
- return s_sizeBlock == m_available; |
- } |
- |
- bool full() const // throw() |
- { |
- return 0 == m_available; |
- } |
- |
- long volatile *alloc( lock & ) |
- { |
- assert( 0 != m_available ); |
- long *refcount = m_refcounts + m_free_list; |
- m_free_list = static_cast<short>( *refcount ); |
- --m_available; |
- return refcount; |
- } |
- |
- void free( long volatile *refcount, lock & ) // throw() |
- { |
- assert( owns( refcount ) ); |
- *refcount = m_free_list; |
- m_free_list = static_cast<short>( refcount - m_refcounts ); |
- ++m_available; |
- } |
- |
- bool owns( long volatile *refcount ) const // throw() |
- { |
- return ! std::less<void*>()( const_cast<long*>( refcount ), const_cast<long*>( m_refcounts ) ) && |
- std::less<void*>()( const_cast<long*>( refcount ), const_cast<long*>( m_refcounts ) + s_sizeBlock ); |
- } |
- }; |
- |
- |
- struct ref_count_allocator::node |
- { |
- node *m_next; |
- node *m_prev; |
- ref_count_block m_block; |
- explicit node( node *next=0, node *prev=0 ) |
- : m_next(next), m_prev(prev), m_block() |
- { |
- if( m_next ) |
- m_next->m_prev = this; |
- if( m_prev ) |
- m_prev->m_next = this; |
- } |
- }; |
- |
- |
- ref_count_allocator::ref_count_allocator() |
- : m_list_blocks(0), m_last_alloc(0), m_last_free(0) |
- { |
- } |
- |
- ref_count_allocator::~ref_count_allocator() |
- { |
- // Just leak the blocks. It's ok, really. |
- // If you need to clean up the blocks and |
- // you are certain that no refcounts are |
- // outstanding, you can use the finalize() |
- // method to force deallocation |
- } |
- |
- void ref_count_allocator::finalize() |
- { |
- lock l( g_critsec ); |
- for( node *next; m_list_blocks; m_list_blocks=next ) |
- { |
- next = m_list_blocks->m_next; |
- delete m_list_blocks; |
- } |
- m_last_alloc = 0; |
- m_last_free = 0; |
- } |
- |
- long volatile *ref_count_allocator::alloc() |
- { |
- lock l( g_critsec ); |
- if( ! m_last_alloc || m_last_alloc->m_block.full() ) |
- { |
- for( m_last_alloc = m_list_blocks; |
- m_last_alloc && m_last_alloc->m_block.full(); |
- m_last_alloc = m_last_alloc->m_next ); |
- if( ! m_last_alloc ) |
- { |
- m_last_alloc = new( std::nothrow ) node( m_list_blocks ); |
- if( ! m_last_alloc ) |
- return 0; |
- m_list_blocks = m_last_alloc; |
- } |
- } |
- return m_last_alloc->m_block.alloc( l ); |
- } |
- |
- long volatile *ref_count_allocator::alloc( long val ) |
- { |
- long volatile *refcount = alloc(); |
- *refcount = val; |
- return refcount; |
- } |
- |
- void ref_count_allocator::free( long volatile *refcount ) // throw() |
- { |
- // don't rearrange the order of these locals! |
- scoped_any<node*,close_delete> scoped_last_free; |
- lock l( g_critsec ); |
- |
- if( ! m_last_free || ! m_last_free->m_block.owns( refcount ) ) |
- { |
- for( m_last_free = m_list_blocks; |
- m_last_free && ! m_last_free->m_block.owns( refcount ); |
- m_last_free = m_last_free->m_next ); |
- } |
- |
- assert( m_last_free && m_last_free->m_block.owns( refcount ) ); |
- m_last_free->m_block.free( refcount, l ); |
- |
- if( m_last_free != m_list_blocks && m_last_free->m_block.empty() ) |
- { |
- if( 0 != ( m_last_free->m_prev->m_next = m_last_free->m_next ) ) |
- m_last_free->m_next->m_prev = m_last_free->m_prev; |
- |
- if( ! m_list_blocks->m_block.empty() ) |
- { |
- m_last_free->m_next = m_list_blocks; |
- m_last_free->m_prev = 0; |
- m_list_blocks->m_prev = m_last_free; |
- m_list_blocks = m_last_free; |
- } |
- else |
- reset( scoped_last_free, m_last_free ); // deleted after critsec is released |
- |
- m_last_free = 0; |
- } |
- } |
- |
- // Here is the global reference count allocator. |
- ref_count_allocator ref_count_allocator::instance; |
-} |