2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
26 * Mach Operating System
27 * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
28 * All Rights Reserved.
30 * Permission to use, copy, modify and distribute this software and its
31 * documentation is hereby granted, provided that both the copyright
32 * notice and this permission notice appear in all copies of the
33 * software, derivative works or modified versions, and any portions
34 * thereof, and that both notices appear in supporting documentation.
36 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
37 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
40 * Carnegie Mellon requests users of this software to return to
42 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
43 * School of Computer Science
44 * Carnegie Mellon University
45 * Pittsburgh PA 15213-3890
47 * any improvements or extensions that they make and grant Carnegie Mellon
48 * the rights to redistribute these changes.
54 * processor.c: processor and processor_set manipulation routines.
58 #include <mach_host.h>
60 #include <mach/boolean.h>
61 #include <mach/policy.h>
62 #include <mach/processor_info.h>
63 #include <mach/vm_param.h>
64 #include <kern/cpu_number.h>
65 #include <kern/host.h>
66 #include <kern/machine.h>
67 #include <kern/misc_protos.h>
68 #include <kern/processor.h>
69 #include <kern/sched.h>
70 #include <kern/task.h>
71 #include <kern/thread.h>
72 #include <kern/ipc_host.h>
73 #include <kern/ipc_tt.h>
74 #include <ipc/ipc_port.h>
75 #include <kern/kalloc.h>
78 #include <kern/zalloc.h>
80 #endif /* MACH_HOST */
83 #include <kern/mk_sp.h> /*** ??? fix so this can be removed ***/
88 #include <mach/mach_host_server.h>
93 struct processor_set default_pset
;
94 struct processor processor_array
[NCPUS
];
96 processor_t master_processor
;
97 processor_t processor_ptr
[NCPUS
];
101 processor_set_t pset
);
104 register processor_t pr
,
108 processor_set_t pset
);
110 kern_return_t
processor_set_base(
111 processor_set_t pset
,
116 kern_return_t
processor_set_limit(
117 processor_set_t pset
,
119 policy_limit_t limit
,
122 kern_return_t
processor_set_things(
123 processor_set_t pset
,
124 mach_port_t
**thing_list
,
125 mach_msg_type_number_t
*count
,
130 * Bootstrap the processor/pset system so the scheduler can run.
133 pset_sys_bootstrap(void)
137 pset_init(&default_pset
);
138 for (i
= 0; i
< NCPUS
; i
++) {
140 * Initialize processor data structures.
141 * Note that cpu_to_processor(i) is processor_ptr[i].
143 processor_ptr
[i
] = &processor_array
[i
];
144 processor_init(processor_ptr
[i
], i
);
146 master_processor
= cpu_to_processor(master_cpu
);
147 default_pset
.active
= TRUE
;
151 * Initialize the given processor_set structure.
155 register processor_set_t pset
)
159 /* setup run-queues */
160 simple_lock_init(&pset
->runq
.lock
, ETAP_THREAD_PSET_RUNQ
);
161 pset
->runq
.count
= 0;
162 for (i
= 0; i
< NRQBM
; i
++) {
163 pset
->runq
.bitmap
[i
] = 0;
165 setbit(MAXPRI
- IDLEPRI
, pset
->runq
.bitmap
);
166 pset
->runq
.highq
= IDLEPRI
;
167 for (i
= 0; i
< NRQS
; i
++) {
168 queue_init(&(pset
->runq
.queues
[i
]));
171 queue_init(&pset
->idle_queue
);
172 pset
->idle_count
= 0;
173 simple_lock_init(&pset
->idle_lock
, ETAP_THREAD_PSET_IDLE
);
174 pset
->mach_factor
= pset
->load_average
= 0;
175 pset
->sched_load
= 0;
176 queue_init(&pset
->processors
);
177 pset
->processor_count
= 0;
178 simple_lock_init(&pset
->processors_lock
, ETAP_THREAD_PSET
);
179 queue_init(&pset
->tasks
);
180 pset
->task_count
= 0;
181 queue_init(&pset
->threads
);
182 pset
->thread_count
= 0;
184 pset
->active
= FALSE
;
185 mutex_init(&pset
->lock
, ETAP_THREAD_PSET
);
186 pset
->pset_self
= IP_NULL
;
187 pset
->pset_name_self
= IP_NULL
;
188 pset
->max_priority
= MAXPRI_STANDARD
;
189 pset
->policies
= POLICY_TIMESHARE
| POLICY_FIFO
| POLICY_RR
;
190 pset
->set_quantum
= min_quantum
;
192 pset
->quantum_adj_index
= 0;
193 simple_lock_init(&pset
->quantum_adj_lock
, ETAP_THREAD_PSET_QUANT
);
195 for (i
= 0; i
<= NCPUS
; i
++) {
196 pset
->machine_quantum
[i
] = min_quantum
;
199 pset
->policy_default
= POLICY_TIMESHARE
;
200 pset
->policy_limit
.ts
.max_priority
= MAXPRI_STANDARD
;
201 pset
->policy_limit
.rr
.max_priority
= MAXPRI_STANDARD
;
202 pset
->policy_limit
.fifo
.max_priority
= MAXPRI_STANDARD
;
203 pset
->policy_base
.ts
.base_priority
= BASEPRI_DEFAULT
;
204 pset
->policy_base
.rr
.base_priority
= BASEPRI_DEFAULT
;
205 pset
->policy_base
.rr
.quantum
= min_quantum
;
206 pset
->policy_base
.fifo
.base_priority
= BASEPRI_DEFAULT
;
210 * Initialize the given processor structure for the processor in
211 * the slot specified by slot_num.
215 register processor_t pr
,
220 /* setup run-queues */
221 simple_lock_init(&pr
->runq
.lock
, ETAP_THREAD_PROC_RUNQ
);
223 for (i
= 0; i
< NRQBM
; i
++) {
224 pr
->runq
.bitmap
[i
] = 0;
226 setbit(MAXPRI
- IDLEPRI
, pr
->runq
.bitmap
);
227 pr
->runq
.highq
= IDLEPRI
;
228 for (i
= 0; i
< NRQS
; i
++) {
229 queue_init(&(pr
->runq
.queues
[i
]));
232 queue_init(&pr
->processor_queue
);
233 pr
->state
= PROCESSOR_OFF_LINE
;
234 pr
->next_thread
= THREAD_NULL
;
235 pr
->idle_thread
= THREAD_NULL
;
237 pr
->first_quantum
= FALSE
;
238 pr
->last_quantum
= 0;
239 pr
->processor_set
= PROCESSOR_SET_NULL
;
240 pr
->processor_set_next
= PROCESSOR_SET_NULL
;
241 queue_init(&pr
->processors
);
242 simple_lock_init(&pr
->lock
, ETAP_THREAD_PROC
);
243 pr
->processor_self
= IP_NULL
;
244 pr
->slot_num
= slot_num
;
248 * pset_remove_processor() removes a processor from a processor_set.
249 * It can only be called on the current processor. Caller must
250 * hold lock on current processor and processor set.
253 pset_remove_processor(
254 processor_set_t pset
,
255 processor_t processor
)
257 if (pset
!= processor
->processor_set
)
258 panic("pset_remove_processor: wrong pset");
260 queue_remove(&pset
->processors
, processor
, processor_t
, processors
);
261 processor
->processor_set
= PROCESSOR_SET_NULL
;
262 pset
->processor_count
--;
267 * pset_add_processor() adds a processor to a processor_set.
268 * It can only be called on the current processor. Caller must
269 * hold lock on curent processor and on pset. No reference counting on
270 * processors. Processor reference to pset is implicit.
274 processor_set_t pset
,
275 processor_t processor
)
277 queue_enter(&pset
->processors
, processor
, processor_t
, processors
);
278 processor
->processor_set
= pset
;
279 pset
->processor_count
++;
284 * pset_remove_task() removes a task from a processor_set.
285 * Caller must hold locks on pset and task. Pset reference count
286 * is not decremented; caller must explicitly pset_deallocate.
290 processor_set_t pset
,
293 if (pset
!= task
->processor_set
)
296 queue_remove(&pset
->tasks
, task
, task_t
, pset_tasks
);
297 task
->processor_set
= PROCESSOR_SET_NULL
;
302 * pset_add_task() adds a task to a processor_set.
303 * Caller must hold locks on pset and task. Pset references to
304 * tasks are implicit.
308 processor_set_t pset
,
311 queue_enter(&pset
->tasks
, task
, task_t
, pset_tasks
);
312 task
->processor_set
= pset
;
318 * pset_remove_thread() removes a thread from a processor_set.
319 * Caller must hold locks on pset and thread. Pset reference count
320 * is not decremented; caller must explicitly pset_deallocate.
324 processor_set_t pset
,
327 queue_remove(&pset
->threads
, thread
, thread_t
, pset_threads
);
328 thread
->processor_set
= PROCESSOR_SET_NULL
;
329 pset
->thread_count
--;
333 * pset_add_thread() adds a thread to a processor_set.
334 * Caller must hold locks on pset and thread. Pset references to
335 * threads are implicit.
339 processor_set_t pset
,
342 queue_enter(&pset
->threads
, thread
, thread_t
, pset_threads
);
343 thread
->processor_set
= pset
;
344 pset
->thread_count
++;
349 * thread_change_psets() changes the pset of a thread. Caller must
350 * hold locks on both psets and thread. The old pset must be
351 * explicitly pset_deallocat()'ed by caller.
356 processor_set_t old_pset
,
357 processor_set_t new_pset
)
359 queue_remove(&old_pset
->threads
, thread
, thread_t
, pset_threads
);
360 old_pset
->thread_count
--;
361 queue_enter(&new_pset
->threads
, thread
, thread_t
, pset_threads
);
362 thread
->processor_set
= new_pset
;
363 new_pset
->thread_count
++;
364 new_pset
->ref_count
++;
370 * Remove one reference to the processor set. Destroy processor_set
371 * if this was the last reference.
375 processor_set_t pset
)
377 if (pset
== PROCESSOR_SET_NULL
)
381 if (--pset
->ref_count
> 0) {
386 panic("pset_deallocate: default_pset destroyed");
392 * Add one reference to the processor set.
396 processor_set_t pset
)
405 processor_info_count(
406 processor_flavor_t flavor
,
407 mach_msg_type_number_t
*count
)
412 case PROCESSOR_BASIC_INFO
:
413 *count
= PROCESSOR_BASIC_INFO_COUNT
;
415 case PROCESSOR_CPU_LOAD_INFO
:
416 *count
= PROCESSOR_CPU_LOAD_INFO_COUNT
;
419 kr
= cpu_info_count(flavor
, count
);
427 register processor_t processor
,
428 processor_flavor_t flavor
,
430 processor_info_t info
,
431 mach_msg_type_number_t
*count
)
433 register int i
, slot_num
, state
;
434 register processor_basic_info_t basic_info
;
435 register processor_cpu_load_info_t cpu_load_info
;
438 if (processor
== PROCESSOR_NULL
)
439 return(KERN_INVALID_ARGUMENT
);
441 slot_num
= processor
->slot_num
;
445 case PROCESSOR_BASIC_INFO
:
447 if (*count
< PROCESSOR_BASIC_INFO_COUNT
)
448 return(KERN_FAILURE
);
450 basic_info
= (processor_basic_info_t
) info
;
451 basic_info
->cpu_type
= machine_slot
[slot_num
].cpu_type
;
452 basic_info
->cpu_subtype
= machine_slot
[slot_num
].cpu_subtype
;
453 state
= processor
->state
;
454 if (state
== PROCESSOR_OFF_LINE
)
455 basic_info
->running
= FALSE
;
457 basic_info
->running
= TRUE
;
458 basic_info
->slot_num
= slot_num
;
459 if (processor
== master_processor
)
460 basic_info
->is_master
= TRUE
;
462 basic_info
->is_master
= FALSE
;
464 *count
= PROCESSOR_BASIC_INFO_COUNT
;
466 return(KERN_SUCCESS
);
468 case PROCESSOR_CPU_LOAD_INFO
:
470 if (*count
< PROCESSOR_CPU_LOAD_INFO_COUNT
)
471 return(KERN_FAILURE
);
473 cpu_load_info
= (processor_cpu_load_info_t
) info
;
474 for (i
=0;i
<CPU_STATE_MAX
;i
++)
475 cpu_load_info
->cpu_ticks
[i
] = machine_slot
[slot_num
].cpu_ticks
[i
];
477 *count
= PROCESSOR_CPU_LOAD_INFO_COUNT
;
479 return(KERN_SUCCESS
);
483 kr
=cpu_info(flavor
, slot_num
, info
, count
);
484 if (kr
== KERN_SUCCESS
)
493 processor_t processor
)
499 if (processor
== PROCESSOR_NULL
)
500 return(KERN_INVALID_ARGUMENT
);
502 if (processor
== master_processor
)
503 return(cpu_start(processor
->slot_num
));
506 processor_lock(processor
);
508 state
= processor
->state
;
509 if (state
!= PROCESSOR_OFF_LINE
) {
510 processor_unlock(processor
);
512 return(KERN_FAILURE
);
514 processor
->state
= PROCESSOR_START
;
515 processor_unlock(processor
);
518 if (processor
->next_thread
== THREAD_NULL
) {
520 extern void start_cpu_thread(void);
522 thread
= kernel_thread_with_priority(kernel_task
, MAXPRI_KERNBAND
,
523 start_cpu_thread
, FALSE
);
527 thread_bind_locked(thread
, processor
);
528 thread_go_locked(thread
, THREAD_AWAKENED
);
529 (void)rem_runq(thread
);
530 processor
->next_thread
= thread
;
531 thread_unlock(thread
);
535 kr
= cpu_start(processor
->slot_num
);
537 if (kr
!= KERN_SUCCESS
) {
539 processor_lock(processor
);
540 processor
->state
= PROCESSOR_OFF_LINE
;
541 processor_unlock(processor
);
550 processor_t processor
)
552 if (processor
== PROCESSOR_NULL
)
553 return(KERN_INVALID_ARGUMENT
);
555 return(processor_shutdown(processor
));
560 processor_t processor
,
561 processor_info_t info
,
562 mach_msg_type_number_t count
)
564 if (processor
== PROCESSOR_NULL
)
565 return(KERN_INVALID_ARGUMENT
);
567 return(cpu_control(processor
->slot_num
, info
, count
));
571 * Precalculate the appropriate system quanta based on load. The
572 * index into machine_quantum is the number of threads on the
573 * processor set queue. It is limited to the number of processors in
579 processor_set_t pset
)
582 register int i
, ncpus
;
584 ncpus
= pset
->processor_count
;
586 for (i
=1; i
<= ncpus
; i
++)
587 pset
->machine_quantum
[i
] = ((min_quantum
* ncpus
) + (i
/ 2)) / i
;
589 pset
->machine_quantum
[0] = pset
->machine_quantum
[1];
591 i
= (pset
->runq
.count
> ncpus
) ? ncpus
: pset
->runq
.count
;
592 pset
->set_quantum
= pset
->machine_quantum
[i
];
593 #else /* NCPUS > 1 */
594 default_pset
.set_quantum
= min_quantum
;
595 #endif /* NCPUS > 1 */
599 processor_set_create(
601 processor_set_t
*new_set
,
602 processor_set_t
*new_name
)
605 host
++; new_set
++; new_name
++;
607 return(KERN_FAILURE
);
611 processor_set_destroy(
612 processor_set_t pset
)
617 return(KERN_FAILURE
);
621 processor_get_assignment(
622 processor_t processor
,
623 processor_set_t
*pset
)
627 state
= processor
->state
;
628 if (state
== PROCESSOR_SHUTDOWN
|| state
== PROCESSOR_OFF_LINE
)
629 return(KERN_FAILURE
);
631 *pset
= processor
->processor_set
;
632 pset_reference(*pset
);
633 return(KERN_SUCCESS
);
638 processor_set_t pset
,
641 processor_set_info_t info
,
642 mach_msg_type_number_t
*count
)
644 if (pset
== PROCESSOR_SET_NULL
)
645 return(KERN_INVALID_ARGUMENT
);
647 if (flavor
== PROCESSOR_SET_BASIC_INFO
) {
648 register processor_set_basic_info_t basic_info
;
650 if (*count
< PROCESSOR_SET_BASIC_INFO_COUNT
)
651 return(KERN_FAILURE
);
653 basic_info
= (processor_set_basic_info_t
) info
;
656 simple_lock(&pset
->processors_lock
);
657 basic_info
->processor_count
= pset
->processor_count
;
658 simple_unlock(&pset
->processors_lock
);
659 basic_info
->default_policy
= pset
->policy_default
;
662 *count
= PROCESSOR_SET_BASIC_INFO_COUNT
;
664 return(KERN_SUCCESS
);
666 else if (flavor
== PROCESSOR_SET_TIMESHARE_DEFAULT
) {
667 register policy_timeshare_base_t ts_base
;
669 if (*count
< POLICY_TIMESHARE_BASE_COUNT
)
670 return(KERN_FAILURE
);
672 ts_base
= (policy_timeshare_base_t
) info
;
675 *ts_base
= pset
->policy_base
.ts
;
678 *count
= POLICY_TIMESHARE_BASE_COUNT
;
680 return(KERN_SUCCESS
);
682 else if (flavor
== PROCESSOR_SET_FIFO_DEFAULT
) {
683 register policy_fifo_base_t fifo_base
;
685 if (*count
< POLICY_FIFO_BASE_COUNT
)
686 return(KERN_FAILURE
);
688 fifo_base
= (policy_fifo_base_t
) info
;
691 *fifo_base
= pset
->policy_base
.fifo
;
694 *count
= POLICY_FIFO_BASE_COUNT
;
696 return(KERN_SUCCESS
);
698 else if (flavor
== PROCESSOR_SET_RR_DEFAULT
) {
699 register policy_rr_base_t rr_base
;
701 if (*count
< POLICY_RR_BASE_COUNT
)
702 return(KERN_FAILURE
);
704 rr_base
= (policy_rr_base_t
) info
;
707 *rr_base
= pset
->policy_base
.rr
;
710 *count
= POLICY_RR_BASE_COUNT
;
712 return(KERN_SUCCESS
);
714 else if (flavor
== PROCESSOR_SET_TIMESHARE_LIMITS
) {
715 register policy_timeshare_limit_t ts_limit
;
717 if (*count
< POLICY_TIMESHARE_LIMIT_COUNT
)
718 return(KERN_FAILURE
);
720 ts_limit
= (policy_timeshare_limit_t
) info
;
723 *ts_limit
= pset
->policy_limit
.ts
;
726 *count
= POLICY_TIMESHARE_LIMIT_COUNT
;
728 return(KERN_SUCCESS
);
730 else if (flavor
== PROCESSOR_SET_FIFO_LIMITS
) {
731 register policy_fifo_limit_t fifo_limit
;
733 if (*count
< POLICY_FIFO_LIMIT_COUNT
)
734 return(KERN_FAILURE
);
736 fifo_limit
= (policy_fifo_limit_t
) info
;
739 *fifo_limit
= pset
->policy_limit
.fifo
;
742 *count
= POLICY_FIFO_LIMIT_COUNT
;
744 return(KERN_SUCCESS
);
746 else if (flavor
== PROCESSOR_SET_RR_LIMITS
) {
747 register policy_rr_limit_t rr_limit
;
749 if (*count
< POLICY_RR_LIMIT_COUNT
)
750 return(KERN_FAILURE
);
752 rr_limit
= (policy_rr_limit_t
) info
;
755 *rr_limit
= pset
->policy_limit
.rr
;
758 *count
= POLICY_RR_LIMIT_COUNT
;
760 return(KERN_SUCCESS
);
762 else if (flavor
== PROCESSOR_SET_ENABLED_POLICIES
) {
763 register int *enabled
;
765 if (*count
< (sizeof(*enabled
)/sizeof(int)))
766 return(KERN_FAILURE
);
768 enabled
= (int *) info
;
771 *enabled
= pset
->policies
;
774 *count
= sizeof(*enabled
)/sizeof(int);
776 return(KERN_SUCCESS
);
781 return(KERN_INVALID_ARGUMENT
);
785 * processor_set_statistics
787 * Returns scheduling statistics for a processor set.
790 processor_set_statistics(
791 processor_set_t pset
,
793 processor_set_info_t info
,
794 mach_msg_type_number_t
*count
)
796 if (pset
== PROCESSOR_SET_NULL
)
797 return (KERN_INVALID_PROCESSOR_SET
);
799 if (flavor
== PROCESSOR_SET_LOAD_INFO
) {
800 register processor_set_load_info_t load_info
;
802 if (*count
< PROCESSOR_SET_LOAD_INFO_COUNT
)
803 return(KERN_FAILURE
);
805 load_info
= (processor_set_load_info_t
) info
;
808 load_info
->task_count
= pset
->task_count
;
809 load_info
->thread_count
= pset
->thread_count
;
810 simple_lock(&pset
->processors_lock
);
811 load_info
->mach_factor
= pset
->mach_factor
;
812 load_info
->load_average
= pset
->load_average
;
813 simple_unlock(&pset
->processors_lock
);
816 *count
= PROCESSOR_SET_LOAD_INFO_COUNT
;
817 return(KERN_SUCCESS
);
820 return(KERN_INVALID_ARGUMENT
);
824 * processor_set_max_priority:
826 * Specify max priority permitted on processor set. This affects
827 * newly created and assigned threads. Optionally change existing
831 processor_set_max_priority(
832 processor_set_t pset
,
834 boolean_t change_threads
)
836 return (KERN_INVALID_ARGUMENT
);
840 * processor_set_policy_enable:
842 * Allow indicated policy on processor set.
846 processor_set_policy_enable(
847 processor_set_t pset
,
850 return (KERN_INVALID_ARGUMENT
);
854 * processor_set_policy_disable:
856 * Forbid indicated policy on processor set. Time sharing cannot
860 processor_set_policy_disable(
861 processor_set_t pset
,
863 boolean_t change_threads
)
865 return (KERN_INVALID_ARGUMENT
);
869 #define THING_THREAD 1
872 * processor_set_things:
874 * Common internals for processor_set_{threads,tasks}
877 processor_set_things(
878 processor_set_t pset
,
879 mach_port_t
**thing_list
,
880 mach_msg_type_number_t
*count
,
883 unsigned int actual
; /* this many things */
886 vm_size_t size
, size_needed
;
889 if (pset
== PROCESSOR_SET_NULL
)
890 return KERN_INVALID_ARGUMENT
;
901 if (type
== THING_TASK
)
902 actual
= pset
->task_count
;
904 actual
= pset
->thread_count
;
906 /* do we have the memory we need? */
908 size_needed
= actual
* sizeof(mach_port_t
);
909 if (size_needed
<= size
)
912 /* unlock the pset and allocate more memory */
918 assert(size_needed
> 0);
923 return KERN_RESOURCE_SHORTAGE
;
926 /* OK, have memory and the processor_set is locked & active */
930 task_t
*tasks
= (task_t
*) addr
;
933 for (i
= 0, task
= (task_t
) queue_first(&pset
->tasks
);
935 i
++, task
= (task_t
) queue_next(&task
->pset_tasks
)) {
936 /* take ref for convert_task_to_port */
937 task_reference(task
);
940 assert(queue_end(&pset
->tasks
, (queue_entry_t
) task
));
945 thread_act_t
*thr_acts
= (thread_act_t
*) addr
;
947 thread_act_t thr_act
;
950 list
= &pset
->threads
;
951 thread
= (thread_t
) queue_first(list
);
953 while (i
< actual
&& !queue_end(list
, (queue_entry_t
)thread
)) {
954 thr_act
= thread_lock_act(thread
);
955 if (thr_act
&& thr_act
->ref_count
> 0) {
956 /* take ref for convert_act_to_port */
957 act_locked_act_reference(thr_act
);
958 thr_acts
[i
] = thr_act
;
961 thread_unlock_act(thread
);
962 thread
= (thread_t
) queue_next(&thread
->pset_threads
);
966 size_needed
= actual
* sizeof(mach_port_t
);
972 /* can unlock processor set now that we have the task/thread refs */
976 /* no things, so return null pointer and deallocate memory */
983 /* if we allocated too much, must copy */
985 if (size_needed
< size
) {
988 newaddr
= kalloc(size_needed
);
992 task_t
*tasks
= (task_t
*) addr
;
994 for (i
= 0; i
< actual
; i
++)
995 task_deallocate(tasks
[i
]);
1000 thread_t
*threads
= (thread_t
*) addr
;
1002 for (i
= 0; i
< actual
; i
++)
1003 thread_deallocate(threads
[i
]);
1008 return KERN_RESOURCE_SHORTAGE
;
1011 bcopy((char *) addr
, (char *) newaddr
, size_needed
);
1016 *thing_list
= (mach_port_t
*) addr
;
1019 /* do the conversion that Mig should handle */
1023 task_t
*tasks
= (task_t
*) addr
;
1025 for (i
= 0; i
< actual
; i
++)
1026 (*thing_list
)[i
] = convert_task_to_port(tasks
[i
]);
1030 case THING_THREAD
: {
1031 thread_act_t
*thr_acts
= (thread_act_t
*) addr
;
1033 for (i
= 0; i
< actual
; i
++)
1034 (*thing_list
)[i
] = convert_act_to_port(thr_acts
[i
]);
1040 return(KERN_SUCCESS
);
1045 * processor_set_tasks:
1047 * List all tasks in the processor set.
1050 processor_set_tasks(
1051 processor_set_t pset
,
1052 task_array_t
*task_list
,
1053 mach_msg_type_number_t
*count
)
1055 return(processor_set_things(pset
, (mach_port_t
**)task_list
, count
, THING_TASK
));
1059 * processor_set_threads:
1061 * List all threads in the processor set.
1064 processor_set_threads(
1065 processor_set_t pset
,
1066 thread_array_t
*thread_list
,
1067 mach_msg_type_number_t
*count
)
1069 return(processor_set_things(pset
, (mach_port_t
**)thread_list
, count
, THING_THREAD
));
1073 * processor_set_base:
1075 * Specify per-policy base priority for a processor set. Set processor
1076 * set default policy to the given policy. This affects newly created
1077 * and assigned threads. Optionally change existing ones.
1081 processor_set_t pset
,
1086 return (KERN_INVALID_ARGUMENT
);
1090 * processor_set_limit:
1092 * Specify per-policy limits for a processor set. This affects
1093 * newly created and assigned threads. Optionally change existing
1097 processor_set_limit(
1098 processor_set_t pset
,
1100 policy_limit_t limit
,
1103 return (KERN_POLICY_LIMIT
);
1107 * processor_set_policy_control
1109 * Controls the scheduling attributes governing the processor set.
1110 * Allows control of enabled policies, and per-policy base and limit
1114 processor_set_policy_control(
1115 processor_set_t pset
,
1117 processor_set_info_t policy_info
,
1118 mach_msg_type_number_t count
,
1121 return (KERN_INVALID_ARGUMENT
);