mirror of
https://github.com/microsoft/WSL.git
synced 2025-07-03 23:33:21 +00:00
337 lines
8.3 KiB
C
337 lines
8.3 KiB
C
![]() |
/*++
|
||
|
|
||
|
Copyright (c) Microsoft. All rights reserved.
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
sched.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This file is the scheduler test.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "lxtcommon.h"
|
||
|
#include "unittests.h"
|
||
|
#include <sched.h>
|
||
|
#include <stdio.h>
|
||
|
#include <sys/syscall.h>
|
||
|
|
||
|
#define LXT_NAME "sched"
|
||
|
|
||
|
int GetDefaultScheduler(PLXT_ARGS Args);
|
||
|
|
||
|
int SetScheduler(PLXT_ARGS Args);
|
||
|
|
||
|
int SetSchedulerChild(PLXT_ARGS Args);
|
||
|
|
||
|
int SetGetAffinity(PLXT_ARGS Args);
|
||
|
|
||
|
int SetGetAffinityNp(PLXT_ARGS Args);
|
||
|
|
||
|
//
|
||
|
// Global constants
|
||
|
//
|
||
|
|
||
|
static const LXT_VARIATION g_LxtVariations[] = {
|
||
|
{"Get Scheduler Default", GetDefaultScheduler},
|
||
|
{"Set Scheduler", SetScheduler},
|
||
|
{"Set-Get Affinity", SetGetAffinity},
|
||
|
{"Set-Get Affinity np", SetGetAffinityNp}};
|
||
|
|
||
|
int SchedTestEntry(int Argc, char* Argv[])
|
||
|
|
||
|
/*++
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
|
||
|
LXT_ARGS Args;
|
||
|
int Result;
|
||
|
|
||
|
LxtCheckResult(LxtInitialize(Argc, Argv, &Args, LXT_NAME));
|
||
|
LxtCheckResult(LxtRunVariations(&Args, g_LxtVariations, LXT_COUNT_OF(g_LxtVariations)));
|
||
|
|
||
|
ErrorExit:
|
||
|
LxtUninitialize();
|
||
|
return !LXT_SUCCESS(Result);
|
||
|
}
|
||
|
|
||
|
int GetDefaultScheduler(PLXT_ARGS Args)
|
||
|
|
||
|
/*++
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
|
||
|
int Result;
|
||
|
int Policy;
|
||
|
|
||
|
Policy = sched_getscheduler(0);
|
||
|
LxtLogInfo("Policy received %d", Policy);
|
||
|
if (Policy == SCHED_OTHER)
|
||
|
{
|
||
|
Result = LXT_RESULT_SUCCESS;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
LxtLogError("Bad policy. Expected(%d) != Returned(%d)", SCHED_OTHER, Policy);
|
||
|
|
||
|
Result = LXT_RESULT_FAILURE;
|
||
|
}
|
||
|
|
||
|
ErrorExit:
|
||
|
return Result;
|
||
|
}
|
||
|
|
||
|
int SetScheduler(PLXT_ARGS Args)
|
||
|
|
||
|
/*++
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
|
||
|
int Result;
|
||
|
struct sched_param Param;
|
||
|
int Policy;
|
||
|
|
||
|
Policy = sched_getscheduler(0);
|
||
|
LxtLogInfo("Policy received %d", Policy);
|
||
|
if (Policy < 0)
|
||
|
{
|
||
|
LxtLogError("Bad policy. errno %d = %s", errno, strerror(errno));
|
||
|
|
||
|
Result = LXT_RESULT_FAILURE;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Set a different policy
|
||
|
//
|
||
|
|
||
|
if (Policy == SCHED_OTHER)
|
||
|
{
|
||
|
Policy = SCHED_FIFO;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Policy = SCHED_OTHER;
|
||
|
}
|
||
|
|
||
|
LxtLogInfo("Setting policy %d", Policy);
|
||
|
Param.sched_priority = 17;
|
||
|
Result = sched_setscheduler(0, Policy, &Param);
|
||
|
if (Result < 0)
|
||
|
{
|
||
|
LxtLogError("Set scheduler failed errno %d = %s", errno, strerror(errno));
|
||
|
|
||
|
Result = LXT_RESULT_FAILURE;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
Result = sched_getscheduler(0);
|
||
|
LxtLogInfo("Policy received %d", Result);
|
||
|
if (Policy != Result)
|
||
|
{
|
||
|
LxtLogError("Bad policy. Expected(%d) != Returned(%d)", Policy, Result);
|
||
|
|
||
|
Result = LXT_RESULT_FAILURE;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
Result = LXT_RESULT_SUCCESS;
|
||
|
|
||
|
ErrorExit:
|
||
|
return Result;
|
||
|
}
|
||
|
|
||
|
int SetSchedulerChild(PLXT_ARGS Args)
|
||
|
|
||
|
/*++
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
|
||
|
int Result;
|
||
|
int Policy;
|
||
|
int Pid;
|
||
|
|
||
|
//
|
||
|
// The child should inherit this scheduler
|
||
|
//
|
||
|
|
||
|
sched_setscheduler(0, SCHED_OTHER, NULL);
|
||
|
|
||
|
Pid = fork();
|
||
|
if (Pid != 0)
|
||
|
{
|
||
|
sleep(1);
|
||
|
|
||
|
Result = sched_setscheduler(Pid, SCHED_FIFO, NULL);
|
||
|
if (Result < 0)
|
||
|
{
|
||
|
LxtLogError("Set scheduler failed errno %d = %s", errno, strerror(errno));
|
||
|
|
||
|
Result = LXT_RESULT_FAILURE;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
sleep(2);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Policy = sched_getscheduler(0);
|
||
|
LxtLogInfo("Child - Policy gotten %d", Policy);
|
||
|
if (Policy != SCHED_OTHER)
|
||
|
{
|
||
|
LxtLogError("Bad policy. Expected(%d) != Returned(%d)", SCHED_OTHER, Policy);
|
||
|
|
||
|
Result = LXT_RESULT_FAILURE;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
sleep(2);
|
||
|
|
||
|
Policy = sched_getscheduler(0);
|
||
|
printf("Child - Policy gotten %d", Policy);
|
||
|
if (Policy != SCHED_FIFO)
|
||
|
{
|
||
|
LxtLogError("Bad policy. Expected(%d) != Returned(%d)", SCHED_FIFO, Policy);
|
||
|
|
||
|
Result = LXT_RESULT_FAILURE;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Result = LXT_RESULT_SUCCESS;
|
||
|
|
||
|
ErrorExit:
|
||
|
return Result;
|
||
|
}
|
||
|
|
||
|
int SetGetAffinity(PLXT_ARGS Args)
|
||
|
|
||
|
/*++
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
|
||
|
int Result;
|
||
|
int Size = -1;
|
||
|
cpu_set_t Set;
|
||
|
cpu_set_t Desired;
|
||
|
int Sizes[] = {-8, 8, 16, 24, 32, 40, 64, 128, 256};
|
||
|
int SizeExpected;
|
||
|
int Index;
|
||
|
|
||
|
CPU_ZERO(&Set);
|
||
|
|
||
|
LxtLogInfo("sizeof(cpu_set_t) = %Iu", sizeof(cpu_set_t));
|
||
|
LxtCheckErrno(Size = LxtSched_GetAffinity(0, sizeof(Set), &Set));
|
||
|
LxtCheckEqual(Size, 64, "%d");
|
||
|
LxtLogInfo("Affinity before: %08x", *(uint32_t*)&Set);
|
||
|
CPU_ZERO(&Desired);
|
||
|
CPU_SET(0, &Desired);
|
||
|
LxtCheckErrno(LxtSched_SetAffinity(0, 1, &Desired));
|
||
|
LxtCheckErrno(Size = LxtSched_GetAffinity(0, sizeof(Set), &Set));
|
||
|
LxtCheckEqual(Size, 64, "%d");
|
||
|
LxtCheckErrno(LxtSched_SetAffinity(0, 3, &Desired));
|
||
|
LxtCheckErrno(Size = LxtSched_GetAffinity(0, sizeof(Set), &Set));
|
||
|
LxtCheckEqual(Size, 64, "%d");
|
||
|
LxtCheckErrno(LxtSched_SetAffinity(0, sizeof(Desired), &Desired));
|
||
|
LxtCheckErrno(Size = LxtSched_GetAffinity(0, sizeof(Set), &Set));
|
||
|
LxtCheckEqual(Size, 64, "%d");
|
||
|
LxtLogInfo("Affinity after: %08x", *(uint32_t*)&Set);
|
||
|
if (!CPU_EQUAL(&Set, &Desired))
|
||
|
{
|
||
|
LxtLogError("sched_setaffinity failed to set the affinity. ");
|
||
|
Result = LXT_RESULT_FAILURE;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Test with various buffer sizes.
|
||
|
//
|
||
|
|
||
|
for (Index = 0; Index < (int)LXT_COUNT_OF(Sizes); Index++)
|
||
|
{
|
||
|
LxtLogInfo("Testing size %d", Sizes[Index]);
|
||
|
LxtCheckErrno(Size = LxtSched_GetAffinity(0, Sizes[Index], &Set));
|
||
|
SizeExpected = Sizes[Index];
|
||
|
if ((SizeExpected > 64) || (SizeExpected < 0))
|
||
|
{
|
||
|
SizeExpected = 64;
|
||
|
}
|
||
|
|
||
|
LxtCheckEqual(Size, SizeExpected, "%d");
|
||
|
if (!CPU_EQUAL(&Set, &Desired))
|
||
|
{
|
||
|
LxtLogError("sched_setaffinity failed to set the affinity. ");
|
||
|
Result = LXT_RESULT_FAILURE;
|
||
|
goto ErrorExit;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LxtCheckErrno(Size = LxtSched_GetAffinity(getpid(), sizeof(Set), &Set));
|
||
|
|
||
|
//
|
||
|
// Invalid parameter variations.
|
||
|
//
|
||
|
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(0, 0, &Set), EINVAL);
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(0, 1, &Set), EINVAL);
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(0, 2, &Set), EINVAL);
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(0, 7, &Set), EINVAL);
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(0, 9, &Set), EINVAL);
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(0, 10, &Set), EINVAL);
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(0, 31, &Set), EINVAL);
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(0, 33, &Set), EINVAL);
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(0, 63, &Set), EINVAL);
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(0, 65, &Set), EINVAL);
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(0, -1, &Set), EINVAL);
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(0, -63, &Set), EINVAL);
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(0, -1, NULL), EINVAL);
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(0, -1, -1), EINVAL);
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(-1, -1, &Set), EINVAL);
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(0, sizeof(Set), NULL), EFAULT);
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(0, sizeof(Set), -1), EFAULT);
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(-1, sizeof(Set), &Set), ESRCH);
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(-1, sizeof(Set), NULL), ESRCH);
|
||
|
LxtCheckErrnoFailure(LxtSched_GetAffinity(-1, sizeof(Set), -1), ESRCH);
|
||
|
Result = LXT_RESULT_SUCCESS;
|
||
|
|
||
|
ErrorExit:
|
||
|
return Result;
|
||
|
}
|
||
|
|
||
|
int SetGetAffinityNp(PLXT_ARGS Args)
|
||
|
|
||
|
/*++
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
|
||
|
int Result;
|
||
|
cpu_set_t Set;
|
||
|
CPU_ZERO(&Set);
|
||
|
CPU_SET(0, &Set);
|
||
|
LxtCheckErrno(LxtSched_SetAffinity(0, sizeof(Set), &Set));
|
||
|
LxtCheckErrno(LxtSched_GetAffinity(0, sizeof(Set), &Set));
|
||
|
|
||
|
//
|
||
|
// N.B Affinity cannot be validated because its not gauranteed for it to
|
||
|
// take affect.
|
||
|
//
|
||
|
|
||
|
LxtLogInfo("Current Affinity: %08x", *(uint32_t*)&Set);
|
||
|
CPU_ZERO(&Set);
|
||
|
CPU_SET(1, &Set);
|
||
|
LxtCheckErrno(LxtSched_SetAffinity(0, sizeof(Set), &Set));
|
||
|
LxtCheckErrno(LxtSched_GetAffinity(0, sizeof(Set), &Set));
|
||
|
LxtLogInfo("Current Affinity: %08x", *(uint32_t*)&Set);
|
||
|
Result = LXT_RESULT_SUCCESS;
|
||
|
|
||
|
ErrorExit:
|
||
|
return Result;
|
||
|
}
|