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