示例#1
0
/**
 * The process priority validator thread.
 * (We don't want to mess with the priority of the calling thread.)
 */
static void *rtSchedNativeValidatorThread(void *pvUser)
{
    const PROCPRIORITY *pCfg = (const PROCPRIORITY *)pvUser;
    SAVEDPRIORITY SavedPriority;
    rtSchedNativeSave(&SavedPriority);

    /*
     * Try out the priorities from the top and down.
     */
    int rc = VINF_SUCCESS;
    int i = RTTHREADTYPE_END;
    while (--i > RTTHREADTYPE_INVALID)
    {
        int iPriority = pCfg->paTypes[i].iPriority + pCfg->iDelta;
        if (setpriority(PRIO_PROCESS, 0, iPriority))
        {
            rc = RTErrConvertFromErrno(errno);
            break;
        }
    }

    /* done */
    rtSchedNativeRestore(&SavedPriority);
    return (void *)(intptr_t)rc;
}
/**
 * The process priority validator thread.
 * (We don't want to mess with the priority of the calling thread.)
 */
static void *rtSchedNativeValidatorThread(void *pvUser)
{
    PVALIDATORPRIORITYPAIR pPrioPair = (PVALIDATORPRIORITYPAIR)pvUser;
    SAVEDPRIORITY SavedPriority;
    rtSchedNativeSave(&SavedPriority);

    int rc = VINF_SUCCESS;

    /*
     * Set the priority to the current value for specified thread type, but
     * only if we have any threads of this type (caller checked - INT_MAX).
     */
    if (pPrioPair->iCurrent != INT_MAX)
        if (setpriority(PRIO_PROCESS, 0, pPrioPair->iCurrent))
            rc = RTErrConvertFromErrno(errno);

    /*
     * Try set the new priority.
     */
    if (RT_SUCCESS(rc) && setpriority(PRIO_PROCESS, 0, pPrioPair->iNew))
        rc = RTErrConvertFromErrno(errno);

    /* done */
    rtSchedNativeRestore(&SavedPriority);
    return (void *)(intptr_t)rc;
}
示例#3
0
/**
 * The prober thread.
 * We don't want to mess with the priority of the calling thread.
 *
 * @remark  This is pretty presumptive stuff, but if it works on Linux and
 *          FreeBSD it does what I want.
 */
static void *rtSchedNativeProberThread(void *pvUser)
{
    SAVEDPRIORITY SavedPriority;
    rtSchedNativeSave(&SavedPriority);

    /*
     * Let's first try and see what we get on a thread level.
     */
    int iMax = sched_get_priority_max(SavedPriority.iPthreadPolicy);
    int iMin = sched_get_priority_min(SavedPriority.iPthreadPolicy);
    if (iMax - iMin >= 32)
    {
        pthread_t Self = pthread_self();
        int i = iMin;
        while (i <= iMax)
        {
            struct sched_param SchedParam = SavedPriority.PthreadSchedParam;
            SchedParam.sched_priority = i;
            if (pthread_setschedparam(Self, SavedPriority.iPthreadPolicy, &SchedParam))
                break;
            i++;
        }
        if (i == iMax)
            g_enmOsPrioSup = OSPRIOSUP_PROCESS_AND_THREAD_LEVEL;
    }

    /*
     * Ok, we didn't have the good stuff, so let's fall back on the unix stuff.
     */
    if (g_enmOsPrioSup == OSPRIOSUP_UNDETERMINED)
        g_enmOsPrioSup = OSPRIOSUP_THREAD_LEVEL;

    /*
     * Check if we can get higher priority (typically only root can do this).
     * (Won't work right if our priority is -19 to start with, but what the heck.)
     *
     * We assume that the unix priority is -19 to 19. I know there are defines
     * for this, but I don't remember which and if I'm awake enough to make sense
     * of them from any SuS spec.
     */
    int iStart = getpriority(PRIO_PROCESS, 0);
    int i = iStart;
    while (i-- > -19)
    {
        if (setpriority(PRIO_PROCESS, 0, i))
            break;
    }
    if (getpriority(PRIO_PROCESS, 0) != iStart)
        g_fCanNice = true;
    else
        g_fCanNice = false;

    /* done */
    rtSchedNativeRestore(&SavedPriority);
    return (void *)VINF_SUCCESS;
}
/**
 * The prober thread.
 * We don't want to mess with the priority of the calling thread.
 *
 * @remark  This is pretty presumptive stuff, but if it works on Linux and
 *          FreeBSD it does what I want.
 */
static void *rtSchedNativeProberThread(void *pvUser)
{
    NOREF(pvUser);
    SAVEDPRIORITY SavedPriority;
    rtSchedNativeSave(&SavedPriority);

    /*
     * Check if we can get higher priority (typically only root can do this).
     * (Won't work right if our priority is -19 to start with, but what the heck.)
     *
     * We assume that the priority range is -19 to 19. Should probably find the right
     * define for this.
     */
    int iStart = getpriority(PRIO_PROCESS, 0);
    int i = iStart;
    while (i-- > -20)
        if (setpriority(PRIO_PROCESS, 0, i))
            break;
    g_iMaxPriority = getpriority(PRIO_PROCESS, 0);
    g_fCanRaisePriority = g_iMaxPriority < iStart;
    g_fCanRestorePriority = setpriority(PRIO_PROCESS, 0, iStart) == 0;

    /*
     * Check if we temporarily lower the thread priority.
     * Again, we assume we're not at the extreme end of the priority scale.
     */
    iStart = getpriority(PRIO_PROCESS, 0);
    i = iStart;
    while (i++ < 19)
        if (setpriority(PRIO_PROCESS, 0, i))
            break;
    g_iMinPriority = getpriority(PRIO_PROCESS, 0);
    if (    setpriority(PRIO_PROCESS, 0, iStart)
        ||  getpriority(PRIO_PROCESS, 0) != iStart)
        g_fCanRestorePriority = false;
    if (g_iMinPriority == g_iMaxPriority)
        g_fCanRestorePriority = g_fCanRaisePriority = false;

    /*
     * Check what happens to child threads when the parent lowers the
     * priority when it's being created.
     */
    iStart = getpriority(PRIO_PROCESS, 0);
    g_fScrewedUpMaxPriorityLimitInheritance = true;
    if (    g_fCanRestorePriority
        &&  !setpriority(PRIO_PROCESS, 0, g_iMinPriority)
        &&  iStart != g_iMinPriority)
    {
        if (rtSchedRunThread(rtSchedNativeSubProberThread, (void *)(intptr_t)iStart) == 0)
            g_fScrewedUpMaxPriorityLimitInheritance = false;
    }

    /* done */
    rtSchedNativeRestore(&SavedPriority);
    return (void *)VINF_SUCCESS;
}
示例#5
0
/**
 * The validator thread.
 * We don't want to mess with the priority of the calling thread.
 *
 * @remark  This is pretty presumptive stuff, but if it works on Linux and
 *          FreeBSD it does what I want.
 */
static void *rtSchedNativeValidatorThread(void *pvUser)
{
    const PROCPRIORITY *pCfg = (const PROCPRIORITY *)pvUser;
    SAVEDPRIORITY SavedPriority;
    rtSchedNativeSave(&SavedPriority);

    int rc = VINF_SUCCESS;
    switch (g_enmOsPrioSup)
    {
        /*
         * Try set the specified process priority and then try
         * out all the thread priorities which are used.
         */
        case OSPRIOSUP_PROCESS_AND_THREAD_LEVEL:
        {
            if (!setpriority(PRIO_PROCESS, 0, pCfg->iNice))
            {
                int iMin = sched_get_priority_min(SavedPriority.iPolicy);
                pthread_t Self = pthread_self();
                for (int i = RTTHREADTYPE_INVALID + 1; i < RTTHREADTYPE_END; i++)
                {
                    struct sched_param SchedParam = SavedPriority.PthreadSchedParam;
                    SchedParam.sched_priority = pCfg->paTypes[i].iPriority
                        + pCfg->iDelta + iMin;
                    rc = pthread_setschedparam(Self, SavedPriority.iPthreadPolicy, &SchedParam);
                    if (rc)
                    {
                        rc = RTErrConvertFromErrno(rc);
                        break;
                    }
                }
            }
            else
                rc = RTErrConvertFromErrno(errno);
            break;
        }

        /*
         * Try out the priorities from the top and down.
         */
        case OSPRIOSUP_THREAD_LEVEL:
        {
            int i = RTTHREADTYPE_END;
            while (--i > RTTHREADTYPE_INVALID)
            {
                int iPriority = pCfg->paTypes[i].iPriority + pCfg->iDelta;
                if (setpriority(PRIO_PROCESS, 0, iPriority))
                {
                    rc = RTErrConvertFromErrno(errno);
                    break;
                }
            }
            break;
        }

        default:
            AssertFailed();
            break;
    }

    /* done */
    rtSchedNativeRestore(&SavedPriority);
    return (void *)rc;
}