Signed-off-by: Hua meng 161220092@smail.nju.edu.cn --- dlls/msvcp90/misc.c | 234 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 155 insertions(+), 79 deletions(-)
diff --git a/dlls/msvcp90/misc.c b/dlls/msvcp90/misc.c index c4671d469e..45d242066c 100644 --- a/dlls/msvcp90/misc.c +++ b/dlls/msvcp90/misc.c @@ -1771,6 +1771,7 @@ DEFINE_RTTI_DATA0(_Runtime_object, 0, ".?AV_Runtime_object@details@Concurrency@@
#endif
+#if _MSVCP_VER >= 100 typedef struct __Concurrent_vector_base_v4 { void* (__cdecl *allocator)(struct __Concurrent_vector_base_v4 *, MSVCP_size_t); @@ -1783,6 +1784,122 @@ typedef struct __Concurrent_vector_base_v4 #define STORAGE_SIZE (sizeof(this->storage) / sizeof(this->storage[0])) #define SEGMENT_SIZE (sizeof(void*) * 8)
+/* based on wined3d_log2i from wined3d.h */ +/* Return the integer base-2 logarithm of (x|1). Result is 0 for x == 0. */ +static inline unsigned int log2i(unsigned int x) +{ +#ifdef HAVE___BUILTIN_CLZ + return __builtin_clz(x|1) ^ 0x1f; +#else + static const unsigned int l[] = + { + ~0u, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + }; + unsigned int i; + + x |= 1; + return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x]; +#endif +} + +/* ?_Segment_index_of@_Concurrent_vector_base_v4@details@Concurrency@@KAII@Z */ +/* ?_Segment_index_of@_Concurrent_vector_base_v4@details@Concurrency@@KA_K_K@Z */ +MSVCP_size_t __cdecl _vector_base_v4__Segment_index_of(MSVCP_size_t x) +{ + unsigned int half; + + TRACE("(%lu)\n", x); + + if((sizeof(x) == 8) && (half = x >> 32)) + return log2i(half) + 32; + + return log2i(x); +} + +/* ?_Internal_throw_exception@_Concurrent_vector_base_v4@details@Concurrency@@IBEXI@Z */ +/* ?_Internal_throw_exception@_Concurrent_vector_base_v4@details@Concurrency@@IEBAX_K@Z */ +DEFINE_THISCALL_WRAPPER(_vector_base_v4__Internal_throw_exception, 8) +void __thiscall _vector_base_v4__Internal_throw_exception(void/*_vector_base_v4*/ *this, MSVCP_size_t idx) +{ + static const struct { + exception_type type; + const char *msg; + } exceptions[] = { + { EXCEPTION_OUT_OF_RANGE, "Index out of range" }, + { EXCEPTION_OUT_OF_RANGE, "Index out of segments table range" }, + { EXCEPTION_RANGE_ERROR, "Index is inside segment which failed to be allocated" }, + }; + + TRACE("(%p %lu)\n", this, idx); + + if(idx < ARRAY_SIZE(exceptions)) + throw_exception(exceptions[idx].type, exceptions[idx].msg); +} + +#ifdef _WIN64 +#define InterlockedCompareExchangeSizeT(dest, exchange, cmp) InterlockedCompareExchangeSize((MSVCP_size_t *)dest, (MSVCP_size_t)exchange, (MSVCP_size_t)cmp) +static MSVCP_size_t InterlockedCompareExchangeSize(MSVCP_size_t volatile *dest, MSVCP_size_t exchange, MSVCP_size_t cmp) +{ + MSVCP_size_t v; + + v = InterlockedCompareExchange64((LONGLONG*)dest, exchange, cmp); + + return v; +} +#else +#define InterlockedCompareExchangeSizeT(dest, exchange, cmp) InterlockedCompareExchange((LONG*)dest, (MSVCP_size_t)exchange, (MSVCP_size_t)cmp) +#endif + +#define SEGMENT_ALLOC_MARKER ((void*)1) + +static void concurrent_vector_alloc_segment(_Concurrent_vector_base_v4 *this, + MSVCP_size_t seg, MSVCP_size_t element_size) +{ + int spin; + + while(!this->segment[seg] || this->segment[seg] == SEGMENT_ALLOC_MARKER) + { + spin = 0; + while(this->segment[seg] == SEGMENT_ALLOC_MARKER) + spin_wait(&spin); + if(!InterlockedCompareExchangeSizeT((this->segment + seg), + SEGMENT_ALLOC_MARKER, 0)) + __TRY + { + if(seg == 0) + this->segment[seg] = this->allocator(this, element_size * (1 << this->first_block)); + else if(seg < this->first_block) + this->segment[seg] = (BYTE**)this->segment[0] + + element_size * (1 << seg); + else + this->segment[seg] = this->allocator(this, element_size * (1 << seg)); + } + __EXCEPT_ALL + { + this->segment[seg] = NULL; + throw_exception(EXCEPTION_RERAISE, NULL); + } + __ENDTRY + if(!this->segment[seg]) + _vector_base_v4__Internal_throw_exception(this, 2); + } +} + /* ??1_Concurrent_vector_base_v4@details@Concurrency@@IAE@XZ */ /* ??1_Concurrent_vector_base_v4@details@Concurrency@@IEAA@XZ */ DEFINE_THISCALL_WRAPPER(_Concurrent_vector_base_v4_dtor, 4) @@ -1827,6 +1944,43 @@ MSVCP_size_t __thiscall _Concurrent_vector_base_v4__Internal_capacity( return 1 << i; }
+/* ?_Internal_reserve@_Concurrent_vector_base_v4@details@Concurrency@@IAEXIII@Z */ +/* ?_Internal_reserve@_Concurrent_vector_base_v4@details@Concurrency@@IEAAX_K00@Z */ +DEFINE_THISCALL_WRAPPER(_Concurrent_vector_base_v4__Internal_reserve, 16) +void __thiscall _Concurrent_vector_base_v4__Internal_reserve( + _Concurrent_vector_base_v4 *this, MSVCP_size_t size, + MSVCP_size_t element_size, MSVCP_size_t max_size) +{ + MSVCP_size_t block_idx, capacity; + int i; + void **new_segment; + + TRACE("(%p %ld %ld %ld)\n", this, size, element_size, max_size); + + if(size > max_size) _vector_base_v4__Internal_throw_exception(this, 0); + capacity = _Concurrent_vector_base_v4__Internal_capacity(this); + if(size <= capacity) return; + block_idx = _vector_base_v4__Segment_index_of(size - 1); + if(!this->first_block) + InterlockedCompareExchangeSizeT(&this->first_block, block_idx + 1, 0); + i = _vector_base_v4__Segment_index_of(capacity); + if(this->storage == this->segment) { + for(; i <= block_idx && i < STORAGE_SIZE; i++) + concurrent_vector_alloc_segment(this, i, element_size); + if(block_idx >= STORAGE_SIZE) { + new_segment = malloc(SEGMENT_SIZE * sizeof(void*)); + if(new_segment == NULL) _vector_base_v4__Internal_throw_exception(this, 2); + memset(new_segment, 0, SEGMENT_SIZE * sizeof(*new_segment)); + memcpy(new_segment, this->storage, STORAGE_SIZE * sizeof(*new_segment)); + if(InterlockedCompareExchangePointer((void*)&this->segment, new_segment, + this->storage) != this->storage) + free(new_segment); + } + } + for(; i <= block_idx; i++) + concurrent_vector_alloc_segment(this, i, element_size); +} + /* ?_Internal_clear@_Concurrent_vector_base_v4@details@Concurrency@@IAEIP6AXPAXI@Z@Z */ /* ?_Internal_clear@_Concurrent_vector_base_v4@details@Concurrency@@IEAA_KP6AXPEAX_K@Z@Z */ DEFINE_THISCALL_WRAPPER(_Concurrent_vector_base_v4__Internal_clear, 8) @@ -1891,16 +2045,6 @@ void * __thiscall _Concurrent_vector_base_v4__Internal_push_back( return NULL; }
-/* ?_Internal_reserve@_Concurrent_vector_base_v4@details@Concurrency@@IAEXIII@Z */ -/* ?_Internal_reserve@_Concurrent_vector_base_v4@details@Concurrency@@IEAAX_K00@Z */ -DEFINE_THISCALL_WRAPPER(_Concurrent_vector_base_v4__Internal_reserve, 16) -void __thiscall _Concurrent_vector_base_v4__Internal_reserve( - _Concurrent_vector_base_v4 *this, MSVCP_size_t len1, - MSVCP_size_t len2, MSVCP_size_t len3) -{ - FIXME("(%p %ld %ld %ld) stub\n", this, len1, len2, len3); -} - /* ?_Internal_resize@_Concurrent_vector_base_v4@details@Concurrency@@IAEXIIIP6AXPAXI@ZP6AX0PBXI@Z2@Z */ /* ?_Internal_resize@_Concurrent_vector_base_v4@details@Concurrency@@IEAAX_K00P6AXPEAX0@ZP6AX1PEBX0@Z3@Z */ DEFINE_THISCALL_WRAPPER(_Concurrent_vector_base_v4__Internal_resize, 28) @@ -1920,6 +2064,7 @@ void __thiscall _Concurrent_vector_base_v4__Internal_swap( { FIXME("(%p %p) stub\n", this, v); } +#endif
#ifndef __GNUC__ void __asm_dummy_vtables(void) { @@ -2392,75 +2537,6 @@ _Ph _Ph_11 = {0}, _Ph_12 = {0}, _Ph_13 = {0}, _Ph_14 = {0}, _Ph_15 = {0}; _Ph _Ph_16 = {0}, _Ph_17 = {0}, _Ph_18 = {0}, _Ph_19 = {0}, _Ph_20 = {0}; #endif
-#if _MSVCP_VER >= 100 -/* based on wined3d_log2i from wined3d.h */ -/* Return the integer base-2 logarithm of (x|1). Result is 0 for x == 0. */ -static inline unsigned int log2i(unsigned int x) -{ -#ifdef HAVE___BUILTIN_CLZ - return __builtin_clz(x|1) ^ 0x1f; -#else - static const unsigned int l[] = - { - ~0u, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - }; - unsigned int i; - - x |= 1; - return (i = x >> 16) ? (x = i >> 8) ? l[x] + 24 : l[i] + 16 : (i = x >> 8) ? l[i] + 8 : l[x]; -#endif -} - -/* ?_Segment_index_of@_Concurrent_vector_base_v4@details@Concurrency@@KAII@Z */ -/* ?_Segment_index_of@_Concurrent_vector_base_v4@details@Concurrency@@KA_K_K@Z */ -MSVCP_size_t __cdecl _vector_base_v4__Segment_index_of(MSVCP_size_t x) -{ - unsigned int half; - - TRACE("(%lu)\n", x); - - if((sizeof(x) == 8) && (half = x >> 32)) - return log2i(half) + 32; - - return log2i(x); -} - -/* ?_Internal_throw_exception@_Concurrent_vector_base_v4@details@Concurrency@@IBEXI@Z */ -/* ?_Internal_throw_exception@_Concurrent_vector_base_v4@details@Concurrency@@IEBAX_K@Z */ -DEFINE_THISCALL_WRAPPER(_vector_base_v4__Internal_throw_exception, 8) -void __thiscall _vector_base_v4__Internal_throw_exception(void/*_vector_base_v4*/ *this, MSVCP_size_t idx) -{ - static const struct { - exception_type type; - const char *msg; - } exceptions[] = { - { EXCEPTION_OUT_OF_RANGE, "Index out of range" }, - { EXCEPTION_OUT_OF_RANGE, "Index out of segments table range" }, - { EXCEPTION_RANGE_ERROR, "Index is inside segment which failed to be allocated" }, - }; - - TRACE("(%p %lu)\n", this, idx); - - if(idx < ARRAY_SIZE(exceptions)) - throw_exception(exceptions[idx].type, exceptions[idx].msg); -} -#endif - #if _MSVCP_VER >= 140 /* ?_IsNonBlockingThread@_Task_impl_base@details@Concurrency@@SA_NXZ */ MSVCP_bool __cdecl _Task_impl_base__IsNonBlockingThread(void)