[prev in list] [next in list] [prev in thread] [next in thread] 

List:       wine-devel
Subject:    [PATCH 04/13 v2] msvcp90: Add implementaion of _Concurrent_vector_Internal_reserve.
From:       Hua Meng <161220092 () smail ! nju ! edu ! cn>
Date:       2018-07-31 15:16:53
Message-ID: b337724f-e9a4-e05a-f68a-0e17c747466c () smail ! nju ! edu ! cn+28F734A36A61CF56
[Download RAW message or body]

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..34a30cf5e1 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(void*));
+            memcpy(new_segment, this->storage, STORAGE_SIZE * element_size);
+            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)
-- 
2.11.0


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic