Annotation of XNU/osfmk/kern/mk_sp_task.c, revision 1.1.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.