|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.