/*++ Copyright (c) Microsoft. All rights reserved. Module Name: sched.c Abstract: This file is the scheduler test. --*/ #include "lxtcommon.h" #include "unittests.h" #include #include #include #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; }