Beispiel #1
0
/**
 * 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;
}
Beispiel #3
0
/**
 * 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;
}
Beispiel #4
0
/**
 * 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;
}
Beispiel #5
0
/**
 * 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;
}