mirror of
https://github.com/microsoft/WSL.git
synced 2025-07-03 15:23:22 +00:00

Many Microsoft employees have contributed to the Windows Subsystem for Linux, this commit is the result of their work since 2016. The entire history of the Windows Subsystem for Linux can't be shared here, but here's an overview of WSL's history after it moved to it own repository in 2021: Number of commits on the main branch: 2930 Number of contributors: 31 Head over https://github.com/microsoft/WSL/releases for a more detailed history of the features added to WSL since 2021.
336 lines
8.3 KiB
C
336 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;
|
|
}
|