/** * Calculate the scheduling properties for all the threads in the default * process priority, assuming the current thread have the type enmType. * * @returns iprt status code. * @param enmType The thread type to be assumed for the current thread. */ DECLHIDDEN(int) rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType) { Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END); /* * First figure out what's supported by the OS. */ if (g_enmOsPrioSup == OSPRIOSUP_UNDETERMINED) { int iPriority = getpriority(PRIO_PROCESS, 0); int rc = rtSchedCreateThread(rtSchedNativeProberThread, NULL); if (RT_FAILURE(rc)) return rc; if (g_enmOsPrioSup == OSPRIOSUP_UNDETERMINED) g_enmOsPrioSup = OSPRIOSUP_THREAD_LEVEL; Assert(getpriority(PRIO_PROCESS, 0) == iPriority); NOREF(iPriority); } /* * Now let's see what we can do... */ int iPriority = getpriority(PRIO_PROCESS, 0); switch (g_enmOsPrioSup) { case OSPRIOSUP_PROCESS_AND_THREAD_LEVEL: { g_aDefaultPriority.iNice = iPriority; g_aDefaultPriority.iDelta = 0; g_aDefaultPriority.paTypes = g_aTypesThread; Assert(enmType == g_aDefaultPriority.paTypes[enmType].enmType); break; } case OSPRIOSUP_THREAD_LEVEL: { if (g_fCanNice) g_aDefaultPriority.paTypes = g_aTypesUnixFree; else g_aDefaultPriority.paTypes = g_aTypesUnixRestricted; Assert(enmType == g_aDefaultPriority.paTypes[enmType].enmType); g_aDefaultPriority.iNice = iPriority - g_aDefaultPriority.paTypes[enmType].iPriority; g_aDefaultPriority.iDelta = g_aDefaultPriority.iNice; break; } default: AssertFailed(); break; } rtSchedDumpPriority(); return VINF_SUCCESS; }
/** * Validates and sets the process priority. * * This will check that all rtThreadNativeSetPriority() will success for all the * thread types when applied to the current thread. * * @returns iprt status code. * @param enmPriority The priority to validate and set. */ DECLHIDDEN(int) rtProcNativeSetPriority(RTPROCPRIORITY enmPriority) { Assert(enmPriority > RTPROCPRIORITY_INVALID && enmPriority < RTPROCPRIORITY_LAST); #ifdef RTTHREAD_POSIX_WITH_CREATE_PRIORITY_PROXY /* * Make sure the proxy creation thread is started so we don't 'lose' our * initial priority if it's lowered. */ bool const fHavePriorityProxy = rtThreadPosixPriorityProxyStart(); #else bool const fHavePriorityProxy = false; #endif int rc; if (enmPriority == RTPROCPRIORITY_DEFAULT) { /* * If we've lowered priority since the process started, it may be impossible * to raise it again for existing thread (new threads will work fine). */ rc = rtSchedNativeCheckThreadTypes(&g_aDefaultPriority, fHavePriorityProxy); if (RT_SUCCESS(rc)) g_pProcessPriority = &g_aDefaultPriority; } else { /* * Find a configuration which matches and can be applied. */ rc = VERR_NOT_FOUND; for (unsigned i = 0; i < RT_ELEMENTS(g_aUnixConfigs); i++) if (g_aUnixConfigs[i].enmPriority == enmPriority) { int rc2 = rtSchedNativeCheckThreadTypes(&g_aUnixConfigs[i], fHavePriorityProxy); if (RT_SUCCESS(rc2)) { g_pProcessPriority = &g_aUnixConfigs[i]; rc = VINF_SUCCESS; break; } if (rc == VERR_NOT_FOUND || rc == VERR_ACCESS_DENIED) rc = rc2; } } #ifdef THREAD_LOGGING LogFlow(("rtProcNativeSetPriority: returns %Rrc enmPriority=%d\n", rc, enmPriority)); rtSchedDumpPriority(); #endif return rc; }
/** * Calculate the scheduling properties for all the threads in the default * process priority, assuming the current thread have the type enmType. * * @returns iprt status code. * @param enmType The thread type to be assumed for the current thread. */ DECLHIDDEN(int) rtSchedNativeCalcDefaultPriority(RTTHREADTYPE enmType) { Assert(enmType > RTTHREADTYPE_INVALID && enmType < RTTHREADTYPE_END); /* * First figure out what's we're allowed to do in this process. */ if (!g_fInitialized) { int iPriority = getpriority(PRIO_PROCESS, 0); #ifdef RLIMIT_RTPRIO /** @todo */ #endif int rc = rtSchedRunThread(rtSchedNativeProberThread, NULL); if (RT_FAILURE(rc)) return rc; Assert(getpriority(PRIO_PROCESS, 0) == iPriority); NOREF(iPriority); g_fInitialized = true; } /* * Select the right priority type table and update the default * process priority structure. */ if (g_fCanRaisePriority && g_fCanRestorePriority && !g_fScrewedUpMaxPriorityLimitInheritance) g_aDefaultPriority.paTypes = &g_aTypesLinuxFree[0]; else if (!g_fCanRaisePriority && g_fCanRestorePriority && !g_fScrewedUpMaxPriorityLimitInheritance) g_aDefaultPriority.paTypes = &g_aTypesLinuxRestricted[0]; else g_aDefaultPriority.paTypes = &g_aTypesLinuxFlat[0]; Assert(enmType == g_aDefaultPriority.paTypes[enmType].enmType); int iPriority = getpriority(PRIO_PROCESS, 0 /* current process */); g_aDefaultPriority.iNice = iPriority - g_aDefaultPriority.paTypes[enmType].iPriority; g_aDefaultPriority.iDelta = g_aDefaultPriority.iNice; rtSchedDumpPriority(); return VINF_SUCCESS; }
/** * Validates and sets the process priority. * * This will check that all rtThreadNativeSetPriority() will success for all the * thread types when applied to the current thread. * * @returns iprt status code. * @param enmPriority The priority to validate and set. */ DECLHIDDEN(int) rtProcNativeSetPriority(RTPROCPRIORITY enmPriority) { Assert(enmPriority > RTPROCPRIORITY_INVALID && enmPriority < RTPROCPRIORITY_LAST); int rc = VINF_SUCCESS; if (enmPriority == RTPROCPRIORITY_DEFAULT) g_pProcessPriority = &g_aDefaultPriority; else { /* * Find a configuration which matches and can be applied. */ rc = VERR_FILE_NOT_FOUND; for (unsigned i = 0; i < RT_ELEMENTS(g_aUnixConfigs); i++) { if (g_aUnixConfigs[i].enmPriority == enmPriority) { int iPriority = getpriority(PRIO_PROCESS, 0); int rc3 = rtSchedRunThread(rtSchedNativeValidatorThread, (void *)&g_aUnixConfigs[i]); Assert(getpriority(PRIO_PROCESS, 0) == iPriority); NOREF(iPriority); if (RT_SUCCESS(rc3)) { g_pProcessPriority = &g_aUnixConfigs[i]; rc = VINF_SUCCESS; break; } if (rc == VERR_FILE_NOT_FOUND) rc = rc3; } } } #ifdef THREAD_LOGGING LogFlow(("rtProcNativeSetPriority: returns %Rrc enmPriority=%d\n", rc, enmPriority)); rtSchedDumpPriority(); #endif return rc; }
/** * Validates and sets the process priority. * This will check that all rtThreadNativeSetPriority() will success for all the * thread types when applied to the current thread. * * @returns iprt status code. * @param enmPriority The priority to validate and set. */ DECLHIDDEN(int) rtProcNativeSetPriority(RTPROCPRIORITY enmPriority) { Assert(enmPriority > RTPROCPRIORITY_INVALID && enmPriority < RTPROCPRIORITY_LAST); int rc = VINF_SUCCESS; if (enmPriority == RTPROCPRIORITY_DEFAULT) g_pProcessPriority = &g_aDefaultPriority; else { /* * Select the array to search. */ const PROCPRIORITY *pa; unsigned c; switch (g_enmOsPrioSup) { case OSPRIOSUP_PROCESS_AND_THREAD_LEVEL: pa = g_aProcessAndThread; c = RT_ELEMENTS(g_aProcessAndThread); break; case OSPRIOSUP_THREAD_LEVEL: pa = g_aUnixConfigs; c = RT_ELEMENTS(g_aUnixConfigs); break; default: pa = NULL; c = 0; break; } /* * Search the array. */ rc = VERR_FILE_NOT_FOUND; unsigned i; for (i = 0; i < c; i++) { if (pa[i].enmPriority == enmPriority) { /* * Validate it. */ int iPriority = getpriority(PRIO_PROCESS, 0); int rc3 = rtSchedCreateThread(rtSchedNativeValidatorThread, (void *)&pa[i]); Assert(getpriority(PRIO_PROCESS, 0) == iPriority); NOREF(iPriority); if (RT_SUCCESS(rc)) rc = rc3; if (RT_SUCCESS(rc)) break; } } /* * Did we get lucky? * If so update process priority and globals. */ if (RT_SUCCESS(rc)) { switch (g_enmOsPrioSup) { case OSPRIOSUP_PROCESS_AND_THREAD_LEVEL: if (setpriority(PRIO_PROCESS, 0, pa[i].iNice)) { rc = RTErrConvertFromErrno(errno); AssertMsgFailed(("setpriority(,,%d) -> errno=%d rc=%Rrc\n", pa[i].iNice, errno, rc)); } break; default: break; } if (RT_SUCCESS(rc)) g_pProcessPriority = &pa[i]; } } #ifdef THREAD_LOGGING LogFlow(("rtProcNativeSetPriority: returns %Rrc enmPriority=%d\n", rc, enmPriority)); rtSchedDumpPriority(); #endif return rc; }