Annotation of XNU/osfmk/kern/mk_sp_task.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * The contents of this file constitute Original Code as defined in and
        !             7:  * are subject to the Apple Public Source License Version 1.1 (the
        !             8:  * "License").  You may not use this file except in compliance with the
        !             9:  * License.  Please obtain a copy of the License at
        !            10:  * http://www.apple.com/publicsource and read it before using this file.
        !            11:  * 
        !            12:  * This Original Code and all software distributed under the License are
        !            13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            17:  * License for the specific language governing rights and limitations
        !            18:  * under the License.
        !            19:  * 
        !            20:  * @APPLE_LICENSE_HEADER_END@
        !            21:  */
        !            22: /*
        !            23:  * @OSF_COPYRIGHT@
        !            24:  * 
        !            25:  */
        !            26: 
        !            27: /***
        !            28:  *** ??? The following files were added when the task system call code
        !            29:  *** was moved into this file.  They should be integrated with the above
        !            30:  *** files if these routine stay; or they should be moved elsewhere when
        !            31:  *** the routines are moved.
        !            32:  ***/
        !            33: #include <mach/message.h>
        !            34: 
        !            35: #include <kern/assert.h>
        !            36: #include <kern/counters.h>
        !            37: #include <kern/task.h>
        !            38: #include <kern/sf.h>
        !            39: #include <kern/mk_sp.h>
        !            40: 
        !            41: /***
        !            42:  *** ??? The next file supplies the prototypes for `task_set_policy()'
        !            43:  *** and `task_policy.'  These routines cannot stay here if they are
        !            44:  *** exported Mach system calls.
        !            45:  ***/
        !            46: #include <mach/mach_host_server.h>
        !            47: 
        !            48: sf_return_t
        !            49: _mk_sp_task_attach(
        !            50:        sf_object_t             pol,            /* policy */
        !            51:        task_t                  task)
        !            52: {
        !            53:        sp_attributes_t         sp_attr;
        !            54:        sp_attributes_size_t    sched_attributes_size;
        !            55: 
        !            56:        counter(c_mk_sp_task_attach++);
        !            57: 
        !            58:        /* get memory to hold scheduling parameters */
        !            59:        sched_attributes_size = pol->sched_attributes_size;
        !            60:        sp_attr = (sp_attributes_t)kalloc(sched_attributes_size);
        !            61:        if (sp_attr == 0) {
        !            62:                return(SF_KERN_RESOURCE_SHORTAGE);
        !            63:        }
        !            64: 
        !            65:        task->policy = pol->policy_id;
        !            66:        task->sp_attributes = sp_attr;
        !            67: 
        !            68:        return(SF_SUCCESS);
        !            69: }
        !            70: 
        !            71: 
        !            72: sf_return_t
        !            73: _mk_sp_task_detach(
        !            74:        sf_object_t             pol,            /* policy */
        !            75:        task_t                  task)
        !            76: {
        !            77:        sp_attributes_t         sp_attr;
        !            78:        sp_attributes_size_t    sched_attributes_size;
        !            79: 
        !            80:        counter(c_mk_sp_task_detach++);
        !            81: 
        !            82:        /* make sure task is associated with this policy */
        !            83:        if (task->policy != pol->policy_id) return(SF_SUCCESS);
        !            84: 
        !            85:        /* free memory holding scheduling parameters */
        !            86:        sched_attributes_size = pol->sched_attributes_size;
        !            87:        assert(task->sp_attributes != SP_ATTRIBUTES_NULL);
        !            88:        kfree((vm_offset_t) task->sp_attributes, sched_attributes_size);
        !            89: 
        !            90:        task->policy = POLICY_NULL;
        !            91:        task->sp_attributes = SP_ATTRIBUTES_NULL;
        !            92: 
        !            93:        return(SF_SUCCESS);
        !            94: }
        !            95: 
        !            96: 
        !            97: /*
        !            98:  *     task_max_priority
        !            99:  *
        !           100:  *     Set the maximum priority for a task. This does not affect threads
        !           101:  *     within the task. Use thread_max_priority() to set their limits.
        !           102:  */
        !           103: kern_return_t
        !           104: task_max_priority(
        !           105:        task_t          task,
        !           106:        processor_set_t pset,
        !           107:        int             max_priority)
        !           108: {
        !           109:        mk_sp_attributes_t      sp_attr;
        !           110:        kern_return_t           ret = KERN_SUCCESS;
        !           111: 
        !           112:        if (task == TASK_NULL || pset == PROCESSOR_SET_NULL ||
        !           113:                        invalid_pri(max_priority))
        !           114:             return(KERN_INVALID_ARGUMENT);
        !           115: 
        !           116:        task_lock(task);
        !           117: 
        !           118:        /*
        !           119:         *  Check for wrong processor set.
        !           120:         */
        !           121:        if (pset != task->processor_set) {
        !           122:                task_unlock(task);
        !           123:                return(KERN_FAILURE);
        !           124:        }
        !           125: 
        !           126:        /* get pointer to scheduling policy-specific data */
        !           127:        assert(task->sp_attributes != SP_ATTRIBUTES_NULL);
        !           128:        sp_attr = (mk_sp_attributes_t)task->sp_attributes;
        !           129: 
        !           130:         sp_attr->max_priority = max_priority;
        !           131: 
        !           132:         /*
        !           133:          *      Reset priority if it violates new max priority
        !           134:          */
        !           135:         if (max_priority < sp_attr->priority) {
        !           136:             sp_attr->priority = max_priority;
        !           137:         }
        !           138: 
        !           139:        task_unlock(task);
        !           140: 
        !           141:        return(ret);
        !           142: }
        !           143: 
        !           144: 
        !           145: /*
        !           146:  *     task_policy
        !           147:  *
        !           148:  *     Set scheduling policy and parameters, both base and limit, for
        !           149:  *     the given task. Policy must be a policy which is enabled for the
        !           150:  *     processor set. Change contained threads if requested. 
        !           151:  */
        !           152: kern_return_t
        !           153: _mk_sp_task_policy(
        !           154:        sf_object_t             pol,
        !           155:        task_t                  task,
        !           156:         policy_t               policy,
        !           157:         policy_base_t          base,
        !           158:        mach_msg_type_number_t  count,
        !           159:         boolean_t              set_limit,
        !           160:         boolean_t              change,
        !           161:        policy_limit_t          *limit_ptr,
        !           162:        int                     *lc_ptr)
        !           163: {
        !           164:         policy_rr_limit_data_t         rr_limit;
        !           165:         policy_fifo_limit_data_t       fifo_limit;
        !           166:         policy_timeshare_limit_data_t  ts_limit;
        !           167:         kern_return_t                  ret = KERN_SUCCESS;
        !           168:        mk_sp_attributes_t              sp_attr;
        !           169: 
        !           170:        counter(c_mk_sp_task_policy++);
        !           171: 
        !           172:        /* this routine currently only works with 3 standard MK policies */
        !           173:        assert((task->policy == POLICY_TIMESHARE)
        !           174:               || (task->policy == POLICY_RR)
        !           175:               || (task->policy == POLICY_FIFO));
        !           176: 
        !           177:        if (set_limit) {
        !           178:                /*
        !           179:                 *      Set scheduling limits to base priority.
        !           180:                 */
        !           181:                switch (policy) {
        !           182:                case POLICY_RR:
        !           183:                {
        !           184:                        policy_rr_base_t rr_base;
        !           185: 
        !           186:                        if (count != POLICY_RR_BASE_COUNT)
        !           187:                                return(KERN_INVALID_ARGUMENT);
        !           188:                        *lc_ptr = POLICY_RR_LIMIT_COUNT;
        !           189:                        rr_base = (policy_rr_base_t) base;
        !           190:                        rr_limit.max_priority = rr_base->base_priority;
        !           191:                        *limit_ptr = (policy_limit_t) &rr_limit;
        !           192:                        break;
        !           193:                }
        !           194: 
        !           195:                case POLICY_FIFO:
        !           196:                {
        !           197:                        policy_fifo_base_t fifo_base;
        !           198: 
        !           199:                        if (count != POLICY_FIFO_BASE_COUNT)
        !           200:                                return(KERN_INVALID_ARGUMENT);
        !           201:                        *lc_ptr = POLICY_FIFO_LIMIT_COUNT;
        !           202:                        fifo_base = (policy_fifo_base_t) base;
        !           203:                        fifo_limit.max_priority = fifo_base->base_priority;
        !           204:                        *limit_ptr = (policy_limit_t) &fifo_limit;
        !           205:                        break;
        !           206:                }
        !           207: 
        !           208:                case POLICY_TIMESHARE:
        !           209:                {
        !           210:                        policy_timeshare_base_t ts_base;
        !           211: 
        !           212:                        if (count != POLICY_TIMESHARE_BASE_COUNT)
        !           213:                                return(KERN_INVALID_ARGUMENT);
        !           214:                        *lc_ptr = POLICY_TIMESHARE_LIMIT_COUNT;
        !           215:                        ts_base = (policy_timeshare_base_t) base;
        !           216:                        ts_limit.max_priority = ts_base->base_priority;
        !           217:                        *limit_ptr = (policy_limit_t) &ts_limit;
        !           218:                        break;
        !           219:                }
        !           220: 
        !           221:                default:
        !           222:                        return(KERN_INVALID_POLICY);
        !           223:                }
        !           224: 
        !           225:        } else {
        !           226:                /*
        !           227:                 *      Use current scheduling limits. Ensure that the
        !           228:                 *      new base priority will not exceed current limits.
        !           229:                 */
        !           230: 
        !           231:                /* get pointer to scheduling policy-specific data */
        !           232:                assert(task->sp_attributes != SP_ATTRIBUTES_NULL);
        !           233:                sp_attr = (mk_sp_attributes_t)task->sp_attributes;
        !           234: 
        !           235:                 switch (policy) {
        !           236:                 case POLICY_RR:
        !           237:                {
        !           238:                        policy_rr_base_t rr_base;
        !           239: 
        !           240:                        if (count != POLICY_RR_BASE_COUNT)
        !           241:                                return(KERN_INVALID_ARGUMENT);
        !           242:                        *lc_ptr = POLICY_RR_LIMIT_COUNT;
        !           243:                        rr_base = (policy_rr_base_t) base;
        !           244:                        if (rr_base->base_priority > sp_attr->max_priority) {
        !           245:                                ret = KERN_POLICY_LIMIT;
        !           246:                                break;
        !           247:                        }
        !           248:                         rr_limit.max_priority = sp_attr->max_priority;
        !           249:                        *limit_ptr = (policy_limit_t) &rr_limit;
        !           250:                         break;
        !           251:                }
        !           252: 
        !           253:                 case POLICY_FIFO:
        !           254:                {
        !           255:                        policy_fifo_base_t fifo_base;
        !           256: 
        !           257:                        if (count != POLICY_FIFO_BASE_COUNT)
        !           258:                                return(KERN_INVALID_ARGUMENT);
        !           259:                        *lc_ptr = POLICY_FIFO_LIMIT_COUNT;
        !           260:                        fifo_base = (policy_fifo_base_t) base;
        !           261:                        if (fifo_base->base_priority > sp_attr->max_priority) {
        !           262:                                ret = KERN_POLICY_LIMIT;
        !           263:                                break;
        !           264:                        }
        !           265:                         fifo_limit.max_priority = sp_attr->max_priority;
        !           266:                        *limit_ptr = (policy_limit_t) &fifo_limit;
        !           267:                         break;
        !           268:                }
        !           269: 
        !           270:                 case POLICY_TIMESHARE:
        !           271:                {
        !           272:                        policy_timeshare_base_t ts_base;
        !           273: 
        !           274:                        if (count != POLICY_TIMESHARE_BASE_COUNT)
        !           275:                                return(KERN_INVALID_ARGUMENT);
        !           276:                        *lc_ptr = POLICY_TIMESHARE_LIMIT_COUNT;
        !           277:                        ts_base = (policy_timeshare_base_t) base;
        !           278:                        if (ts_base->base_priority > sp_attr->max_priority) {
        !           279:                                ret = KERN_POLICY_LIMIT;
        !           280:                                break;
        !           281:                        }
        !           282:                         ts_limit.max_priority = sp_attr->max_priority;
        !           283:                        *limit_ptr = (policy_limit_t) &ts_limit;
        !           284:                         break;
        !           285:                }
        !           286: 
        !           287:                 default:
        !           288:                         return(KERN_INVALID_POLICY);
        !           289:                 }
        !           290: 
        !           291:        }
        !           292: 
        !           293:        return(ret);
        !           294: }
        !           295: 
        !           296: /*
        !           297:  *     task_set_policy
        !           298:  *
        !           299:  *     Set scheduling policy and parameters, both base and limit, for 
        !           300:  *     the given task. Policy can be any policy implemented by the
        !           301:  *     processor set, whether enabled or not. Change contained threads
        !           302:  *     if requested.
        !           303:  */
        !           304: kern_return_t
        !           305: _mk_sp_task_set_policy(
        !           306:        sf_object_t             pol,
        !           307:        task_t                  task,
        !           308:        processor_set_t         pset,
        !           309:        policy_t                policy,
        !           310:        policy_base_t           base,
        !           311:        mach_msg_type_number_t  base_count,
        !           312:        policy_limit_t          limit,
        !           313:        mach_msg_type_number_t  limit_count,
        !           314:        boolean_t               change)
        !           315: {
        !           316:        mk_sp_attributes_t      sp_attr;
        !           317:        kern_return_t           ret = KERN_SUCCESS;
        !           318: 
        !           319:        counter(c_mk_sp_task_set_policy++);
        !           320: 
        !           321:        /* check arguments */
        !           322:        switch (policy) {
        !           323:        case POLICY_RR:
        !           324:        {
        !           325:                policy_rr_base_t rr_base = (policy_rr_base_t) base;
        !           326:                policy_rr_limit_t rr_limit = (policy_rr_limit_t) limit;
        !           327: 
        !           328:                if (base_count != POLICY_RR_BASE_COUNT || 
        !           329:                    limit_count != POLICY_RR_LIMIT_COUNT) {
        !           330:                        ret = KERN_INVALID_ARGUMENT;
        !           331:                        break;
        !           332:                }
        !           333:                if (invalid_pri(rr_base->base_priority) ||
        !           334:                     invalid_pri(rr_limit->max_priority)) {
        !           335:                        ret = KERN_INVALID_ARGUMENT;
        !           336:                        break;
        !           337:                }
        !           338:                break;
        !           339:        }
        !           340: 
        !           341:        case POLICY_FIFO:
        !           342:        {
        !           343:                policy_fifo_base_t fifo_base = (policy_fifo_base_t) base;
        !           344:                policy_fifo_limit_t fifo_limit = (policy_fifo_limit_t) limit;
        !           345: 
        !           346:                if (base_count != POLICY_FIFO_BASE_COUNT || 
        !           347:                    limit_count != POLICY_FIFO_LIMIT_COUNT) {
        !           348:                        ret = KERN_INVALID_ARGUMENT;
        !           349:                        break;
        !           350:                }
        !           351:                if (invalid_pri(fifo_base->base_priority) ||
        !           352:                    invalid_pri(fifo_limit->max_priority)) {
        !           353:                        ret = KERN_INVALID_ARGUMENT;
        !           354:                         break;
        !           355:                 }
        !           356:                 break;
        !           357:        }
        !           358: 
        !           359:        case POLICY_TIMESHARE:
        !           360:        {
        !           361:                policy_timeshare_base_t ts_base = 
        !           362:                                        (policy_timeshare_base_t) base;
        !           363:                policy_timeshare_limit_t ts_limit = 
        !           364:                                        (policy_timeshare_limit_t) limit;
        !           365: 
        !           366:                if (base_count != POLICY_TIMESHARE_BASE_COUNT || 
        !           367:                    limit_count != POLICY_TIMESHARE_LIMIT_COUNT) {
        !           368:                        ret = KERN_INVALID_ARGUMENT;
        !           369:                        break;
        !           370:                }
        !           371:                if (invalid_pri(ts_base->base_priority) ||
        !           372:                    invalid_pri(ts_limit->max_priority)) {
        !           373:                        ret = KERN_INVALID_ARGUMENT;
        !           374:                         break;
        !           375:                 }
        !           376:                 break;
        !           377:        }
        !           378: 
        !           379:        default:
        !           380:                ret = KERN_INVALID_POLICY;
        !           381:        }
        !           382: 
        !           383:        /* stop if invalid arguments encountered */
        !           384:        if (ret != KERN_SUCCESS) {
        !           385:                return(ret);
        !           386:        }
        !           387: 
        !           388:        /* update task policy fields */
        !           389:        if ((task->policy == POLICY_TIMESHARE)
        !           390:               || (task->policy == POLICY_RR)
        !           391:               || (task->policy == POLICY_FIFO)) {
        !           392:                /* policies are close relatives; take advantage of that */
        !           393: 
        !           394:                /* get pointer to scheduling policy-specific data */
        !           395:                assert(task->sp_attributes != SP_ATTRIBUTES_NULL);
        !           396:                sp_attr = (mk_sp_attributes_t)task->sp_attributes;
        !           397: 
        !           398:                task->policy = policy;
        !           399:                sp_attr->policy_id = policy;
        !           400:        }
        !           401:        else {
        !           402:                /* old task policy is unrelated to standard MK policies */
        !           403:                /*** ??? fix me ***/
        !           404:                panic("mk_sp_task_set_policy");
        !           405:        }
        !           406: 
        !           407:        /* update scheduling parameters */
        !           408:        switch (policy) {
        !           409:        case POLICY_RR:
        !           410:        {
        !           411:                int temp;
        !           412:                policy_rr_base_t rr_base = (policy_rr_base_t) base;
        !           413:                policy_rr_limit_t rr_limit = (policy_rr_limit_t) limit;
        !           414: 
        !           415:                 temp = rr_base->quantum * 1000;
        !           416:                 if (temp % tick)
        !           417:                     temp += tick;
        !           418:                 sp_attr->sched_data = temp/tick;
        !           419:                sp_attr->priority = rr_base->base_priority;     
        !           420:                sp_attr->max_priority = rr_limit->max_priority; 
        !           421:                break;
        !           422:        }
        !           423: 
        !           424:        case POLICY_FIFO:
        !           425:        {
        !           426:                policy_fifo_base_t fifo_base = (policy_fifo_base_t) base;
        !           427:                policy_fifo_limit_t fifo_limit = (policy_fifo_limit_t) limit;
        !           428: 
        !           429:                sp_attr->sched_data = 0;
        !           430:                 sp_attr->priority = fifo_base->base_priority;        
        !           431:                sp_attr->max_priority = fifo_limit->max_priority;       
        !           432:                 break;
        !           433:        }
        !           434: 
        !           435:        case POLICY_TIMESHARE:
        !           436:        {
        !           437:                policy_timeshare_base_t ts_base = 
        !           438:                                        (policy_timeshare_base_t) base;
        !           439:                policy_timeshare_limit_t ts_limit = 
        !           440:                                        (policy_timeshare_limit_t) limit;
        !           441: 
        !           442:                sp_attr->sched_data = 0;
        !           443:                 sp_attr->priority = ts_base->base_priority;        
        !           444:                sp_attr->max_priority = ts_limit->max_priority; 
        !           445:                 break;
        !           446:        }
        !           447: 
        !           448:        default:
        !           449:                ret = KERN_INVALID_POLICY;
        !           450:        }
        !           451: 
        !           452:        return(ret);
        !           453: }
        !           454: 
        !           455: 
        !           456: kern_return_t
        !           457: _mk_sp_task_set_sched(
        !           458:        sf_object_t             pol,            /* policy */
        !           459:        task_t                  task,
        !           460:        policy_t                policy,
        !           461:        sched_attr_t            sched_attr,
        !           462:        mach_msg_type_number_t  sched_attrCnt,
        !           463:        boolean_t               set_limit,
        !           464:        boolean_t               change)
        !           465: {
        !           466:        counter(c_mk_sp_task_set_sched++);
        !           467: 
        !           468:        panic("not yet implemented???");
        !           469: 
        !           470:        return(KERN_FAILURE);
        !           471: }
        !           472: 
        !           473: 
        !           474: kern_return_t
        !           475: _mk_sp_task_get_sched(
        !           476:        sf_object_t             pol,            /* policy */
        !           477:        task_t                  task,
        !           478:        policy_t                policy,
        !           479:        sched_attr_t            sched_attr,
        !           480:        mach_msg_type_number_t  sched_attrCnt,
        !           481:        mach_msg_type_number_t  sched_attr_size)
        !           482: {
        !           483:        counter(c_mk_sp_task_get_sched++);
        !           484: 
        !           485:        panic("not yet implemented???");
        !           486: 
        !           487:        return(KERN_FAILURE);
        !           488: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.