Piotr Caban : msvcrt: Add SchedulerPolicy class implementation.

Alexandre Julliard julliard at winehq.org
Mon Mar 27 15:26:08 CDT 2017


Module: wine
Branch: master
Commit: e71edd0a1e2578ac50e26668372e49e4808adb25
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e71edd0a1e2578ac50e26668372e49e4808adb25

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon Mar 27 10:28:19 2017 +0200

msvcrt: Add SchedulerPolicy class implementation.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msvcrt/msvcrt.h    |   2 +
 dlls/msvcrt/scheduler.c | 120 ++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 108 insertions(+), 14 deletions(-)

diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h
index 04c97a8..e24f500 100644
--- a/dlls/msvcrt/msvcrt.h
+++ b/dlls/msvcrt/msvcrt.h
@@ -1411,4 +1411,6 @@ static inline BOOL heap_free(void *mem)
 {
     return HeapFree(GetProcessHeap(), 0, mem);
 }
+
+#define INHERIT_THREAD_PRIORITY 0xF000
 #endif /* __WINE_MSVCRT_H */
diff --git a/dlls/msvcrt/scheduler.c b/dlls/msvcrt/scheduler.c
index 9551810..23220b8 100644
--- a/dlls/msvcrt/scheduler.c
+++ b/dlls/msvcrt/scheduler.c
@@ -330,6 +330,7 @@ typedef enum {
     ContextPriority,
     SchedulingProtocol,
     DynamicProgressFeedback,
+    WinRTInitialization,
     last_policy_id
 } PolicyElementKey;
 
@@ -345,8 +346,47 @@ DEFINE_THISCALL_WRAPPER(SchedulerPolicy_SetPolicyValue, 12)
 unsigned int __thiscall SchedulerPolicy_SetPolicyValue(SchedulerPolicy *this,
         PolicyElementKey policy, unsigned int val)
 {
-    FIXME("(%p %d %d) stub\n", this, policy, val);
-    return 0;
+    unsigned int ret;
+
+    TRACE("(%p %d %d)\n", this, policy, val);
+
+    if (policy == MinConcurrency)
+        throw_exception(EXCEPTION_INVALID_SCHEDULER_POLICY_KEY, 0, "MinConcurrency");
+    if (policy == MaxConcurrency)
+        throw_exception(EXCEPTION_INVALID_SCHEDULER_POLICY_KEY, 0, "MaxConcurrency");
+    if (policy < SchedulerKind || policy >= last_policy_id)
+        throw_exception(EXCEPTION_INVALID_SCHEDULER_POLICY_KEY, 0, "Invalid policy");
+
+    switch(policy) {
+    case SchedulerKind:
+        if (val)
+            throw_exception(EXCEPTION_INVALID_SCHEDULER_POLICY_VALUE, 0, "SchedulerKind");
+        break;
+    case TargetOversubscriptionFactor:
+        if (!val)
+            throw_exception(EXCEPTION_INVALID_SCHEDULER_POLICY_VALUE,
+                    0, "TargetOversubscriptionFactor");
+        break;
+    case ContextPriority:
+        if (((int)val < -7 /* THREAD_PRIORITY_REALTIME_LOWEST */
+                    || val > 6 /* THREAD_PRIORITY_REALTIME_HIGHEST */)
+            && val != THREAD_PRIORITY_IDLE && val != THREAD_PRIORITY_TIME_CRITICAL
+            && val != INHERIT_THREAD_PRIORITY)
+            throw_exception(EXCEPTION_INVALID_SCHEDULER_POLICY_VALUE, 0, "ContextPriority");
+        break;
+    case SchedulingProtocol:
+    case DynamicProgressFeedback:
+    case WinRTInitialization:
+        if (val != 0 && val != 1)
+            throw_exception(EXCEPTION_INVALID_SCHEDULER_POLICY_VALUE, 0, "SchedulingProtocol");
+        break;
+    default:
+        break;
+    }
+
+    ret = this->policy_container->policies[policy];
+    this->policy_container->policies[policy] = val;
+    return ret;
 }
 
 /* ?SetConcurrencyLimits at SchedulerPolicy@Concurrency@@QAEXII at Z */
@@ -355,7 +395,15 @@ DEFINE_THISCALL_WRAPPER(SchedulerPolicy_SetConcurrencyLimits, 12)
 void __thiscall SchedulerPolicy_SetConcurrencyLimits(SchedulerPolicy *this,
         unsigned int min_concurrency, unsigned int max_concurrency)
 {
-    FIXME("(%p %d %d) stub\n", this, min_concurrency, max_concurrency);
+    TRACE("(%p %d %d)\n", this, min_concurrency, max_concurrency);
+
+    if (min_concurrency > max_concurrency)
+        throw_exception(EXCEPTION_INVALID_SCHEDULER_POLICY_THREAD_SPECIFICATION, 0, NULL);
+    if (!max_concurrency)
+        throw_exception(EXCEPTION_INVALID_SCHEDULER_POLICY_VALUE, 0, "MaxConcurrency");
+
+    this->policy_container->policies[MinConcurrency] = min_concurrency;
+    this->policy_container->policies[MaxConcurrency] = max_concurrency;
 }
 
 /* ?GetPolicyValue at SchedulerPolicy@Concurrency@@QBEIW4PolicyElementKey at 2@@Z */
@@ -364,8 +412,11 @@ DEFINE_THISCALL_WRAPPER(SchedulerPolicy_GetPolicyValue, 8)
 unsigned int __thiscall SchedulerPolicy_GetPolicyValue(
         const SchedulerPolicy *this, PolicyElementKey policy)
 {
-    FIXME("(%p %d) stub\n", this, policy);
-    return 0;
+    TRACE("(%p %d)\n", this, policy);
+
+    if (policy < SchedulerKind || policy >= last_policy_id)
+        throw_exception(EXCEPTION_INVALID_SCHEDULER_POLICY_KEY, 0, "Invalid policy");
+    return this->policy_container->policies[policy];
 }
 
 /* ??0SchedulerPolicy at Concurrency@@QAE at XZ */
@@ -373,17 +424,54 @@ unsigned int __thiscall SchedulerPolicy_GetPolicyValue(
 DEFINE_THISCALL_WRAPPER(SchedulerPolicy_ctor, 4)
 SchedulerPolicy* __thiscall SchedulerPolicy_ctor(SchedulerPolicy *this)
 {
-    FIXME("(%p) stub\n", this);
-    return NULL;
+    TRACE("(%p)\n", this);
+
+    this->policy_container = MSVCRT_operator_new(sizeof(*this->policy_container));
+    /* TODO: default values can probably be affected by CurrentScheduler */
+    this->policy_container->policies[SchedulerKind] = 0;
+    this->policy_container->policies[MaxConcurrency] = -1;
+    this->policy_container->policies[MinConcurrency] = 1;
+    this->policy_container->policies[TargetOversubscriptionFactor] = 1;
+    this->policy_container->policies[LocalContextCacheSize] = 8;
+    this->policy_container->policies[ContextStackSize] = 0;
+    this->policy_container->policies[ContextPriority] = THREAD_PRIORITY_NORMAL;
+    this->policy_container->policies[SchedulingProtocol] = 0;
+    this->policy_container->policies[DynamicProgressFeedback] = 1;
+    return this;
 }
 
 /* ??0SchedulerPolicy at Concurrency@@QAA at IZZ */
 /* ??0SchedulerPolicy at Concurrency@@QEAA at _KZZ */
+/* TODO: don't leak policy_container on exception */
 SchedulerPolicy* __cdecl SchedulerPolicy_ctor_policies(
         SchedulerPolicy *this, MSVCRT_size_t n, ...)
 {
-    FIXME("(%p %ld) stub\n", this, n);
-    return NULL;
+    unsigned int min_concurrency, max_concurrency;
+    __ms_va_list valist;
+    MSVCRT_size_t i;
+
+    TRACE("(%p %ld)\n", this, n);
+
+    SchedulerPolicy_ctor(this);
+    min_concurrency = this->policy_container->policies[MinConcurrency];
+    max_concurrency = this->policy_container->policies[MaxConcurrency];
+
+    __ms_va_start(valist, n);
+    for(i=0; i<n; i++) {
+        PolicyElementKey policy = va_arg(valist, PolicyElementKey);
+        unsigned int val = va_arg(valist, unsigned int);
+
+        if(policy == MinConcurrency)
+            min_concurrency = val;
+        else if(policy == MaxConcurrency)
+            max_concurrency = val;
+        else
+            SchedulerPolicy_SetPolicyValue(this, policy, val);
+    }
+    __ms_va_end(valist);
+
+    SchedulerPolicy_SetConcurrencyLimits(this, min_concurrency, max_concurrency);
+    return this;
 }
 
 /* ??4SchedulerPolicy at Concurrency@@QAEAAV01 at ABV01@@Z */
@@ -392,8 +480,10 @@ DEFINE_THISCALL_WRAPPER(SchedulerPolicy_op_assign, 8)
 SchedulerPolicy* __thiscall SchedulerPolicy_op_assign(
         SchedulerPolicy *this, const SchedulerPolicy *rhs)
 {
-    FIXME("(%p %p) stub\n", this, rhs);
-    return NULL;
+    TRACE("(%p %p)\n", this, rhs);
+    memcpy(this->policy_container->policies, rhs->policy_container->policies,
+            sizeof(this->policy_container->policies));
+    return this;
 }
 
 /* ??0SchedulerPolicy at Concurrency@@QAE at ABV01@@Z */
@@ -402,8 +492,9 @@ DEFINE_THISCALL_WRAPPER(SchedulerPolicy_copy_ctor, 8)
 SchedulerPolicy* __thiscall SchedulerPolicy_copy_ctor(
         SchedulerPolicy *this, const SchedulerPolicy *rhs)
 {
-    FIXME("(%p %p) stub\n", this, rhs);
-    return NULL;
+    TRACE("(%p %p)\n", this, rhs);
+    SchedulerPolicy_ctor(this);
+    return SchedulerPolicy_op_assign(this, rhs);
 }
 
 /* ??1SchedulerPolicy at Concurrency@@QAE at XZ */
@@ -411,7 +502,8 @@ SchedulerPolicy* __thiscall SchedulerPolicy_copy_ctor(
 DEFINE_THISCALL_WRAPPER(SchedulerPolicy_dtor, 4)
 void __thiscall SchedulerPolicy_dtor(SchedulerPolicy *this)
 {
-    FIXME("(%p) stub\n", this);
+    TRACE("(%p)\n", this);
+    MSVCRT_operator_delete(this->policy_container);
 }
 
 extern const vtable_ptr MSVCRT_type_info_vtable;




More information about the wine-cvs mailing list