]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/kern/processor.h
xnu-1456.1.26.tar.gz
[apple/xnu.git] / osfmk / kern / processor.h
index c96731742d90ed9461c759ca1afe1b1ed09d47eb..fcf61d0444612d7e04fa4dbfc64d74bbd1c461f5 100644 (file)
@@ -1,14 +1,19 @@
 /*
- * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2009 Apple Inc. All rights reserved.
  *
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ * 
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
  * 
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
@@ -18,7 +23,7 @@
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * 
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /*
  * @OSF_COPYRIGHT@
 #include <machine/ast_types.h>
 
 struct processor_set {
-       queue_head_t            idle_queue;             /* idle processors */
-       int                                     idle_count;             /* how many ? */
        queue_head_t            active_queue;   /* active processors */
+       queue_head_t            idle_queue;             /* idle processors */
 
-       queue_head_t            processors;             /* all processors here */
-       int                                     processor_count;/* how many ? */
-       decl_simple_lock_data(,sched_lock)      /* lock for runq and above */
-
-       struct  run_queue       runq;                   /* runq for this set */
+       processor_t                     low_pri, low_count;
 
-       queue_head_t            tasks;                  /* tasks assigned */
-       int                                     task_count;             /* how many */
-       queue_head_t            threads;                /* threads in this set */
-       int                                     thread_count;   /* how many */
-       int                                     ref_count;              /* structure ref count */
-       boolean_t                       active;                 /* is pset in use */
-       decl_mutex_data(,       lock)                   /* lock for above */
+       int                                     processor_count;
 
-       int                                     timeshare_quanta;       /* timeshare quantum factor */
+       decl_simple_lock_data(,sched_lock)      /* lock for above */
 
        struct ipc_port *       pset_self;              /* port for operations */
        struct ipc_port *       pset_name_self; /* port for information */
 
-       uint32_t                        run_count;              /* threads running in set */
-       uint32_t                        share_count;    /* timeshare threads running in set */
+       processor_set_t         pset_list;              /* chain of associated psets */
+       pset_node_t                     node;
+};
+
+extern struct processor_set    pset0;
 
-       integer_t                       mach_factor;    /* mach_factor */
-       integer_t                       load_average;   /* load_average */
+struct pset_node {
+       processor_set_t         psets;                  /* list of associated psets */
 
-       uint32_t                        pri_shift;              /* timeshare usage -> priority */
+       pset_node_t                     nodes;                  /* list of associated subnodes */
+       pset_node_t                     node_list;              /* chain of associated nodes */
+
+       pset_node_t                     parent;
+};
+
+extern struct pset_node        pset_node0;
+
+extern queue_head_t            tasks, threads;
+extern int                             tasks_count, threads_count;
+decl_lck_mtx_data(extern,tasks_threads_lock)
+
+struct processor_meta {
+       queue_head_t            idle_queue;
+       processor_t                     primary;
 };
 
-extern struct processor_set    default_pset;
+typedef struct processor_meta  *processor_meta_t;
+#define PROCESSOR_META_NULL            ((processor_meta_t) 0)
 
 struct processor {
        queue_chain_t           processor_queue;/* idle/active queue link,
@@ -120,22 +132,23 @@ struct processor {
                                                *next_thread,   /* next thread when dispatched */
                                                *idle_thread;   /* this processor's idle thread. */
 
-       processor_set_t         processor_set;  /* current membership */
+       processor_set_t         processor_set;  /* assigned set */
 
        int                                     current_pri;    /* priority of current thread */
+       int                                     cpu_id;                 /* platform numeric id */
 
        timer_call_data_t       quantum_timer;  /* timer for quantum expiration */
        uint64_t                        quantum_end;    /* time when current quantum ends */
        uint64_t                        last_dispatch;  /* time of last dispatch */
 
-       int                                     timeslice;              /* quanta before timeslice ends */
        uint64_t                        deadline;               /* current deadline */
+       int                                     timeslice;              /* quanta before timeslice ends */
 
-       struct run_queue        runq;                   /* local runq for this processor */
+       struct run_queue        runq;                   /* runq for this processor */
+       processor_meta_t        processor_meta;
 
-       queue_chain_t           processors;             /* processors in set */
-       decl_simple_lock_data(,lock)
        struct ipc_port *       processor_self; /* port for operations */
+
        processor_t                     processor_list; /* all existing processors */
        processor_data_t        processor_data; /* per-processor data */
 };
@@ -144,115 +157,100 @@ extern processor_t              processor_list;
 extern unsigned int            processor_count;
 decl_simple_lock_data(extern,processor_list_lock)
 
-extern processor_t     master_processor;
+extern uint32_t                        processor_avail_count;
 
-/*
- *     NOTE: The processor->processor_set link is needed in one of the
- *     scheduler's critical paths.  [Figure out where to look for another
- *     thread to run on this processor.]  It is accessed without locking.
- *     The following access protocol controls this field.
- *
- *     Read from own processor - just read.
- *     Read from another processor - lock processor structure during read.
- *     Write from own processor - lock processor structure during write.
- *     Write from another processor - NOT PERMITTED.
- *
- */
+extern processor_t             master_processor;
 
 /*
- *     Processor state locking:
- *
- *     Values for the processor state are defined below.  If the processor
- *     is off-line or being shutdown, then it is only necessary to lock
- *     the processor to change its state.  Otherwise it is only necessary
- *     to lock its processor set's sched_lock.  Scheduler code will
- *     typically lock only the sched_lock, but processor manipulation code
- *     will often lock both.
+ *     Processor state is accessed by locking the scheduling lock
+ *     for the assigned processor set.
  */
-
 #define PROCESSOR_OFF_LINE             0       /* Not available */
-#define        PROCESSOR_RUNNING               1       /* Normal execution */
-#define        PROCESSOR_IDLE                  2       /* Idle */
-#define PROCESSOR_DISPATCHING  3       /* Dispatching (idle -> running) */
-#define PROCESSOR_SHUTDOWN             4       /* Going off-line */
-#define PROCESSOR_START                        5       /* Being started */
+#define PROCESSOR_SHUTDOWN             1       /* Going off-line */
+#define PROCESSOR_START                        2       /* Being started */
+#define PROCESSOR_INACTIVE             3       /* Inactive (unavailable) */
+#define        PROCESSOR_IDLE                  4       /* Idle (available) */
+#define PROCESSOR_DISPATCHING  5       /* Dispatching (idle -> active) */
+#define        PROCESSOR_RUNNING               6       /* Normal execution */
 
 extern processor_t     current_processor(void);
 
 extern processor_t     cpu_to_processor(
                                                int                     cpu);
 
-/* Useful lock macros */
-
-#define        pset_lock(pset)         mutex_lock(&(pset)->lock)
-#define        pset_lock_try(pset)     mutex_try(&(pset)->lock)
-#define pset_unlock(pset)      mutex_unlock(&(pset)->lock)
-
-#define processor_lock(pr)     simple_lock(&(pr)->lock)
-#define processor_unlock(pr)   simple_unlock(&(pr)->lock)
-
-extern void            processor_bootstrap(void);
+/* Lock macros */
+
+#define pset_lock(p)                   simple_lock(&(p)->sched_lock)
+#define pset_unlock(p)                 simple_unlock(&(p)->sched_lock)
+#define pset_lock_init(p)              simple_lock_init(&(p)->sched_lock, 0)
+
+/* Update hints */
+
+#define pset_pri_hint(ps, p, pri)              \
+MACRO_BEGIN                                                                                            \
+       if ((p) != (ps)->low_pri) {                                                     \
+               if ((pri) < (ps)->low_pri->current_pri)                 \
+                       (ps)->low_pri = (p);                                            \
+               else                                                                                    \
+               if ((ps)->low_pri->state < PROCESSOR_IDLE)              \
+                       (ps)->low_pri = (p);                                            \
+       }                                                                                                       \
+MACRO_END
+
+#define pset_count_hint(ps, p, cnt)            \
+MACRO_BEGIN                                                                                            \
+       if ((p) != (ps)->low_count) {                                           \
+               if ((cnt) < (ps)->low_count->runq.count)                \
+                       (ps)->low_count = (p);                                          \
+               else                                                                                    \
+               if ((ps)->low_count->state < PROCESSOR_IDLE)    \
+                       (ps)->low_count = (p);                                          \
+       }                                                                                                       \
+MACRO_END
+
+extern void            processor_bootstrap(void) __attribute__((section("__TEXT, initcode")));
 
 extern void            processor_init(
                                        processor_t             processor,
-                                       int                             slot_num);
+                                       int                             cpu_id,
+                                       processor_set_t processor_set) __attribute__((section("__TEXT, initcode")));
 
-extern void            timeshare_quanta_update(
-                                       processor_set_t         pset);
-
-extern void            pset_init(
-                                       processor_set_t         pset);
-
-#define pset_run_incr(pset)                                    \
-       hw_atomic_add(&(pset)->run_count, 1)
-
-#define pset_run_decr(pset)                                    \
-       hw_atomic_sub(&(pset)->run_count, 1)
-
-#define pset_share_incr(pset)                          \
-       hw_atomic_add(&(pset)->share_count, 1)
-
-#define pset_share_decr(pset)                          \
-       hw_atomic_sub(&(pset)->share_count, 1)
+extern void            processor_meta_init(
+                                       processor_t             processor,
+                                       processor_t             primary);
 
 extern kern_return_t   processor_shutdown(
                                                        processor_t             processor);
 
-extern void            pset_remove_processor(
-                                       processor_set_t         pset,
-                                       processor_t                     processor);
+extern void            processor_queue_shutdown(
+                                       processor_t             processor);
 
-extern void            pset_add_processor(
-                                       processor_set_t         pset,
-                                       processor_t                     processor);
+extern processor_set_t processor_pset(
+                                                       processor_t             processor);
 
-extern void            pset_remove_task(
-                                       processor_set_t         pset,
-                                       task_t                          task);
+extern pset_node_t             pset_node_root(void);
 
-extern void            pset_add_task(
-                                       processor_set_t         pset,
-                                       task_t                          task);
+extern processor_set_t pset_create(
+                                                       pset_node_t             node);
 
-extern void            pset_remove_thread(
-                                       processor_set_t         pset,
-                                       thread_t                        thread);
-
-extern void            pset_add_thread(
+extern void            pset_init(
                                        processor_set_t         pset,
-                                       thread_t                        thread);
-
-extern void            thread_change_psets(
-                                       thread_t                        thread,
-                                       processor_set_t         old_pset,
-                                       processor_set_t         new_pset);
-
+                                       pset_node_t                     node) __attribute__((section("__TEXT, initcode")));
 
 extern kern_return_t   processor_info_count(
                                                        processor_flavor_t              flavor,
                                                        mach_msg_type_number_t  *count);
 
-#endif /* MACH_KERNEL_PRIVATE */
+#define pset_deallocate(x)
+#define pset_reference(x)
+
+extern void                    machine_run_count(
+                                               uint32_t        count);
+
+extern boolean_t       machine_cpu_is_inactive(
+                                               int                     cpu_id);
+
+#else  /* MACH_KERNEL_PRIVATE */
 
 __BEGIN_DECLS
 
@@ -264,4 +262,6 @@ extern void         pset_reference(
 
 __END_DECLS
 
+#endif /* MACH_KERNEL_PRIVATE */
+
 #endif /* _KERN_PROCESSOR_H_ */