summaryrefslogtreecommitdiff
path: root/kern
diff options
context:
space:
mode:
Diffstat (limited to 'kern')
-rw-r--r--kern/act.c34
-rw-r--r--kern/act.h5
-rw-r--r--kern/assert.h17
-rw-r--r--kern/ast.c22
-rw-r--r--kern/ast.h2
-rw-r--r--kern/boot_script.c6
-rw-r--r--kern/boot_script.h4
-rw-r--r--kern/bootstrap.c52
-rw-r--r--kern/bootstrap.h24
-rw-r--r--kern/counters.c6
-rw-r--r--kern/counters.h6
-rw-r--r--kern/debug.c21
-rw-r--r--kern/debug.h4
-rw-r--r--kern/elf-load.c2
-rw-r--r--kern/eventcount.c21
-rw-r--r--kern/eventcount.h7
-rw-r--r--kern/exception.c114
-rw-r--r--kern/exception.h66
-rw-r--r--kern/host.c26
-rw-r--r--kern/ipc_host.c2
-rw-r--r--kern/ipc_kobject.c30
-rw-r--r--kern/ipc_kobject.h5
-rw-r--r--kern/ipc_mig.c236
-rw-r--r--kern/ipc_mig.h79
-rw-r--r--kern/ipc_sched.c12
-rw-r--r--kern/ipc_tt.c68
-rw-r--r--kern/list.h6
-rw-r--r--kern/lock.c36
-rw-r--r--kern/lock.h8
-rw-r--r--kern/lock_mon.c51
-rw-r--r--kern/mach_clock.c79
-rw-r--r--kern/mach_clock.h9
-rw-r--r--kern/mach_factor.c16
-rw-r--r--kern/machine.c102
-rw-r--r--kern/machine.h2
-rw-r--r--kern/macro_help.h55
-rw-r--r--kern/macros.h72
-rw-r--r--kern/pc_sample.c42
-rw-r--r--kern/pc_sample.h2
-rw-r--r--kern/printf.c112
-rw-r--r--kern/printf.h16
-rw-r--r--kern/priority.c18
-rw-r--r--kern/priority.h28
-rw-r--r--kern/processor.c49
-rw-r--r--kern/processor.h6
-rw-r--r--kern/profile.c2
-rw-r--r--kern/queue.c24
-rw-r--r--kern/queue.h41
-rw-r--r--kern/rbtree.h10
-rw-r--r--kern/rdxtree.c830
-rw-r--r--kern/rdxtree.h209
-rw-r--r--kern/rdxtree_i.h66
-rw-r--r--kern/refcount.h8
-rw-r--r--kern/sched.h8
-rw-r--r--kern/sched_prim.c236
-rw-r--r--kern/sched_prim.h29
-rw-r--r--kern/server_loop.ch104
-rw-r--r--kern/shuttle.h2
-rw-r--r--kern/slab.c143
-rw-r--r--kern/slab.h32
-rw-r--r--kern/startup.c53
-rw-r--r--kern/startup.h28
-rw-r--r--kern/strings.c40
-rw-r--r--kern/syscall_emulation.c54
-rw-r--r--kern/syscall_emulation.h6
-rw-r--r--kern/syscall_subr.c58
-rw-r--r--kern/syscall_subr.h1
-rw-r--r--kern/syscall_sw.c29
-rw-r--r--kern/task.c181
-rw-r--r--kern/task.h22
-rw-r--r--kern/task_notify.cli7
-rw-r--r--kern/thread.c181
-rw-r--r--kern/thread.h43
-rw-r--r--kern/thread_swap.c27
-rw-r--r--kern/thread_swap.h5
-rw-r--r--kern/time_stamp.c24
-rw-r--r--kern/timer.c89
-rw-r--r--kern/timer.h6
-rw-r--r--kern/xpr.c29
-rw-r--r--kern/xpr.h2
80 files changed, 2707 insertions, 1502 deletions
diff --git a/kern/act.c b/kern/act.c
index 36fa79c1..3186f7e9 100644
--- a/kern/act.c
+++ b/kern/act.c
@@ -64,7 +64,7 @@ static Act free_acts[ACT_STATIC_KLUDGE];
Act null_act;
void
-global_act_init()
+global_act_init(void)
{
#ifndef ACT_STATIC_KLUDGE
kmem_cache_init(&act_cache, "Act", sizeof(struct Act), 0,
@@ -97,7 +97,6 @@ kern_return_t act_create(task_t task, vm_offset_t user_stack,
struct Act **new_act)
{
Act *act;
- int rc;
#ifndef ACT_STATIC_KLUDGE
act = (Act*)kmem_cache_alloc(&act_cache);
@@ -258,7 +257,7 @@ void act_detach(Act *cur_act)
so RPC entry paths need not check it.
Locking: Act */
-void act_execute_returnhandlers()
+void act_execute_returnhandlers(void)
{
Act *act = current_act();
@@ -1014,11 +1013,11 @@ act_set_special_port(Act *act, int which, ipc_port_t port)
* Return thread's machine-dependent state.
*/
kern_return_t
-act_get_state_immediate(act, flavor, old_state, old_state_count)
- register Act *act;
- int flavor;
- void *old_state; /* pointer to OUT array */
- unsigned int *old_state_count; /*IN/OUT*/
+act_get_state_immediate(
+ Act *act,
+ int flavor,
+ void *old_state, /* pointer to OUT array */
+ unsigned int *old_state_count) /*IN/OUT*/
{
kern_return_t ret;
@@ -1040,11 +1039,11 @@ act_get_state_immediate(act, flavor, old_state, old_state_count)
* Change thread's machine-dependent state.
*/
kern_return_t
-act_set_state_immediate(act, flavor, new_state, new_state_count)
- register Act *act;
- int flavor;
- void *new_state;
- unsigned int new_state_count;
+act_set_state_immediate(
+ Act *act,
+ int flavor,
+ void *new_state,
+ unsigned int new_state_count)
{
kern_return_t ret;
@@ -1062,7 +1061,7 @@ act_set_state_immediate(act, flavor, new_state, new_state_count)
return act_set_state(act, flavor, new_state, new_state_count);
}
-void act_count()
+void act_count(void)
{
int i;
Act *act;
@@ -1077,7 +1076,7 @@ void act_count()
ACT_STATIC_KLUDGE-i, ACT_STATIC_KLUDGE, ACT_STATIC_KLUDGE-amin);
}
-dump_act(act)
+void dump_act(act)
Act *act;
{
act_count();
@@ -1098,8 +1097,7 @@ dump_act(act)
#ifdef ACTWATCH
Act *
-get_next_act(sp)
- int sp;
+get_next_act(int sp)
{
static int i;
Act *act;
@@ -1115,6 +1113,6 @@ get_next_act(sp)
return act;
}
}
-#endif
+#endif /* ACTWATCH */
#endif /* MIGRATING_THREADS */
diff --git a/kern/act.h b/kern/act.h
index e0647244..f46f53a3 100644
--- a/kern/act.h
+++ b/kern/act.h
@@ -40,8 +40,6 @@
#include <kern/refcount.h>
#include <kern/queue.h>
-#include "act.h"/*XXX*/
-
struct task;
struct thread;
struct Act;
@@ -176,7 +174,6 @@ kern_return_t act_terminate_task_locked(struct Act *act);
/* Exported to thread.c */
extern Act null_act;
-kern_return_t act_create_kernel(Act **out_act);
/* Exported to machine-dependent activation code */
void act_execute_returnhandlers(void);
@@ -192,4 +189,4 @@ kern_return_t act_machine_get_state(Act *inc, int flavor, int *tstate, unsigned
#endif /* MIGRATING_THREADS */
-#endif _KERN_ACT_H_
+#endif /* _KERN_ACT_H_ */
diff --git a/kern/assert.h b/kern/assert.h
index 2829728b..7b66d1b1 100644
--- a/kern/assert.h
+++ b/kern/assert.h
@@ -29,26 +29,21 @@
/* assert.h 4.2 85/01/21 */
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#ifndef NDEBUG
#define MACH_ASSERT 1
#endif
#if MACH_ASSERT
-extern void Assert(char *exp, char *filename, int line) __attribute__ ((noreturn));
+extern void Assert(const char *exp, const char *filename, int line) __attribute__ ((noreturn));
#define assert(ex) \
-MACRO_BEGIN \
- if (!(ex)) \
- Assert(#ex, __FILE__, __LINE__); \
-MACRO_END
-
-#ifdef lint
-#define assert_static(x)
-#else /* lint */
+ ((ex) \
+ ? (void) (0) \
+ : Assert (#ex, __FILE__, __LINE__))
+
#define assert_static(x) assert(x)
-#endif /* lint */
#else /* MACH_ASSERT */
#define assert(ex)
diff --git a/kern/ast.c b/kern/ast.c
index 97da3abc..4b9d63d6 100644
--- a/kern/ast.c
+++ b/kern/ast.c
@@ -56,10 +56,10 @@
volatile ast_t need_ast[NCPUS];
void
-ast_init()
+ast_init(void)
{
#ifndef MACHINE_AST
- register int i;
+ int i;
for (i=0; i<NCPUS; i++)
need_ast[i] = 0;
@@ -69,8 +69,8 @@ ast_init()
void
ast_taken(void)
{
- register thread_t self = current_thread();
- register ast_t reasons;
+ thread_t self = current_thread();
+ ast_t reasons;
/*
* Interrupts are still disabled.
@@ -114,12 +114,12 @@ ast_taken(void)
}
void
-ast_check()
+ast_check(void)
{
- register int mycpu = cpu_number();
- register processor_t myprocessor;
- register thread_t thread = current_thread();
- register run_queue_t rq;
+ int mycpu = cpu_number();
+ processor_t myprocessor;
+ thread_t thread = current_thread();
+ run_queue_t rq;
spl_t s = splsched();
/*
@@ -190,7 +190,7 @@ ast_check()
#endif /* MACH_FIXPRI */
rq = &(myprocessor->processor_set->runq);
if (!(myprocessor->first_quantum) && (rq->count > 0)) {
- register queue_t q;
+ queue_t q;
/*
* This is not the first quantum, and there may
* be something in the processor_set runq.
@@ -198,7 +198,7 @@ ast_check()
*/
q = rq->runq + *(volatile int *)&rq->low;
if (queue_empty(q)) {
- register int i;
+ int i;
/*
* Need to recheck and possibly update hint.
diff --git a/kern/ast.h b/kern/ast.h
index 4c28b1e6..7d472be9 100644
--- a/kern/ast.h
+++ b/kern/ast.h
@@ -41,7 +41,7 @@
*/
#include "cpu_number.h"
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#include <machine/ast.h>
/*
diff --git a/kern/boot_script.c b/kern/boot_script.c
index b2e9393b..b245d1d8 100644
--- a/kern/boot_script.c
+++ b/kern/boot_script.c
@@ -76,14 +76,14 @@ create_task (struct cmd *cmd, long *val)
/* Resume a task. */
static int
-resume_task (struct cmd *cmd, long *val)
+resume_task (struct cmd *cmd, const long *val)
{
return boot_script_task_resume (cmd);
}
/* Resume a task when the user hits return. */
static int
-prompt_resume_task (struct cmd *cmd, long *val)
+prompt_resume_task (struct cmd *cmd, const long *val)
{
return boot_script_prompt_task_resume (cmd);
}
@@ -485,7 +485,7 @@ boot_script_parse_line (void *hook, char *cmdline)
/* Execute commands previously parsed. */
int
-boot_script_exec ()
+boot_script_exec (void)
{
int cmd_index;
diff --git a/kern/boot_script.h b/kern/boot_script.h
index c5ad6732..c007d777 100644
--- a/kern/boot_script.h
+++ b/kern/boot_script.h
@@ -69,10 +69,6 @@ int boot_script_exec_cmd (void *hook,
task_t task, char *path, int argc,
char **argv, char *strings, int stringlen);
-/* The user must define this function. Load the contents of FILE
- into a fresh anonymous memory object and return the memory object port. */
-mach_port_t boot_script_read_file (const char *file);
-
/* The user must define this functions to perform the corresponding
Mach task manipulations. */
int boot_script_task_create (struct cmd *); /* task_create + task_suspend */
diff --git a/kern/bootstrap.c b/kern/bootstrap.c
index 4a39f26a..0a8dcedb 100644
--- a/kern/bootstrap.c
+++ b/kern/bootstrap.c
@@ -37,6 +37,7 @@
#include <mach/message.h>
#include <machine/locore.h>
#include <machine/vm_param.h>
+#include <machine/pcb.h>
#include <ipc/ipc_port.h>
#include <ipc/mach_port.h>
#include <kern/debug.h>
@@ -86,8 +87,8 @@ static mach_port_t boot_host_port; /* local name */
extern char *kernel_cmdline;
-static void user_bootstrap(); /* forward */
-static void user_bootstrap_compat(); /* forward */
+static void user_bootstrap(void); /* forward */
+static void user_bootstrap_compat(void); /* forward */
static void bootstrap_exec_compat(void *exec_data); /* forward */
static void get_compat_strings(char *flags_str, char *root_str); /* forward */
@@ -111,7 +112,7 @@ task_insert_send_right(
return name;
}
-void bootstrap_create()
+void bootstrap_create(void)
{
int compat;
int n = 0;
@@ -165,18 +166,18 @@ void bootstrap_create()
}
else
{
- int i, losers, maxlen;
+ int i, losers;
/* Initialize boot script variables. We leak these send rights. */
losers = boot_script_set_variable
("host-port", VAL_PORT,
- (long)ipc_port_make_send(realhost.host_priv_self));
+ (long) realhost.host_priv_self);
if (losers)
panic ("cannot set boot-script variable host-port: %s",
boot_script_error_string (losers));
losers = boot_script_set_variable
("device-port", VAL_PORT,
- (long) ipc_port_make_send(master_device_port));
+ (long) master_device_port);
if (losers)
panic ("cannot set boot-script variable device-port: %s",
boot_script_error_string (losers));
@@ -256,15 +257,11 @@ void bootstrap_create()
}
#endif
- maxlen = 0;
for (i = 0; i < boot_info.mods_count; ++i)
{
int err;
char *line = (char*)phystokv(bmods[i].string);
- int len = strlen (line) + 1;
- if (len > maxlen)
- maxlen = len;
- printf ("\rmodule %d: %*s", i, -maxlen, line);
+ printf ("module %d: %s\n", i, line);
err = boot_script_parse_line (&bmods[i], line);
if (err)
{
@@ -272,7 +269,7 @@ void bootstrap_create()
++losers;
}
}
- printf ("\r%d multiboot modules %*s", i, -maxlen, "");
+ printf ("%d multiboot modules\n", i);
if (losers)
panic ("%d of %d boot script commands could not be parsed",
losers, boot_info.mods_count);
@@ -334,7 +331,7 @@ itoa(
vm_size_t num)
{
char buf[sizeof(vm_size_t)*2+3];
- register char *np;
+ char *np;
np = buf + sizeof(buf);
*--np = 0;
@@ -354,7 +351,7 @@ itoa(
*/
static void get_compat_strings(char *flags_str, char *root_str)
{
- register char *ip, *cp;
+ char *ip, *cp;
strcpy (root_str, "UNKNOWN");
@@ -535,16 +532,12 @@ static void copy_bootstrap(void *e, exec_info_t *boot_exec_info)
/*
* Allocate the stack, and build the argument list.
*/
-extern vm_offset_t user_stack_low();
-extern vm_offset_t set_user_regs();
-
static void
build_args_and_stack(struct exec_info *boot_exec_info,
char **argv, char **envp)
{
vm_offset_t stack_base;
vm_size_t stack_size;
- register
char * arg_ptr;
int arg_count, envc;
int arg_len;
@@ -606,7 +599,7 @@ build_args_and_stack(struct exec_info *boot_exec_info,
/*
* first the argument count
*/
- (void) copyout((char *)&arg_count,
+ (void) copyout(&arg_count,
arg_pos,
sizeof(integer_t));
arg_pos += sizeof(integer_t);
@@ -619,7 +612,7 @@ build_args_and_stack(struct exec_info *boot_exec_info,
arg_item_len = strlen(arg_ptr) + 1; /* include trailing 0 */
/* set string pointer */
- (void) copyout((char *)&string_pos,
+ (void) copyout(&string_pos,
arg_pos,
sizeof (char *));
arg_pos += sizeof(char *);
@@ -632,7 +625,7 @@ build_args_and_stack(struct exec_info *boot_exec_info,
/*
* Null terminator for argv.
*/
- (void) copyout((char *)&zero, arg_pos, sizeof(char *));
+ (void) copyout(&zero, arg_pos, sizeof(char *));
arg_pos += sizeof(char *);
/*
@@ -643,7 +636,7 @@ build_args_and_stack(struct exec_info *boot_exec_info,
arg_item_len = strlen(arg_ptr) + 1; /* include trailing 0 */
/* set string pointer */
- (void) copyout((char *)&string_pos,
+ (void) copyout(&string_pos,
arg_pos,
sizeof (char *));
arg_pos += sizeof(char *);
@@ -656,12 +649,12 @@ build_args_and_stack(struct exec_info *boot_exec_info,
/*
* Null terminator for envp.
*/
- (void) copyout((char *)&zero, arg_pos, sizeof(char *));
+ (void) copyout(&zero, arg_pos, sizeof(char *));
}
static void
-user_bootstrap_compat()
+user_bootstrap_compat(void)
{
exec_info_t boot_exec_info;
@@ -748,7 +741,8 @@ boot_script_exec_cmd (void *hook, task_t task, char *path, int argc,
assert(err == 0);
thread->saved.other = &info;
thread_start (thread, user_bootstrap);
- thread_resume (thread);
+ err = thread_resume (thread);
+ assert(err == 0);
/* We need to synchronize with the new thread and block this
main thread until it has finished referring to our local state. */
@@ -757,13 +751,14 @@ boot_script_exec_cmd (void *hook, task_t task, char *path, int argc,
thread_sleep ((event_t) &info, simple_lock_addr(info.lock), FALSE);
simple_lock (&info.lock);
}
+ simple_unlock (&info.lock);
printf ("\n");
}
return 0;
}
-static void user_bootstrap()
+static void user_bootstrap(void)
{
struct user_bootstrap_info *info = current_thread()->saved.other;
exec_info_t boot_exec_info;
@@ -791,6 +786,7 @@ static void user_bootstrap()
simple_lock (&info->lock);
assert (!info->done);
info->done = 1;
+ simple_unlock (&info->lock);
thread_wakeup ((event_t) info);
/*
@@ -823,6 +819,7 @@ boot_script_task_create (struct cmd *cmd)
printf("boot_script_task_create failed with %x\n", rc);
return BOOT_SCRIPT_MACH_ERROR;
}
+ task_set_name(cmd->task, cmd->path);
return 0;
}
@@ -860,7 +857,8 @@ boot_script_free_task (task_t task, int aborting)
int
boot_script_insert_right (struct cmd *cmd, mach_port_t port, mach_port_t *name)
{
- *name = task_insert_send_right (cmd->task, (ipc_port_t)port);
+ *name = task_insert_send_right (cmd->task,
+ ipc_port_make_send((ipc_port_t) port));
return 0;
}
diff --git a/kern/bootstrap.h b/kern/bootstrap.h
new file mode 100644
index 00000000..b8ed8d9f
--- /dev/null
+++ b/kern/bootstrap.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _KERN_BOOTSTRAP_H_
+#define _KERN_BOOTSTRAP_H_
+
+extern void bootstrap_create(void);
+
+#endif /* _KERN_BOOTSTRAP_H_ */
diff --git a/kern/counters.c b/kern/counters.c
index a9d450e1..0a0665bf 100644
--- a/kern/counters.c
+++ b/kern/counters.c
@@ -32,13 +32,12 @@
* This makes them easier to examine with ddb.
*/
+#if MACH_COUNTERS
mach_counter_t c_thread_invoke_hits = 0;
mach_counter_t c_thread_invoke_misses = 0;
mach_counter_t c_thread_invoke_csw = 0;
mach_counter_t c_thread_handoff_hits = 0;
mach_counter_t c_thread_handoff_misses = 0;
-
-#if MACH_COUNTERS
mach_counter_t c_threads_current = 0;
mach_counter_t c_threads_max = 0;
mach_counter_t c_threads_min = 0;
@@ -47,6 +46,9 @@ mach_counter_t c_stacks_current = 0;
mach_counter_t c_stacks_max = 0;
mach_counter_t c_stacks_min = 0;
mach_counter_t c_stacks_total = 0;
+mach_counter_t c_stack_alloc_hits = 0;
+mach_counter_t c_stack_alloc_misses = 0;
+mach_counter_t c_stack_alloc_max = 0;
mach_counter_t c_clock_ticks = 0;
mach_counter_t c_ipc_mqueue_send_block = 0;
mach_counter_t c_ipc_mqueue_receive_block_user = 0;
diff --git a/kern/counters.h b/kern/counters.h
index 474c6a29..aa1e739b 100644
--- a/kern/counters.h
+++ b/kern/counters.h
@@ -55,13 +55,12 @@
typedef unsigned int mach_counter_t;
+#if MACH_COUNTERS
extern mach_counter_t c_thread_invoke_hits;
extern mach_counter_t c_thread_invoke_misses;
extern mach_counter_t c_thread_invoke_csw;
extern mach_counter_t c_thread_handoff_hits;
extern mach_counter_t c_thread_handoff_misses;
-
-#if MACH_COUNTERS
extern mach_counter_t c_threads_current;
extern mach_counter_t c_threads_max;
extern mach_counter_t c_threads_min;
@@ -70,6 +69,9 @@ extern mach_counter_t c_stacks_current;
extern mach_counter_t c_stacks_max;
extern mach_counter_t c_stacks_min;
extern mach_counter_t c_stacks_total;
+extern mach_counter_t c_stack_alloc_hits;
+extern mach_counter_t c_stack_alloc_misses;
+extern mach_counter_t c_stack_alloc_max;
extern mach_counter_t c_clock_ticks;
extern mach_counter_t c_ipc_mqueue_send_block;
extern mach_counter_t c_ipc_mqueue_receive_block_user;
diff --git a/kern/debug.c b/kern/debug.c
index 8a04f1db..faa03565 100644
--- a/kern/debug.c
+++ b/kern/debug.c
@@ -38,11 +38,7 @@
#include <machine/loose_ends.h>
#include <machine/model_dep.h>
-extern void cnputc();
-
-#if MACH_KDB
-extern int db_breakpoints_inserted;
-#endif
+#include <device/cons.h>
#if NCPUS>1
simple_lock_data_t Assert_print_lock; /* uninited, we take our chances */
@@ -55,7 +51,7 @@ do_cnputc(char c, vm_offset_t offset)
}
void
-Assert(char *exp, char *file, int line)
+Assert(const char *exp, const char *file, int line)
{
#if NCPUS > 1
simple_lock(&Assert_print_lock);
@@ -67,14 +63,11 @@ Assert(char *exp, char *file, int line)
exp, file, line);
#endif
-#if MACH_KDB
- if (db_breakpoints_inserted)
-#endif
Debugger("assertion failure");
}
void SoftDebugger(message)
- char * message;
+ const char *message;
{
printf("Debugger invoked: %s\n", message);
@@ -96,7 +89,7 @@ void SoftDebugger(message)
asm("ta 0x81");
#endif /* sun4 */
-#if defined(mips ) || defined(luna88k) || defined(i860) || defined(alpha)
+#if defined(mips ) || defined(i860) || defined(alpha)
gimmeabreak();
#endif
@@ -106,7 +99,7 @@ void SoftDebugger(message)
}
void Debugger(message)
- char * message;
+ const char *message;
{
#if !MACH_KDB
panic("Debugger invoked, but there isn't one!");
@@ -201,14 +194,12 @@ log(int level, const char *fmt, ...)
{
va_list listp;
-#ifdef lint
- level++;
-#endif
va_start(listp, fmt);
_doprnt(fmt, listp, do_cnputc, 0, 0);
va_end(listp);
}
+/* GCC references this for stack protection. */
unsigned char __stack_chk_guard [ sizeof (vm_offset_t) ] =
{
[ sizeof (vm_offset_t) - 3 ] = '\r',
diff --git a/kern/debug.h b/kern/debug.h
index e429bdd1..6c8977b8 100644
--- a/kern/debug.h
+++ b/kern/debug.h
@@ -62,7 +62,7 @@ extern void log (int level, const char *fmt, ...);
extern void panic_init(void);
extern void panic (const char *s, ...) __attribute__ ((noreturn));
-extern void SoftDebugger (char *message);
-extern void Debugger (char *message) __attribute__ ((noreturn));
+extern void SoftDebugger (const char *message);
+extern void Debugger (const char *message) __attribute__ ((noreturn));
#endif /* _mach_debug__debug_ */
diff --git a/kern/elf-load.c b/kern/elf-load.c
index 1d103d3c..441276ef 100644
--- a/kern/elf-load.c
+++ b/kern/elf-load.c
@@ -80,6 +80,8 @@ int exec_load(exec_read_func_t *read, exec_read_exec_func_t *read_exec,
result = (*read_exec)(handle,
ph->p_offset, ph->p_filesz,
ph->p_vaddr, ph->p_memsz, type);
+ if (result)
+ return result;
}
}
diff --git a/kern/eventcount.c b/kern/eventcount.c
index 6fcebff5..a9d7bd41 100644
--- a/kern/eventcount.c
+++ b/kern/eventcount.c
@@ -53,13 +53,6 @@
#include <kern/eventcount.h>
-
-#if NCPUS <= 1
-void simpler_thread_setrun(
- thread_t th,
- boolean_t may_preempt); /* forward */
-#endif
-
#define MAX_EVCS 10 /* xxx for now */
evc_t all_eventcounters[MAX_EVCS];
@@ -105,7 +98,7 @@ evc_destroy(evc_t ev)
* Thread termination.
* HORRIBLE. This stuff needs to be fixed.
*/
-void evc_notify_abort(thread_t thread)
+void evc_notify_abort(const thread_t thread)
{
int i;
evc_t ev;
@@ -130,7 +123,7 @@ void evc_notify_abort(thread_t thread)
* Just so that we return success, and give
* up the stack while blocked
*/
-static void
+static void __attribute__((noreturn))
evc_continue(void)
{
thread_syscall_return(KERN_SUCCESS);
@@ -235,8 +228,8 @@ kern_return_t evc_wait_clear(natural_t ev_id)
void
evc_signal(evc_t ev)
{
- register volatile thread_t thread;
- register int state;
+ volatile thread_t thread;
+ int state;
spl_t s;
if (ev->sanity != ev)
return;
@@ -325,8 +318,8 @@ simpler_thread_setrun(
thread_t th,
boolean_t may_preempt)
{
- register struct run_queue *rq;
- register int whichq;
+ struct run_queue *rq;
+ int whichq;
/*
* XXX should replace queue with a boolean in this case.
@@ -347,7 +340,7 @@ simpler_thread_setrun(
whichq = (th)->sched_pri;
simple_lock(&(rq)->lock); /* lock the run queue */
- enqueue_head(&(rq)->runq[whichq], (queue_entry_t) (th));
+ enqueue_head(&(rq)->runq[whichq], &((th)->links));
if (whichq < (rq)->low || (rq)->count == 0)
(rq)->low = whichq; /* minimize */
diff --git a/kern/eventcount.h b/kern/eventcount.h
index 6872a347..7cc82207 100644
--- a/kern/eventcount.h
+++ b/kern/eventcount.h
@@ -53,7 +53,12 @@ extern void evc_init(evc_t ev),
/* kernel and user visible */
extern kern_return_t evc_wait(natural_t ev_id);
+extern kern_return_t evc_wait_clear(natural_t ev_id);
-extern void evc_notify_abort (thread_t thread);
+#if NCPUS <= 1
+void simpler_thread_setrun(
+ thread_t th,
+ boolean_t may_preempt);
+#endif
#endif /* _KERN_EVENTCOUNT_H_ */
diff --git a/kern/exception.c b/kern/exception.c
index 453a0758..6cb3bfbf 100644
--- a/kern/exception.c
+++ b/kern/exception.c
@@ -47,23 +47,13 @@
#include <kern/processor.h>
#include <kern/sched.h>
#include <kern/sched_prim.h>
+#include <kern/exception.h>
+#include <kern/macros.h>
#include <mach/machine/vm_types.h>
-
-
-extern void exception() __attribute__ ((noreturn));
-extern void exception_try_task() __attribute__ ((noreturn));
-extern void exception_no_server() __attribute__ ((noreturn));
-
-extern void exception_raise() __attribute__ ((noreturn));
-extern kern_return_t exception_parse_reply();
-extern void exception_raise_continue() __attribute__ ((noreturn));
-extern void exception_raise_continue_slow() __attribute__ ((noreturn));
-extern void exception_raise_continue_fast() __attribute__ ((noreturn));
-
#if MACH_KDB
-extern void thread_kdb_return();
-extern void db_printf();
+#include <machine/trap.h>
+#include <ddb/db_output.h>
boolean_t debug_user_with_kdb = FALSE;
#endif /* MACH_KDB */
@@ -93,11 +83,13 @@ boolean_t debug_user_with_kdb = FALSE;
*/
void
-exception(_exception, code, subcode)
- integer_t _exception, code, subcode;
+exception(
+ integer_t _exception,
+ integer_t code,
+ integer_t subcode)
{
- register ipc_thread_t self = current_thread();
- register ipc_port_t exc_port;
+ ipc_thread_t self = current_thread();
+ ipc_port_t exc_port;
if (_exception == KERN_SUCCESS)
panic("exception");
@@ -163,12 +155,14 @@ exception(_exception, code, subcode)
*/
void
-exception_try_task(_exception, code, subcode)
- integer_t _exception, code, subcode;
+exception_try_task(
+ integer_t _exception,
+ integer_t code,
+ integer_t subcode)
{
ipc_thread_t self = current_thread();
- register task_t task = self->task;
- register ipc_port_t exc_port;
+ task_t task = self->task;
+ ipc_port_t exc_port;
/*
* Optimized version of retrieve_task_exception.
@@ -228,9 +222,9 @@ exception_try_task(_exception, code, subcode)
*/
void
-exception_no_server()
+exception_no_server(void)
{
- register ipc_thread_t self = current_thread();
+ ipc_thread_t self = current_thread();
/*
* If this thread is being terminated, cooperate.
@@ -330,12 +324,13 @@ mach_msg_type_t exc_code_proto = {
int exception_raise_misses = 0;
void
-exception_raise(dest_port, thread_port, task_port,
- _exception, code, subcode)
- ipc_port_t dest_port;
- ipc_port_t thread_port;
- ipc_port_t task_port;
- integer_t _exception, code, subcode;
+exception_raise(
+ ipc_port_t dest_port,
+ ipc_port_t thread_port,
+ ipc_port_t task_port,
+ integer_t _exception,
+ integer_t code,
+ integer_t subcode)
{
ipc_thread_t self = current_thread();
ipc_thread_t receiver;
@@ -428,7 +423,7 @@ exception_raise(dest_port, thread_port, task_port,
*/
{
- register ipc_pset_t dest_pset;
+ ipc_pset_t dest_pset;
dest_pset = dest_port->ip_pset;
if (dest_pset == IPS_NULL)
@@ -490,7 +485,7 @@ exception_raise(dest_port, thread_port, task_port,
* Release the receiver's reference for his object.
*/
{
- register ipc_object_t object = receiver->ith_object;
+ ipc_object_t object = receiver->ith_object;
io_lock(object);
io_release(object);
@@ -498,7 +493,7 @@ exception_raise(dest_port, thread_port, task_port,
}
{
- register struct mach_exception *exc =
+ struct mach_exception *exc =
(struct mach_exception *) &kmsg->ikm_header;
ipc_space_t space = receiver->task->itk_space;
@@ -609,30 +604,18 @@ exception_raise(dest_port, thread_port, task_port,
ip_unlock(reply_port);
{
- register ipc_entry_t table;
- register ipc_entry_t entry;
- register mach_port_index_t index;
-
- /* optimized ipc_entry_get */
-
- table = space->is_table;
- index = table->ie_next;
+ kern_return_t kr;
+ ipc_entry_t entry;
- if (index == 0)
+ kr = ipc_entry_get (space, &exc->Head.msgh_remote_port, &entry);
+ if (kr)
goto abort_copyout;
-
- entry = &table[index];
- table->ie_next = entry->ie_next;
- entry->ie_request = 0;
-
{
- register mach_port_gen_t gen;
+ mach_port_gen_t gen;
assert((entry->ie_bits &~ IE_BITS_GEN_MASK) == 0);
gen = entry->ie_bits + IE_BITS_GEN_ONE;
- exc->Head.msgh_remote_port = MACH_PORT_MAKE(index, gen);
-
/* optimized ipc_right_copyout */
entry->ie_bits = gen | (MACH_PORT_TYPE_SEND_ONCE | 1);
@@ -710,7 +693,7 @@ exception_raise(dest_port, thread_port, task_port,
#endif
slow_exception_raise: {
- register struct mach_exception *exc =
+ struct mach_exception *exc =
(struct mach_exception *) &kmsg->ikm_header;
ipc_kmsg_t reply_kmsg;
mach_port_seqno_t reply_seqno;
@@ -772,6 +755,12 @@ exception_raise(dest_port, thread_port, task_port,
}
}
+/* Macro used by MIG to cleanly check the type. */
+#define BAD_TYPECHECK(type, check) unlikely (({\
+ union { mach_msg_type_t t; unsigned32_t w; } _t, _c;\
+ _t.t = *(type); _c.t = *(check);_t.w != _c.w; }))
+
+/* Type descriptor for the return code. */
mach_msg_type_t exc_RetCode_proto = {
/* msgt_name = */ MACH_MSG_TYPE_INTEGER_32,
/* msgt_size = */ 32,
@@ -794,10 +783,9 @@ mach_msg_type_t exc_RetCode_proto = {
*/
kern_return_t
-exception_parse_reply(kmsg)
- ipc_kmsg_t kmsg;
+exception_parse_reply(ipc_kmsg_t kmsg)
{
- register mig_reply_header_t *msg =
+ mig_reply_header_t *msg =
(mig_reply_header_t *) &kmsg->ikm_header;
kern_return_t kr;
@@ -805,7 +793,7 @@ exception_parse_reply(kmsg)
MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND_ONCE, 0)) ||
(msg->Head.msgh_size != sizeof *msg) ||
(msg->Head.msgh_id != MACH_EXCEPTION_REPLY_ID) ||
- (* (int *) &msg->RetCodeType != * (int *) &exc_RetCode_proto)) {
+ (BAD_TYPECHECK(&msg->RetCodeType, &exc_RetCode_proto))) {
/*
* Bozo user sent us a misformatted reply.
*/
@@ -839,7 +827,7 @@ exception_parse_reply(kmsg)
*/
void
-exception_raise_continue()
+exception_raise_continue(void)
{
ipc_thread_t self = current_thread();
ipc_port_t reply_port = self->ith_port;
@@ -871,10 +859,10 @@ exception_raise_continue()
*/
void
-exception_raise_continue_slow(mr, kmsg, seqno)
- mach_msg_return_t mr;
- ipc_kmsg_t kmsg;
- mach_port_seqno_t seqno;
+exception_raise_continue_slow(
+ mach_msg_return_t mr,
+ ipc_kmsg_t kmsg,
+ mach_port_seqno_t seqno)
{
ipc_thread_t self = current_thread();
ipc_port_t reply_port = self->ith_port;
@@ -954,9 +942,9 @@ exception_raise_continue_slow(mr, kmsg, seqno)
*/
void
-exception_raise_continue_fast(reply_port, kmsg)
- ipc_port_t reply_port;
- ipc_kmsg_t kmsg;
+exception_raise_continue_fast(
+ ipc_port_t reply_port,
+ ipc_kmsg_t kmsg)
{
ipc_thread_t self = current_thread();
kern_return_t kr;
diff --git a/kern/exception.h b/kern/exception.h
new file mode 100644
index 00000000..55902dd1
--- /dev/null
+++ b/kern/exception.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _KERN_EXCEPTION_H_
+#define _KERN_EXCEPTION_H_
+
+#include <ipc/ipc_types.h>
+#include <ipc/ipc_kmsg.h>
+
+extern void
+exception(
+ integer_t _exception,
+ integer_t code,
+ integer_t subcode) __attribute__ ((noreturn));
+
+extern void
+exception_try_task(
+ integer_t _exception,
+ integer_t code,
+ integer_t subcode) __attribute__ ((noreturn));
+
+extern void
+exception_no_server(void) __attribute__ ((noreturn));
+
+extern void
+exception_raise(
+ ipc_port_t dest_port,
+ ipc_port_t thread_port,
+ ipc_port_t task_port,
+ integer_t _exception,
+ integer_t code,
+ integer_t subcode) __attribute__ ((noreturn));
+
+extern kern_return_t
+exception_parse_reply(ipc_kmsg_t kmsg);
+
+extern void
+exception_raise_continue(void) __attribute__ ((noreturn));
+
+extern void
+exception_raise_continue_slow(
+ mach_msg_return_t mr,
+ ipc_kmsg_t kmsg,
+ mach_port_seqno_t seqno) __attribute__ ((noreturn));
+
+extern void
+exception_raise_continue_fast(
+ ipc_port_t reply_port,
+ ipc_kmsg_t kmsg) __attribute__ ((noreturn));
+
+#endif /* _KERN_EXCEPTION_H_ */
diff --git a/kern/host.c b/kern/host.c
index 57a40b43..2855cd2d 100644
--- a/kern/host.c
+++ b/kern/host.c
@@ -47,12 +47,12 @@
host_data_t realhost;
kern_return_t host_processors(
- host_t host,
+ const host_t host,
processor_array_t *processor_list,
natural_t *countp)
{
- register int i;
- register processor_t *tp;
+ int i;
+ processor_t *tp;
vm_offset_t addr;
unsigned int count;
@@ -95,12 +95,12 @@ kern_return_t host_processors(
}
kern_return_t host_info(
- host_t host,
+ const host_t host,
int flavor,
host_info_t info,
natural_t *count)
{
- register integer_t i, *slot_ptr;
+ integer_t i, *slot_ptr;
if (host == HOST_NULL)
return KERN_INVALID_ARGUMENT;
@@ -109,7 +109,7 @@ kern_return_t host_info(
case HOST_BASIC_INFO:
{
- register host_basic_info_t basic_info;
+ host_basic_info_t basic_info;
/*
* Basic information about this host.
@@ -152,7 +152,7 @@ kern_return_t host_info(
case HOST_SCHED_INFO:
{
- register host_sched_info_t sched_info;
+ host_sched_info_t sched_info;
extern int min_quantum;
/* minimum quantum, in microseconds */
@@ -174,7 +174,7 @@ kern_return_t host_info(
case HOST_LOAD_INFO:
{
- register host_load_info_t load_info;
+ host_load_info_t load_info;
extern long avenrun[3], mach_factor[3];
if (*count < HOST_LOAD_INFO_COUNT)
@@ -204,7 +204,7 @@ kern_return_t host_info(
*/
kern_return_t host_kernel_version(
- host_t host,
+ const host_t host,
kernel_version_t out_version)
{
extern char version[];
@@ -225,7 +225,7 @@ kern_return_t host_kernel_version(
#if MACH_HOST
kern_return_t
host_processor_sets(
- host_t host,
+ const host_t host,
processor_set_name_array_t *pset_list,
natural_t *count)
{
@@ -302,7 +302,7 @@ host_processor_sets(
return KERN_RESOURCE_SHORTAGE;
}
- memcpy((char *) newaddr, (char *) addr, size_needed);
+ memcpy((void *) newaddr, (void *) addr, size_needed);
kfree(addr, size);
psets = (processor_set_t *) newaddr;
}
@@ -324,7 +324,7 @@ host_processor_sets(
*/
kern_return_t
host_processor_sets(
- host_t host,
+ const host_t host,
processor_set_name_array_t *pset_list,
natural_t *count)
{
@@ -362,7 +362,7 @@ host_processor_sets(
*/
kern_return_t
host_processor_set_priv(
- host_t host,
+ const host_t host,
processor_set_t pset_name,
processor_set_t *pset)
{
diff --git a/kern/ipc_host.c b/kern/ipc_host.c
index cd1c11ab..a02eb6f6 100644
--- a/kern/ipc_host.c
+++ b/kern/ipc_host.c
@@ -205,7 +205,7 @@ ipc_pset_terminate(
*/
kern_return_t
processor_set_default(
- host_t host,
+ const host_t host,
processor_set_t *pset)
{
if (host == HOST_NULL)
diff --git a/kern/ipc_kobject.c b/kern/ipc_kobject.c
index 37d4eb99..709ec9ec 100644
--- a/kern/ipc_kobject.c
+++ b/kern/ipc_kobject.c
@@ -49,8 +49,21 @@
#include <vm/memory_object_proxy.h>
#include <device/ds_routines.h>
+#include <kern/mach.server.h>
+#include <ipc/mach_port.server.h>
+#include <kern/mach_host.server.h>
+#include <device/device.server.h>
+#include <device/device_pager.server.h>
+#include <kern/mach4.server.h>
+#include <kern/gnumach.server.h>
+
+#if MACH_DEBUG
+#include <kern/mach_debug.server.h>
+#endif
+
#if MACH_MACHINE_ROUTINES
#include <machine/machine_routines.h>
+#include MACHINE_SERVER_HEADER
#endif
@@ -146,21 +159,6 @@ ipc_kobject_server(request)
* to perform the kernel function
*/
{
- extern mig_routine_t mach_server_routine(),
- mach_port_server_routine(),
- mach_host_server_routine(),
- device_server_routine(),
- device_pager_server_routine(),
- mach4_server_routine(),
- gnumach_server_routine();
-#if MACH_DEBUG
- extern mig_routine_t mach_debug_server_routine();
-#endif
-
-#if MACH_MACHINE_ROUTINES
- extern mig_routine_t MACHINE_SERVER_ROUTINE();
-#endif
-
check_simple_locks();
if ((routine = mach_server_routine(&request->ikm_header)) != 0
|| (routine = mach_port_server_routine(&request->ikm_header)) != 0
@@ -246,7 +244,7 @@ ipc_kobject_server(request)
} else {
/*
* The message contents of the request are intact.
- * Destroy everthing except the reply port right,
+ * Destroy everything except the reply port right,
* which is needed in the reply message.
*/
diff --git a/kern/ipc_kobject.h b/kern/ipc_kobject.h
index cb795741..606a66a9 100644
--- a/kern/ipc_kobject.h
+++ b/kern/ipc_kobject.h
@@ -36,13 +36,12 @@
* Declarations for letting a port represent a kernel object.
*/
-#include <ipc/ipc_kmsg.h>
-#include <ipc/ipc_types.h>
-
#ifndef _KERN_IPC_KOBJECT_H_
#define _KERN_IPC_KOBJECT_H_
#include <mach/machine/vm_types.h>
+#include <ipc/ipc_types.h>
+#include <ipc/ipc_kmsg.h>
typedef vm_offset_t ipc_kobject_t;
diff --git a/kern/ipc_mig.c b/kern/ipc_mig.c
index 3f55da7c..22dac420 100644
--- a/kern/ipc_mig.c
+++ b/kern/ipc_mig.c
@@ -37,6 +37,7 @@
#include <kern/task.h>
#include <kern/ipc_kobject.h>
#include <kern/ipc_tt.h>
+#include <kern/ipc_mig.h>
#include <vm/vm_map.h>
#include <vm/vm_user.h>
#include <ipc/port.h>
@@ -91,7 +92,7 @@ mach_msg_send_from_kernel(
mach_msg_return_t
mach_msg_rpc_from_kernel(msg, send_size, reply_size)
- mach_msg_header_t *msg;
+ const mach_msg_header_t *msg;
mach_msg_size_t send_size;
mach_msg_size_t reply_size;
{
@@ -109,8 +110,7 @@ mach_msg_rpc_from_kernel(msg, send_size, reply_size)
*/
void
-mach_msg_abort_rpc(thread)
- ipc_thread_t thread;
+mach_msg_abort_rpc(ipc_thread_t thread)
{
ipc_port_t reply = IP_NULL;
@@ -140,14 +140,14 @@ mach_msg_abort_rpc(thread)
*/
mach_msg_return_t
-mach_msg(msg, option, send_size, rcv_size, rcv_name, time_out, notify)
- mach_msg_header_t *msg;
- mach_msg_option_t option;
- mach_msg_size_t send_size;
- mach_msg_size_t rcv_size;
- mach_port_t rcv_name;
- mach_msg_timeout_t time_out;
- mach_port_t notify;
+mach_msg(
+ mach_msg_header_t *msg,
+ mach_msg_option_t option,
+ mach_msg_size_t send_size,
+ mach_msg_size_t rcv_size,
+ mach_port_t rcv_name,
+ mach_msg_timeout_t time_out,
+ mach_port_t notify)
{
ipc_space_t space = current_space();
vm_map_t map = current_map();
@@ -271,10 +271,10 @@ mig_put_reply_port(
/*
* mig_strncpy.c - by Joshua Block
*
- * mig_strncp -- Bounded string copy. Does what the library routine strncpy
- * OUGHT to do: Copies the (null terminated) string in src into dest, a
- * buffer of length len. Assures that the copy is still null terminated
- * and doesn't overflow the buffer, truncating the copy if necessary.
+ * mig_strncpy -- Bounded string copy. Does what the library routine
+ * strncpy does: Copies the (null terminated) string in src into dest,
+ * a buffer of length len. Returns the length of the destination
+ * string excluding the terminating null.
*
* Parameters:
*
@@ -284,37 +284,44 @@ mig_put_reply_port(
*
* len - Length of destination buffer.
*/
-void mig_strncpy(dest, src, len)
-char *dest, *src;
-int len;
+vm_size_t
+mig_strncpy(dest, src, len)
+ char *dest;
+ const char *src;
+ int len;
{
- int i;
+ char *dest_ = dest;
+ int i;
- if (len <= 0)
- return;
+ if (len <= 0)
+ return 0;
- for (i=1; i<len; i++)
- if (! (*dest++ = *src++))
- return;
+ for (i = 0; i < len; i++) {
+ if (! (*dest = *src))
+ break;
+ dest++;
+ src++;
+ }
- *dest = '\0';
- return;
+ return dest - dest_;
}
#define fast_send_right_lookup(name, port, abort) \
MACRO_BEGIN \
- register ipc_space_t space = current_space(); \
- register ipc_entry_t entry; \
- register mach_port_index_t index = MACH_PORT_INDEX(name); \
+ ipc_space_t space = current_space(); \
+ ipc_entry_t entry; \
\
is_read_lock(space); \
assert(space->is_active); \
\
- if ((index >= space->is_table_size) || \
- (((entry = &space->is_table[index])->ie_bits & \
- (IE_BITS_GEN_MASK|MACH_PORT_TYPE_SEND)) != \
- (MACH_PORT_GEN(name) | MACH_PORT_TYPE_SEND))) { \
- is_read_unlock(space); \
+ entry = ipc_entry_lookup (space, name); \
+ if (entry == IE_NULL) { \
+ is_read_unlock (space); \
+ abort; \
+ } \
+ \
+ if (IE_BITS_TYPE (entry->ie_bits) != MACH_PORT_TYPE_SEND) { \
+ is_read_unlock (space); \
abort; \
} \
\
@@ -327,11 +334,10 @@ MACRO_BEGIN \
MACRO_END
device_t
-port_name_to_device(name)
- mach_port_t name;
+port_name_to_device(mach_port_t name)
{
- register ipc_port_t port;
- register device_t device;
+ ipc_port_t port;
+ device_t device;
fast_send_right_lookup(name, port, goto abort);
/* port is locked */
@@ -371,17 +377,16 @@ port_name_to_device(name)
}
thread_t
-port_name_to_thread(name)
- mach_port_t name;
+port_name_to_thread(mach_port_t name)
{
- register ipc_port_t port;
+ ipc_port_t port;
fast_send_right_lookup(name, port, goto abort);
/* port is locked */
if (ip_active(port) &&
(ip_kotype(port) == IKOT_THREAD)) {
- register thread_t thread;
+ thread_t thread;
thread = (thread_t) port->ip_kobject;
assert(thread != THREAD_NULL);
@@ -417,17 +422,16 @@ port_name_to_thread(name)
}
task_t
-port_name_to_task(name)
- mach_port_t name;
+port_name_to_task(mach_port_t name)
{
- register ipc_port_t port;
+ ipc_port_t port;
fast_send_right_lookup(name, port, goto abort);
/* port is locked */
if (ip_active(port) &&
(ip_kotype(port) == IKOT_TASK)) {
- register task_t task;
+ task_t task;
task = (task_t) port->ip_kobject;
assert(task != TASK_NULL);
@@ -468,14 +472,14 @@ vm_map_t
port_name_to_map(
mach_port_t name)
{
- register ipc_port_t port;
+ ipc_port_t port;
fast_send_right_lookup(name, port, goto abort);
/* port is locked */
if (ip_active(port) &&
(ip_kotype(port) == IKOT_TASK)) {
- register vm_map_t map;
+ vm_map_t map;
map = ((task_t) port->ip_kobject)->map;
assert(map != VM_MAP_NULL);
@@ -513,17 +517,16 @@ port_name_to_map(
}
ipc_space_t
-port_name_to_space(name)
- mach_port_t name;
+port_name_to_space(mach_port_t name)
{
- register ipc_port_t port;
+ ipc_port_t port;
fast_send_right_lookup(name, port, goto abort);
/* port is locked */
if (ip_active(port) &&
(ip_kotype(port) == IKOT_TASK)) {
- register ipc_space_t space;
+ ipc_space_t space;
space = ((task_t) port->ip_kobject)->itk_space;
assert(space != IS_NULL);
@@ -569,12 +572,11 @@ port_name_to_space(name)
* AARGH!
*/
-kern_return_t thread_get_state_KERNEL(thread_port, flavor,
- old_state, old_state_count)
- mach_port_t thread_port; /* port right for thread */
- int flavor;
- thread_state_t old_state; /* pointer to OUT array */
- natural_t *old_state_count; /* IN/OUT */
+kern_return_t thread_get_state_KERNEL(
+ mach_port_t thread_port, /* port right for thread */
+ int flavor,
+ thread_state_t old_state, /* pointer to OUT array */
+ natural_t *old_state_count) /* IN/OUT */
{
thread_t thread;
kern_return_t result;
@@ -586,12 +588,11 @@ kern_return_t thread_get_state_KERNEL(thread_port, flavor,
return result;
}
-kern_return_t thread_set_state_KERNEL(thread_port, flavor,
- new_state, new_state_count)
- mach_port_t thread_port; /* port right for thread */
- int flavor;
- thread_state_t new_state;
- natural_t new_state_count;
+kern_return_t thread_set_state_KERNEL(
+ mach_port_t thread_port, /* port right for thread */
+ int flavor,
+ thread_state_t new_state,
+ natural_t new_state_count)
{
thread_t thread;
kern_return_t result;
@@ -613,7 +614,7 @@ kern_return_t thread_set_state_KERNEL(thread_port, flavor,
* knows to fall back on an RPC. For other return values, it won't
* retry with an RPC. The retry might get a different (incorrect) rc.
* Return values are only set (and should only be set, with copyout)
- * on successfull calls.
+ * on successful calls.
*/
kern_return_t
@@ -650,12 +651,12 @@ syscall_vm_map(
} else
port = (ipc_port_t) memory_object;
- copyin((char *)address, (char *)&addr, sizeof(vm_offset_t));
+ copyin(address, &addr, sizeof(vm_offset_t));
result = vm_map(map, &addr, size, mask, anywhere,
port, offset, copy,
cur_protection, max_protection, inheritance);
if (result == KERN_SUCCESS)
- copyout((char *)&addr, (char *)address, sizeof(vm_offset_t));
+ copyout(&addr, address, sizeof(vm_offset_t));
if (IP_VALID(port))
ipc_port_release_send(port);
vm_map_deallocate(map);
@@ -663,11 +664,11 @@ syscall_vm_map(
return result;
}
-kern_return_t syscall_vm_allocate(target_map, address, size, anywhere)
- mach_port_t target_map;
- vm_offset_t *address;
- vm_size_t size;
- boolean_t anywhere;
+kern_return_t syscall_vm_allocate(
+ mach_port_t target_map,
+ vm_offset_t *address,
+ vm_size_t size,
+ boolean_t anywhere)
{
vm_map_t map;
vm_offset_t addr;
@@ -677,19 +678,19 @@ kern_return_t syscall_vm_allocate(target_map, address, size, anywhere)
if (map == VM_MAP_NULL)
return MACH_SEND_INTERRUPTED;
- copyin((char *)address, (char *)&addr, sizeof(vm_offset_t));
+ copyin(address, &addr, sizeof(vm_offset_t));
result = vm_allocate(map, &addr, size, anywhere);
if (result == KERN_SUCCESS)
- copyout((char *)&addr, (char *)address, sizeof(vm_offset_t));
+ copyout(&addr, address, sizeof(vm_offset_t));
vm_map_deallocate(map);
return result;
}
-kern_return_t syscall_vm_deallocate(target_map, start, size)
- mach_port_t target_map;
- vm_offset_t start;
- vm_size_t size;
+kern_return_t syscall_vm_deallocate(
+ mach_port_t target_map,
+ vm_offset_t start,
+ vm_size_t size)
{
vm_map_t map;
kern_return_t result;
@@ -704,10 +705,10 @@ kern_return_t syscall_vm_deallocate(target_map, start, size)
return result;
}
-kern_return_t syscall_task_create(parent_task, inherit_memory, child_task)
- mach_port_t parent_task;
- boolean_t inherit_memory;
- mach_port_t *child_task; /* OUT */
+kern_return_t syscall_task_create(
+ mach_port_t parent_task,
+ boolean_t inherit_memory,
+ mach_port_t *child_task) /* OUT */
{
task_t t, c;
ipc_port_t port;
@@ -725,7 +726,7 @@ kern_return_t syscall_task_create(parent_task, inherit_memory, child_task)
(void) ipc_kmsg_copyout_object(current_space(),
(ipc_object_t) port,
MACH_MSG_TYPE_PORT_SEND, &name);
- copyout((char *)&name, (char *)child_task,
+ copyout(&name, child_task,
sizeof(mach_port_t));
}
task_deallocate(t);
@@ -733,8 +734,7 @@ kern_return_t syscall_task_create(parent_task, inherit_memory, child_task)
return result;
}
-kern_return_t syscall_task_terminate(task)
- mach_port_t task;
+kern_return_t syscall_task_terminate(mach_port_t task)
{
task_t t;
kern_return_t result;
@@ -749,8 +749,7 @@ kern_return_t syscall_task_terminate(task)
return result;
}
-kern_return_t syscall_task_suspend(task)
- mach_port_t task;
+kern_return_t syscall_task_suspend(mach_port_t task)
{
task_t t;
kern_return_t result;
@@ -765,10 +764,10 @@ kern_return_t syscall_task_suspend(task)
return result;
}
-kern_return_t syscall_task_set_special_port(task, which_port, port_name)
- mach_port_t task;
- int which_port;
- mach_port_t port_name;
+kern_return_t syscall_task_set_special_port(
+ mach_port_t task,
+ int which_port,
+ mach_port_t port_name)
{
task_t t;
ipc_port_t port;
@@ -798,10 +797,10 @@ kern_return_t syscall_task_set_special_port(task, which_port, port_name)
}
kern_return_t
-syscall_mach_port_allocate(task, right, namep)
- mach_port_t task;
- mach_port_right_t right;
- mach_port_t *namep;
+syscall_mach_port_allocate(
+ mach_port_t task,
+ mach_port_right_t right,
+ mach_port_t *namep)
{
ipc_space_t space;
mach_port_t name;
@@ -813,17 +812,17 @@ syscall_mach_port_allocate(task, right, namep)
kr = mach_port_allocate(space, right, &name);
if (kr == KERN_SUCCESS)
- copyout((char *)&name, (char *)namep, sizeof(mach_port_t));
+ copyout(&name, namep, sizeof(mach_port_t));
is_release(space);
return kr;
}
kern_return_t
-syscall_mach_port_allocate_name(task, right, name)
- mach_port_t task;
- mach_port_right_t right;
- mach_port_t name;
+syscall_mach_port_allocate_name(
+ mach_port_t task,
+ mach_port_right_t right,
+ mach_port_t name)
{
ipc_space_t space;
kern_return_t kr;
@@ -839,9 +838,9 @@ syscall_mach_port_allocate_name(task, right, name)
}
kern_return_t
-syscall_mach_port_deallocate(task, name)
- mach_port_t task;
- mach_port_t name;
+syscall_mach_port_deallocate(
+ mach_port_t task,
+ mach_port_t name)
{
ipc_space_t space;
kern_return_t kr;
@@ -857,11 +856,11 @@ syscall_mach_port_deallocate(task, name)
}
kern_return_t
-syscall_mach_port_insert_right(task, name, right, rightType)
- mach_port_t task;
- mach_port_t name;
- mach_port_t right;
- mach_msg_type_name_t rightType;
+syscall_mach_port_insert_right(
+ mach_port_t task,
+ mach_port_t name,
+ mach_port_t right,
+ mach_msg_type_name_t rightType)
{
ipc_space_t space;
ipc_object_t object;
@@ -896,8 +895,7 @@ syscall_mach_port_insert_right(task, name, right, rightType)
return kr;
}
-kern_return_t syscall_thread_depress_abort(thread)
- mach_port_t thread;
+kern_return_t syscall_thread_depress_abort(mach_port_t thread)
{
thread_t t;
kern_return_t result;
@@ -915,10 +913,6 @@ kern_return_t syscall_thread_depress_abort(thread)
/*
* Device traps -- these are way experimental.
*/
-
-extern io_return_t ds_device_write_trap();
-extern io_return_t ds_device_writev_trap();
-
io_return_t
syscall_device_write_request(mach_port_t device_name,
mach_port_t reply_name,
@@ -928,7 +922,7 @@ syscall_device_write_request(mach_port_t device_name,
vm_size_t data_count)
{
device_t dev;
- ipc_port_t reply_port;
+ /*ipc_port_t reply_port;*/
io_return_t res;
/*
@@ -949,9 +943,10 @@ syscall_device_write_request(mach_port_t device_name,
/*
* Translate reply port.
*/
- if (reply_name == MACH_PORT_NULL)
+ /*if (reply_name == MACH_PORT_NULL)
reply_port = IP_NULL;
- else {
+ */
+ if (reply_name != MACH_PORT_NULL) {
/* Homey don't play that. */
device_deallocate(dev);
return KERN_INVALID_RIGHT;
@@ -978,7 +973,7 @@ syscall_device_writev_request(mach_port_t device_name,
vm_size_t iocount)
{
device_t dev;
- ipc_port_t reply_port;
+ /*ipc_port_t reply_port;*/
io_return_t res;
/*
@@ -999,9 +994,10 @@ syscall_device_writev_request(mach_port_t device_name,
/*
* Translate reply port.
*/
- if (reply_name == MACH_PORT_NULL)
+ /*if (reply_name == MACH_PORT_NULL)
reply_port = IP_NULL;
- else {
+ */
+ if (reply_name != MACH_PORT_NULL) {
/* Homey don't play that. */
device_deallocate(dev);
return KERN_INVALID_RIGHT;
diff --git a/kern/ipc_mig.h b/kern/ipc_mig.h
index f352bdc6..6f063eca 100644
--- a/kern/ipc_mig.h
+++ b/kern/ipc_mig.h
@@ -27,6 +27,7 @@
#define _IPC_MIG_H_
#include <mach/std_types.h>
+#include <device/device_types.h>
/*
* Routine: mach_msg_send_from_kernel
@@ -58,8 +59,84 @@ extern mach_msg_return_t mach_msg_send_from_kernel(
extern void mach_msg_abort_rpc (ipc_thread_t);
extern mach_msg_return_t mach_msg_rpc_from_kernel(
- mach_msg_header_t *msg,
+ const mach_msg_header_t *msg,
mach_msg_size_t send_size,
mach_msg_size_t reply_size);
+extern kern_return_t syscall_vm_map(
+ mach_port_t target_map,
+ vm_offset_t *address,
+ vm_size_t size,
+ vm_offset_t mask,
+ boolean_t anywhere,
+ mach_port_t memory_object,
+ vm_offset_t offset,
+ boolean_t copy,
+ vm_prot_t cur_protection,
+ vm_prot_t max_protection,
+ vm_inherit_t inheritance);
+
+extern kern_return_t syscall_vm_allocate(
+ mach_port_t target_map,
+ vm_offset_t *address,
+ vm_size_t size,
+ boolean_t anywhere);
+
+extern kern_return_t syscall_vm_deallocate(
+ mach_port_t target_map,
+ vm_offset_t start,
+ vm_size_t size);
+
+extern kern_return_t syscall_task_create(
+ mach_port_t parent_task,
+ boolean_t inherit_memory,
+ mach_port_t *child_task);
+
+extern kern_return_t syscall_task_terminate(mach_port_t task);
+
+extern kern_return_t syscall_task_suspend(mach_port_t task);
+
+extern kern_return_t syscall_task_set_special_port(
+ mach_port_t task,
+ int which_port,
+ mach_port_t port_name);
+
+extern kern_return_t syscall_mach_port_allocate(
+ mach_port_t task,
+ mach_port_right_t right,
+ mach_port_t *namep);
+
+extern kern_return_t syscall_mach_port_deallocate(
+ mach_port_t task,
+ mach_port_t name);
+
+extern kern_return_t syscall_mach_port_insert_right(
+ mach_port_t task,
+ mach_port_t name,
+ mach_port_t right,
+ mach_msg_type_name_t rightType);
+
+extern kern_return_t syscall_mach_port_allocate_name(
+ mach_port_t task,
+ mach_port_right_t right,
+ mach_port_t name);
+
+extern kern_return_t syscall_thread_depress_abort(mach_port_t thread);
+
+extern io_return_t syscall_device_write_request(
+ mach_port_t device_name,
+ mach_port_t reply_name,
+ dev_mode_t mode,
+ recnum_t recnum,
+ vm_offset_t data,
+ vm_size_t data_count);
+
+io_return_t syscall_device_writev_request(
+ mach_port_t device_name,
+ mach_port_t reply_name,
+ dev_mode_t mode,
+ recnum_t recnum,
+ io_buf_vec_t *iovec,
+ vm_size_t iocount);
+
#endif /* _IPC_MIG_H_ */
diff --git a/kern/ipc_sched.c b/kern/ipc_sched.c
index 615ad608..be82971b 100644
--- a/kern/ipc_sched.c
+++ b/kern/ipc_sched.c
@@ -182,9 +182,9 @@ thread_will_wait_with_timeout(
boolean_t
thread_handoff(
- register thread_t old,
- register continuation_t continuation,
- register thread_t new)
+ thread_t old,
+ continuation_t continuation,
+ thread_t new)
{
spl_t s;
@@ -214,7 +214,7 @@ thread_handoff(
thread_unlock(new);
(void) splx(s);
- counter_always(c_thread_handoff_misses++);
+ counter(c_thread_handoff_misses++);
return FALSE;
}
@@ -268,7 +268,7 @@ thread_handoff(
*/
old->wake_active = FALSE;
thread_unlock(old);
- thread_wakeup((event_t)&old->wake_active);
+ thread_wakeup(TH_EV_WAKE_ACTIVE(old));
goto after_old_thread;
}
} else
@@ -278,6 +278,6 @@ thread_handoff(
after_old_thread:
(void) splx(s);
- counter_always(c_thread_handoff_hits++);
+ counter(c_thread_handoff_hits++);
return TRUE;
}
diff --git a/kern/ipc_tt.c b/kern/ipc_tt.c
index 6d32e5b0..e4d657b7 100644
--- a/kern/ipc_tt.c
+++ b/kern/ipc_tt.c
@@ -72,7 +72,7 @@ ipc_task_init(
int i;
- kr = ipc_space_create(&ipc_table_entries[0], &space);
+ kr = ipc_space_create(&space);
if (kr != KERN_SUCCESS)
panic("ipc_task_init");
@@ -213,8 +213,7 @@ ipc_task_terminate(
*/
void
-ipc_thread_init(thread)
- thread_t thread;
+ipc_thread_init(thread_t thread)
{
ipc_port_t kport;
@@ -243,8 +242,7 @@ ipc_thread_init(thread)
*/
void
-ipc_thread_enable(thread)
- thread_t thread;
+ipc_thread_enable(thread_t thread)
{
ipc_port_t kport;
@@ -264,8 +262,7 @@ ipc_thread_enable(thread)
*/
void
-ipc_thread_disable(thread)
- thread_t thread;
+ipc_thread_disable(thread_t thread)
{
ipc_port_t kport;
@@ -286,8 +283,7 @@ ipc_thread_disable(thread)
*/
void
-ipc_thread_terminate(thread)
- thread_t thread;
+ipc_thread_terminate(thread_t thread)
{
ipc_port_t kport;
@@ -387,9 +383,9 @@ retrieve_thread_self(thread)
ipc_port_t
retrieve_task_self_fast(
- register task_t task)
+ task_t task)
{
- register ipc_port_t port;
+ ipc_port_t port;
assert(task == current_task());
@@ -424,10 +420,9 @@ retrieve_task_self_fast(
*/
ipc_port_t
-retrieve_thread_self_fast(thread)
- register thread_t thread;
+retrieve_thread_self_fast(thread_t thread)
{
- register ipc_port_t port;
+ ipc_port_t port;
assert(thread == current_thread());
@@ -648,9 +643,9 @@ task_get_special_port(
kern_return_t
task_set_special_port(
- task_t task,
- int which,
- ipc_port_t port)
+ task_t task,
+ int which,
+ const ipc_port_t port)
{
ipc_port_t *whichp;
ipc_port_t old;
@@ -705,10 +700,10 @@ task_set_special_port(
*/
kern_return_t
-thread_get_special_port(thread, which, portp)
- thread_t thread;
- int which;
- ipc_port_t *portp;
+thread_get_special_port(
+ thread_t thread,
+ int which,
+ ipc_port_t *portp)
{
ipc_port_t *whichp;
ipc_port_t port;
@@ -758,10 +753,10 @@ thread_get_special_port(thread, which, portp)
*/
kern_return_t
-thread_set_special_port(thread, which, port)
- thread_t thread;
- int which;
- ipc_port_t port;
+thread_set_special_port(
+ thread_t thread,
+ int which,
+ ipc_port_t port)
{
ipc_port_t *whichp;
ipc_port_t old;
@@ -890,10 +885,10 @@ mach_ports_register(
*/
kern_return_t
-mach_ports_lookup(task, portsp, portsCnt)
- task_t task;
- ipc_port_t **portsp;
- mach_msg_type_number_t *portsCnt;
+mach_ports_lookup(
+ task_t task,
+ ipc_port_t **portsp,
+ mach_msg_type_number_t *portsCnt)
{
vm_offset_t memory;
vm_size_t size;
@@ -1003,8 +998,7 @@ convert_port_to_space(
*/
vm_map_t
-convert_port_to_map(port)
- ipc_port_t port;
+convert_port_to_map(ipc_port_t port)
{
vm_map_t map = VM_MAP_NULL;
@@ -1032,8 +1026,7 @@ convert_port_to_map(port)
*/
thread_t
-convert_port_to_thread(port)
- ipc_port_t port;
+convert_port_to_thread(ipc_port_t port)
{
thread_t thread = THREAD_NULL;
@@ -1061,8 +1054,7 @@ convert_port_to_thread(port)
*/
ipc_port_t
-convert_task_to_port(task)
- task_t task;
+convert_task_to_port(task_t task)
{
ipc_port_t port;
@@ -1088,8 +1080,7 @@ convert_task_to_port(task)
*/
ipc_port_t
-convert_thread_to_port(thread)
- thread_t thread;
+convert_thread_to_port(thread_t thread)
{
ipc_port_t port;
@@ -1113,8 +1104,7 @@ convert_thread_to_port(thread)
*/
void
-space_deallocate(space)
- ipc_space_t space;
+space_deallocate(ipc_space_t space)
{
if (space != IS_NULL)
is_release(space);
diff --git a/kern/list.h b/kern/list.h
index 03414718..be927625 100644
--- a/kern/list.h
+++ b/kern/list.h
@@ -31,9 +31,7 @@
#include <stddef.h>
#include <sys/types.h>
-
-#define structof(ptr, type, member) \
- ((type *)((char *)ptr - offsetof(type, member)))
+#include <kern/macros.h>
/*
* Structure used as both head and node.
@@ -240,7 +238,7 @@ static inline void list_add(struct list *prev, struct list *next,
/*
* Insert a node at the head of a list.
*/
-static inline void list_insert(struct list *list, struct list *node)
+static inline void list_insert_head(struct list *list, struct list *node)
{
list_add(list, list->next, node);
}
diff --git a/kern/lock.c b/kern/lock.c
index 44d4448e..3c74fec8 100644
--- a/kern/lock.c
+++ b/kern/lock.c
@@ -133,7 +133,7 @@ unsigned int simple_locks_taken = 0;
struct simple_locks_info {
simple_lock_t l;
- unsigned int ra;
+ void *ra;
} simple_locks_info[NSLINFO];
void check_simple_locks(void)
@@ -161,10 +161,8 @@ void simple_lock(
info = &simple_locks_info[simple_locks_taken++];
info->l = l;
- /* XXX we want our return address, if possible */
-#if defined(__i386__)
- info->ra = *((unsigned long *)&l - 1);
-#endif /* i386 */
+ info->ra =
+ __builtin_extract_return_addr (__builtin_return_address (0));
}
boolean_t simple_lock_try(
@@ -179,10 +177,8 @@ boolean_t simple_lock_try(
info = &simple_locks_info[simple_locks_taken++];
info->l = l;
- /* XXX we want our return address, if possible */
-#if defined(__i386__)
- info->ra = *((unsigned long *)&l - 1);
-#endif /* i386 */
+ info->ra =
+ __builtin_extract_return_addr (__builtin_return_address (0));
return TRUE;
}
@@ -250,9 +246,9 @@ void lock_sleepable(
*/
void lock_write(
- register lock_t l)
+ lock_t l)
{
- register int i;
+ int i;
check_simple_locks();
simple_lock(&l->interlock);
@@ -308,7 +304,7 @@ void lock_write(
}
void lock_done(
- register lock_t l)
+ lock_t l)
{
simple_lock(&l->interlock);
@@ -340,9 +336,9 @@ void lock_done(
}
void lock_read(
- register lock_t l)
+ lock_t l)
{
- register int i;
+ int i;
check_simple_locks();
simple_lock(&l->interlock);
@@ -387,9 +383,9 @@ void lock_read(
* Returns TRUE if the upgrade *failed*.
*/
boolean_t lock_read_to_write(
- register lock_t l)
+ lock_t l)
{
- register int i;
+ int i;
check_simple_locks();
simple_lock(&l->interlock);
@@ -443,7 +439,7 @@ boolean_t lock_read_to_write(
}
void lock_write_to_read(
- register lock_t l)
+ lock_t l)
{
simple_lock(&l->interlock);
@@ -474,7 +470,7 @@ void lock_write_to_read(
*/
boolean_t lock_try_write(
- register lock_t l)
+ lock_t l)
{
simple_lock(&l->interlock);
@@ -513,7 +509,7 @@ boolean_t lock_try_write(
*/
boolean_t lock_try_read(
- register lock_t l)
+ lock_t l)
{
simple_lock(&l->interlock);
@@ -547,7 +543,7 @@ boolean_t lock_try_read(
* Returns FALSE if the upgrade *failed*.
*/
boolean_t lock_try_read_to_write(
- register lock_t l)
+ lock_t l)
{
check_simple_locks();
simple_lock(&l->interlock);
diff --git a/kern/lock.h b/kern/lock.h
index a8f2fd1c..a6d286a1 100644
--- a/kern/lock.h
+++ b/kern/lock.h
@@ -94,7 +94,9 @@ extern void check_simple_locks(void);
/*
* Do not allocate storage for locks if not needed.
*/
-#define decl_simple_lock_data(class,name)
+struct simple_lock_data_empty {};
+#define decl_simple_lock_data(class,name) \
+class struct simple_lock_data_empty name;
#define simple_lock_addr(lock) ((simple_lock_t)0)
/*
@@ -102,7 +104,7 @@ extern void check_simple_locks(void);
*/
#define simple_lock_init(l)
#define simple_lock(l)
-#define simple_unlock(l)
+#define simple_unlock(l) ((void)(l))
#define simple_lock_try(l) (TRUE) /* always succeeds */
#define simple_lock_taken(l) (1) /* always succeeds */
#define check_simple_locks()
@@ -171,4 +173,6 @@ extern boolean_t lock_try_read_to_write(lock_t);
extern void lock_set_recursive(lock_t);
extern void lock_clear_recursive(lock_t);
+void db_show_all_slocks(void);
+
#endif /* _KERN_LOCK_H_ */
diff --git a/kern/lock_mon.c b/kern/lock_mon.c
index 14504281..f6bbd5dd 100644
--- a/kern/lock_mon.c
+++ b/kern/lock_mon.c
@@ -64,7 +64,6 @@ typedef unsigned int time_stamp_t;
#define LOCK_INFO_HASH_COUNT 1024
#define LOCK_INFO_PER_BUCKET (LOCK_INFO_MAX/LOCK_INFO_HASH_COUNT)
-
#define HASH_LOCK(lock) ((long)lock>>5 & (LOCK_INFO_HASH_COUNT-1))
struct lock_info {
@@ -85,7 +84,7 @@ struct lock_info_bucket lock_info[LOCK_INFO_HASH_COUNT];
struct lock_info default_lock_info;
unsigned default_lock_stack = 0;
-extern int curr_ipl[];
+extern spl_t curr_ipl[];
@@ -94,8 +93,8 @@ locate_lock_info(lock)
decl_simple_lock_data(, **lock)
{
struct lock_info *li = &(lock_info[HASH_LOCK(*lock)].info[0]);
- register i;
- register my_cpu = cpu_number();
+ int i;
+ my_cpu = cpu_number();
for (i=0; i < LOCK_INFO_PER_BUCKET; i++, li++)
if (li->lock) {
@@ -112,11 +111,11 @@ decl_simple_lock_data(, **lock)
}
-simple_lock(lock)
+void simple_lock(lock)
decl_simple_lock_data(, *lock)
{
- register struct lock_info *li = locate_lock_info(&lock);
- register my_cpu = cpu_number();
+ struct lock_info *li = locate_lock_info(&lock);
+ my_cpu = cpu_number();
if (current_thread())
li->stack = current_thread()->lock_stack++;
@@ -131,11 +130,11 @@ decl_simple_lock_data(, *lock)
li->time = time_stamp - li->time;
}
-simple_lock_try(lock)
+int simple_lock_try(lock)
decl_simple_lock_data(, *lock)
{
- register struct lock_info *li = locate_lock_info(&lock);
- register my_cpu = cpu_number();
+ struct lock_info *li = locate_lock_info(&lock);
+ my_cpu = cpu_number();
if (curr_ipl[my_cpu])
li->masked++;
@@ -151,12 +150,12 @@ decl_simple_lock_data(, *lock)
}
}
-simple_unlock(lock)
+void simple_unlock(lock)
decl_simple_lock_data(, *lock)
{
- register time_stamp_t stamp = time_stamp;
- register time_stamp_t *time = &locate_lock_info(&lock)->time;
- register unsigned *lock_stack;
+ time_stamp_t stamp = time_stamp;
+ time_stamp_t *time = &locate_lock_info(&lock)->time;
+ unsigned *lock_stack;
*time = stamp - *time;
_simple_unlock(lock);
@@ -167,16 +166,13 @@ decl_simple_lock_data(, *lock)
}
}
-lip() {
+void lip(void) {
lis(4, 1, 0);
}
#define lock_info_sort lis
-unsigned scurval, ssum;
-struct lock_info *sli;
-
-lock_info_sort(arg, abs, count)
+void lock_info_sort(arg, abs, count)
{
struct lock_info *li, mean;
int bucket = 0;
@@ -215,9 +211,6 @@ lock_info_sort(arg, abs, count)
sum = li->success + li->fail;
if(!sum && !abs)
continue;
- scurval = curval;
- ssum = sum;
- sli = li;
if (!abs) switch(arg) {
case 0:
break;
@@ -257,7 +250,7 @@ lock_info_sort(arg, abs, count)
#define lock_info_clear lic
-lock_info_clear()
+void lock_info_clear(void)
{
struct lock_info *li;
int bucket = 0;
@@ -271,7 +264,7 @@ lock_info_clear()
memset(&default_lock_info, 0, sizeof(struct lock_info));
}
-print_lock_info(li)
+void print_lock_info(li)
struct lock_info *li;
{
int off;
@@ -299,11 +292,11 @@ struct lock_info *li;
* Measure lock/unlock operations
*/
-time_lock(loops)
+void time_lock(int loops)
{
decl_simple_lock_data(, lock)
- register time_stamp_t stamp;
- register int i;
+ time_stamp_t stamp;
+ int i;
if (!loops)
@@ -340,7 +333,7 @@ void
retry_simple_lock(lock)
decl_simple_lock_data(, *lock)
{
- register count = 0;
+ count = 0;
while(!simple_lock_try(lock))
if (count++ > 1000000 && lock != &kdb_lock) {
@@ -356,7 +349,7 @@ decl_simple_lock_data(, *lock)
void
retry_bit_lock(index, addr)
{
- register count = 0;
+ count = 0;
while(!bit_lock_try(index, addr))
if (count++ > 1000000) {
diff --git a/kern/mach_clock.c b/kern/mach_clock.c
index edf87f07..b627b89d 100644
--- a/kern/mach_clock.c
+++ b/kern/mach_clock.c
@@ -27,7 +27,7 @@
* the rights to redistribute these changes.
*/
/*
- * File: clock_prim.c
+ * File: mach_clock.c
* Author: Avadis Tevanian, Jr.
* Date: 1986
*
@@ -54,6 +54,7 @@
#include <kern/thread.h>
#include <kern/time_stamp.h>
#include <kern/timer.h>
+#include <kern/priority.h>
#include <vm/vm_kern.h>
#include <sys/time.h>
#include <machine/mach_param.h> /* HZ */
@@ -64,8 +65,6 @@
#include <kern/pc_sample.h>
#endif
-void softclock(); /* forward */
-
int hz = HZ; /* number of ticks per second */
int tick = (1000000 / HZ); /* number of usec per tick */
time_value_t time = { 0, 0 }; /* time since bootup (uncorrected) */
@@ -121,13 +120,13 @@ timer_elt_data_t timer_head; /* ordered list of timeouts */
* the accuracy of the hardware clock.
*
*/
-void clock_interrupt(usec, usermode, basepri)
- register int usec; /* microseconds per tick */
- boolean_t usermode; /* executing user code */
- boolean_t basepri; /* at base priority */
+void clock_interrupt(
+ int usec, /* microseconds per tick */
+ boolean_t usermode, /* executing user code */
+ boolean_t basepri) /* at base priority */
{
- register int my_cpu = cpu_number();
- register thread_t thread = current_thread();
+ int my_cpu = cpu_number();
+ thread_t thread = current_thread();
counter(c_clock_ticks++);
counter(c_threads_total += c_threads_current);
@@ -150,8 +149,7 @@ void clock_interrupt(usec, usermode, basepri)
* Increment the CPU time statistics.
*/
{
- extern void thread_quantum_update(); /* in priority.c */
- register int state;
+ int state;
if (usermode)
state = CPU_STATE_USER;
@@ -187,8 +185,8 @@ void clock_interrupt(usec, usermode, basepri)
*/
if (my_cpu == master_cpu) {
- register spl_t s;
- register timer_elt_t telt;
+ spl_t s;
+ timer_elt_t telt;
boolean_t needsoft = FALSE;
#if TS_FORMAT == 1
@@ -221,7 +219,7 @@ void clock_interrupt(usec, usermode, basepri)
time_value_add_usec(&time, usec);
}
else {
- register int delta;
+ int delta;
if (timedelta < 0) {
delta = usec - tickdelta;
@@ -236,7 +234,7 @@ void clock_interrupt(usec, usermode, basepri)
update_mapped_time(&time);
/*
- * Schedule soft-interupt for timeout if needed
+ * Schedule soft-interrupt for timeout if needed
*/
if (needsoft) {
if (basepri) {
@@ -272,15 +270,15 @@ void clock_interrupt(usec, usermode, basepri)
* and corrupts it.
*/
-void softclock()
+void softclock(void)
{
/*
* Handle timeouts.
*/
spl_t s;
- register timer_elt_t telt;
- register void (*fcn)( void * param );
- register void *param;
+ timer_elt_t telt;
+ void (*fcn)( void * param );
+ void *param;
while (TRUE) {
s = splsched();
@@ -311,12 +309,12 @@ void softclock()
* telt timer element. Function and param are already set.
* interval time-out interval, in hz.
*/
-void set_timeout(telt, interval)
- register timer_elt_t telt; /* already loaded */
- register unsigned int interval;
+void set_timeout(
+ timer_elt_t telt, /* already loaded */
+ unsigned int interval)
{
spl_t s;
- register timer_elt_t next;
+ timer_elt_t next;
s = splsched();
simple_lock(&timer_lock);
@@ -341,8 +339,7 @@ void set_timeout(telt, interval)
splx(s);
}
-boolean_t reset_timeout(telt)
- register timer_elt_t telt;
+boolean_t reset_timeout(timer_elt_t telt)
{
spl_t s;
@@ -362,7 +359,7 @@ boolean_t reset_timeout(telt)
}
}
-void init_timeout()
+void init_timeout(void)
{
simple_lock_init(&timer_lock);
queue_init(&timer_head.chain);
@@ -389,7 +386,7 @@ record_time_stamp (time_value_t *stamp)
*/
kern_return_t
host_get_time(host, current_time)
- host_t host;
+ const host_t host;
time_value_t *current_time; /* OUT */
{
if (host == HOST_NULL)
@@ -408,7 +405,7 @@ host_get_time(host, current_time)
*/
kern_return_t
host_set_time(host, new_time)
- host_t host;
+ const host_t host;
time_value_t new_time;
{
spl_t s;
@@ -446,7 +443,7 @@ host_set_time(host, new_time)
*/
kern_return_t
host_adjust_time(host, new_adjustment, old_adjustment)
- host_t host;
+ const host_t host;
time_value_t new_adjustment;
time_value_t *old_adjustment; /* OUT */
{
@@ -492,7 +489,7 @@ host_adjust_time(host, new_adjustment, old_adjustment)
return (KERN_SUCCESS);
}
-void mapable_time_init()
+void mapable_time_init(void)
{
if (kmem_alloc_wired(kernel_map, (vm_offset_t *) &mtime, PAGE_SIZE)
!= KERN_SUCCESS)
@@ -501,13 +498,13 @@ void mapable_time_init()
update_mapped_time(&time);
}
-int timeopen()
+int timeopen(dev_t dev, int flag, io_req_t ior)
{
return(0);
}
-int timeclose()
+void timeclose(dev_t dev, int flag)
{
- return(0);
+ return;
}
/*
@@ -528,13 +525,13 @@ timer_elt_data_t timeout_timers[NTIMERS];
* param: parameter to pass to function
* interval: timeout interval, in hz.
*/
-void timeout(fcn, param, interval)
- void (*fcn)( void * param );
- void * param;
- int interval;
+void timeout(
+ void (*fcn)(void *param),
+ void * param,
+ int interval)
{
spl_t s;
- register timer_elt_t elt;
+ timer_elt_t elt;
s = splsched();
simple_lock(&timer_lock);
@@ -557,11 +554,11 @@ void timeout(fcn, param, interval)
* and removed.
*/
boolean_t untimeout(fcn, param)
- register void (*fcn)( void * param );
- register void * param;
+ void (*fcn)( void * param );
+ const void * param;
{
spl_t s;
- register timer_elt_t elt;
+ timer_elt_t elt;
s = splsched();
simple_lock(&timer_lock);
diff --git a/kern/mach_clock.h b/kern/mach_clock.h
index 4e4e8ff1..89fd3352 100644
--- a/kern/mach_clock.h
+++ b/kern/mach_clock.h
@@ -29,6 +29,10 @@
#include <mach/time_value.h>
#include <kern/host.h>
#include <kern/queue.h>
+#include <sys/types.h>
+
+struct io_req;
+typedef struct io_req *io_req_t;
/* Timers in kernel. */
@@ -102,6 +106,9 @@ extern void mapable_time_init (void);
/* For public timer elements. */
extern void timeout(timer_func_t *fcn, void *param, int interval);
-extern boolean_t untimeout(timer_func_t *fcn, void *param);
+extern boolean_t untimeout(timer_func_t *fcn, const void *param);
+
+extern int timeopen(dev_t dev, int flag, io_req_t ior);
+extern void timeclose(dev_t dev, int flag);
#endif /* _KERN_MACH_CLOCK_H_ */
diff --git a/kern/mach_factor.c b/kern/mach_factor.c
index 558c4a06..debce0b0 100644
--- a/kern/mach_factor.c
+++ b/kern/mach_factor.c
@@ -55,13 +55,13 @@ static long fract[3] = {
void compute_mach_factor(void)
{
- register processor_set_t pset;
- register processor_t processor;
- register int ncpus;
- register int nthreads;
- register long factor_now;
- register long average_now;
- register long load_now;
+ processor_set_t pset;
+ processor_t processor;
+ int ncpus;
+ int nthreads;
+ long factor_now;
+ long average_now;
+ long load_now;
simple_lock(&all_psets_lock);
pset = (processor_set_t) queue_first(&all_psets);
@@ -123,7 +123,7 @@ void compute_mach_factor(void)
* And some ugly stuff to keep w happy.
*/
if (pset == &default_pset) {
- register int i;
+ int i;
for (i = 0; i < 3; i++) {
mach_factor[i] = ( (mach_factor[i]*fract[i])
diff --git a/kern/machine.c b/kern/machine.c
index c2a19b99..eced7688 100644
--- a/kern/machine.c
+++ b/kern/machine.c
@@ -72,12 +72,11 @@ decl_simple_lock_data(,action_lock);
* Flag specified cpu as up and running. Called when a processor comes
* online.
*/
-void cpu_up(cpu)
- int cpu;
+void cpu_up(int cpu)
{
- register struct machine_slot *ms;
- register processor_t processor;
- register spl_t s;
+ struct machine_slot *ms;
+ processor_t processor;
+ spl_t s;
processor = cpu_to_processor(cpu);
pset_lock(&default_pset);
@@ -102,12 +101,11 @@ void cpu_up(cpu)
* Flag specified cpu as down. Called when a processor is about to
* go offline.
*/
-void cpu_down(cpu)
- int cpu;
+void cpu_down(int cpu)
{
- register struct machine_slot *ms;
- register processor_t processor;
- register spl_t s;
+ struct machine_slot *ms;
+ processor_t processor;
+ spl_t s;
s = splsched();
processor = cpu_to_processor(cpu);
@@ -126,8 +124,8 @@ void cpu_down(cpu)
kern_return_t
host_reboot(host, options)
- host_t host;
- int options;
+ const host_t host;
+ int options;
{
if (host == HOST_NULL)
return (KERN_INVALID_HOST);
@@ -153,11 +151,11 @@ host_reboot(host, options)
* a reference.
*/
void
-processor_request_action(processor, new_pset)
-processor_t processor;
-processor_set_t new_pset;
+processor_request_action(
+ processor_t processor,
+ processor_set_t new_pset)
{
- register processor_set_t pset;
+ processor_set_t pset;
/*
* Processor must be in a processor set. Must lock its idle lock to
@@ -228,10 +226,10 @@ processor_set_t new_pset;
* Synchronizes with assignment completion if wait is TRUE.
*/
kern_return_t
-processor_assign(processor, new_pset, wait)
-processor_t processor;
-processor_set_t new_pset;
-boolean_t wait;
+processor_assign(
+ processor_t processor,
+ processor_set_t new_pset,
+ boolean_t wait)
{
spl_t s;
@@ -315,14 +313,11 @@ Retry:
#else /* MACH_HOST */
kern_return_t
-processor_assign(processor, new_pset, wait)
-processor_t processor;
-processor_set_t new_pset;
-boolean_t wait;
+processor_assign(
+ processor_t processor,
+ processor_set_t new_pset,
+ boolean_t wait)
{
-#ifdef lint
- processor++; new_pset++; wait++;
-#endif
return KERN_FAILURE;
}
@@ -334,8 +329,7 @@ boolean_t wait;
* with the shutdown (can be called from interrupt level).
*/
kern_return_t
-processor_shutdown(processor)
-processor_t processor;
+processor_shutdown(processor_t processor)
{
spl_t s;
@@ -364,12 +358,10 @@ processor_t processor;
/*
* action_thread() shuts down processors or changes their assignment.
*/
-void processor_doaction(); /* forward */
-
-void action_thread_continue()
+void action_thread_continue(void)
{
- register processor_t processor;
- register spl_t s;
+ processor_t processor;
+ spl_t s;
while (TRUE) {
s = splsched();
@@ -395,7 +387,7 @@ void action_thread_continue()
}
}
-void action_thread()
+void __attribute__((noreturn)) action_thread(void)
{
action_thread_continue();
/*NOTREACHED*/
@@ -406,21 +398,15 @@ void action_thread()
* is to schedule ourselves onto a cpu and then save our
* context back into the runqs before taking out the cpu.
*/
-#ifdef __GNUC__
-__volatile__
-#endif
-void processor_doshutdown(); /* forward */
-
-void processor_doaction(processor)
-register processor_t processor;
+void processor_doaction(processor_t processor)
{
thread_t this_thread;
spl_t s;
- register processor_set_t pset;
+ processor_set_t pset;
#if MACH_HOST
- register processor_set_t new_pset;
- register thread_t thread;
- register thread_t prev_thread = THREAD_NULL;
+ processor_set_t new_pset;
+ thread_t thread;
+ thread_t prev_thread = THREAD_NULL;
boolean_t have_pset_ref = FALSE;
#endif /* MACH_HOST */
@@ -633,13 +619,10 @@ Restart_pset:
* running on the processor's shutdown stack.
*/
-#ifdef __GNUC__
-__volatile__
-#endif
void processor_doshutdown(processor)
-register processor_t processor;
+processor_t processor;
{
- register int cpu = processor->slot_num;
+ int cpu = processor->slot_num;
timer_switch(&kernel_timer[cpu]);
@@ -663,23 +646,20 @@ register processor_t processor;
#else /* NCPUS > 1 */
kern_return_t
-processor_assign(processor, new_pset, wait)
-processor_t processor;
-processor_set_t new_pset;
-boolean_t wait;
+processor_assign(
+ processor_t processor,
+ processor_set_t new_pset,
+ boolean_t wait)
{
-#ifdef lint
- processor++; new_pset++; wait++;
-#endif /* lint */
return(KERN_FAILURE);
}
#endif /* NCPUS > 1 */
kern_return_t
-host_get_boot_info(priv_host, boot_info)
- host_t priv_host;
- kernel_boot_info_t boot_info;
+host_get_boot_info(
+ host_t priv_host,
+ kernel_boot_info_t boot_info)
{
char *src = "";
diff --git a/kern/machine.h b/kern/machine.h
index af2b7e91..c67213a2 100644
--- a/kern/machine.h
+++ b/kern/machine.h
@@ -53,6 +53,6 @@ extern kern_return_t processor_shutdown (processor_t);
/*
* action_thread() shuts down processors or changes their assignment.
*/
-extern void action_thread_continue (void);
+extern void action_thread_continue (void) __attribute__((noreturn));
#endif /* _MACHINE_H_ */
diff --git a/kern/macro_help.h b/kern/macro_help.h
deleted file mode 100644
index a3d156b7..00000000
--- a/kern/macro_help.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: kern/macro_help.h
- *
- * Provide help in making lint-free macro routines
- *
- */
-
-#ifndef _KERN_MACRO_HELP_H_
-#define _KERN_MACRO_HELP_H_
-
-#if !defined(MACRO_BEGIN)
-
-#include <mach/boolean.h>
-
-#ifdef lint
-boolean_t NEVER;
-boolean_t ALWAYS;
-#else /* lint */
-#define NEVER FALSE
-#define ALWAYS TRUE
-#endif /* lint */
-
-#define MACRO_BEGIN ({
-#define MACRO_END })
-
-#define MACRO_RETURN if (ALWAYS) return
-
-#endif /* !MACRO_BEGIN */
-
-#endif /* _KERN_MACRO_HELP_H_ */
diff --git a/kern/macros.h b/kern/macros.h
new file mode 100644
index 00000000..fb8dc5e1
--- /dev/null
+++ b/kern/macros.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2009, 2010, 2013 Richard Braun.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * Helper macros.
+ */
+
+#ifndef _KERN_MACROS_H
+#define _KERN_MACROS_H
+
+#define MACRO_BEGIN ({
+#define MACRO_END })
+#define MACRO_RETURN if (1) return
+
+#define __QUOTE(x) #x
+#define QUOTE(x) __QUOTE(x)
+
+#ifdef __ASSEMBLER__
+#define DECL_CONST(x, s) x
+#else /* __ASSEMBLER__ */
+#define __DECL_CONST(x, s) x##s
+#define DECL_CONST(x, s) __DECL_CONST(x, s)
+#endif /* __ASSEMBLER__ */
+
+#define STRLEN(x) (sizeof(x) - 1)
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+#define DIV_CEIL(n, d) (((n) + (d) - 1) / (d))
+
+#define P2ALIGNED(x, a) (((x) & ((a) - 1)) == 0)
+#define ISP2(x) P2ALIGNED(x, x)
+#define P2ALIGN(x, a) ((x) & -(a))
+#define P2ROUND(x, a) (-(-(x) & -(a)))
+#define P2END(x, a) (-(~(x) & -(a)))
+
+#define structof(ptr, type, member) \
+ ((type *)((char *)(ptr) - offsetof(type, member)))
+
+#define alignof(x) __alignof__(x)
+
+#define likely(expr) __builtin_expect(!!(expr), 1)
+#define unlikely(expr) __builtin_expect(!!(expr), 0)
+
+#define barrier() asm volatile("" : : : "memory")
+
+#define __noreturn __attribute__((noreturn))
+#define __aligned(x) __attribute__((aligned(x)))
+#define __always_inline inline __attribute__((always_inline))
+#define __section(x) __attribute__((section(x)))
+#define __packed __attribute__((packed))
+#define __alias(x) __attribute__((alias(x)))
+
+#define __format_printf(fmt, args) \
+ __attribute__((format(printf, fmt, args)))
+
+#endif /* _KERN_MACROS_H */
diff --git a/kern/pc_sample.c b/kern/pc_sample.c
index 57002581..fcb9d71b 100644
--- a/kern/pc_sample.c
+++ b/kern/pc_sample.c
@@ -43,12 +43,9 @@
typedef sampled_pc_t sampled_pcs[MAX_PC_SAMPLES];
-int pc_sampling_enabled = 0;
-decl_simple_lock_data(, pc_sampling_lock) /* lock for enabling */
-
void take_pc_sample(
- register thread_t t,
- register sample_control_t *cp,
+ const thread_t t,
+ sample_control_t *cp,
sampled_pc_flavor_t flavor)
{
vm_offset_t pc;
@@ -192,6 +189,9 @@ get_sampled_pcs(
(sampled_pc_array_t)cp->buffer,
(seqidx2 + 1) * sizeof(sampled_pc_t));
}
+ } else if (nsamples < 0) {
+ /* Bogus SEQNO supplied. */
+ nsamples = 0;
} else {
/* could either be zero because of overflow, or because
* we are being lied to. In either case, return nothing.
@@ -244,8 +244,8 @@ task_get_sampled_pcs(
kern_return_t
thread_enable_pc_sampling(
- thread_t thread,
- int *tickp,
+ const thread_t thread,
+ const int *tickp,
sampled_pc_flavor_t flavors)
{
return KERN_FAILURE; /* not implemented */
@@ -253,8 +253,8 @@ thread_enable_pc_sampling(
kern_return_t
task_enable_pc_sampling(
- task_t task,
- int *tickp,
+ const task_t task,
+ const int *tickp,
sampled_pc_flavor_t flavors)
{
return KERN_FAILURE; /* not implemented */
@@ -262,36 +262,36 @@ task_enable_pc_sampling(
kern_return_t
thread_disable_pc_sampling(
- thread_t thread,
- int *samplecntp)
+ const thread_t thread,
+ const int *samplecntp)
{
return KERN_FAILURE; /* not implemented */
}
kern_return_t
task_disable_pc_sampling(
- task_t task,
- int *samplecntp)
+ const task_t task,
+ const int *samplecntp)
{
return KERN_FAILURE; /* not implemented */
}
kern_return_t
thread_get_sampled_pcs(
- thread_t thread,
- sampled_pc_seqno_t *seqnop,
- sampled_pc_array_t sampled_pcs_out,
- int *sampled_pcs_cntp)
+ const thread_t thread,
+ const sampled_pc_seqno_t *seqnop,
+ const sampled_pc_array_t sampled_pcs_out,
+ const int *sampled_pcs_cntp)
{
return KERN_FAILURE; /* not implemented */
}
kern_return_t
task_get_sampled_pcs(
- task_t task,
- sampled_pc_seqno_t *seqnop,
- sampled_pc_array_t sampled_pcs_out,
- int *sampled_pcs_cntp)
+ const task_t task,
+ const sampled_pc_seqno_t *seqnop,
+ const sampled_pc_array_t sampled_pcs_out,
+ const int *sampled_pcs_cntp)
{
return KERN_FAILURE; /* not implemented */
}
diff --git a/kern/pc_sample.h b/kern/pc_sample.h
index 3c64068d..4832cb9f 100644
--- a/kern/pc_sample.h
+++ b/kern/pc_sample.h
@@ -49,7 +49,7 @@
#include <mach/pc_sample.h>
#include <mach/machine/vm_types.h>
#include <kern/kern_types.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
/*
* Control structure for sampling, included in
diff --git a/kern/printf.c b/kern/printf.c
index a3a771d0..50f23623 100644
--- a/kern/printf.c
+++ b/kern/printf.c
@@ -126,17 +126,17 @@
#define isdigit(d) ((d) >= '0' && (d) <= '9')
#define Ctod(c) ((c) - '0')
-#define MAXBUF (sizeof(long int) * 8) /* enough for binary */
+#define MAXBUF (sizeof(long long int) * 8) /* enough for binary */
void printnum(
- register unsigned long u,
- register int base,
+ unsigned long long u,
+ int base,
void (*putc)( char, vm_offset_t ),
vm_offset_t putc_arg)
{
char buf[MAXBUF]; /* build number here */
- register char * p = &buf[MAXBUF-1];
+ char * p = &buf[MAXBUF-1];
static char digs[] = "0123456789abcdef";
do {
@@ -151,23 +151,8 @@ void printnum(
boolean_t _doprnt_truncates = FALSE;
-/* printf could be called at _any_ point during system initialization,
- including before printf_init() gets called from the "normal" place
- in kern/startup.c. */
-boolean_t _doprnt_lock_initialized = FALSE;
-decl_simple_lock_data(,_doprnt_lock)
-
-void printf_init(void)
-{
- if (!_doprnt_lock_initialized)
- {
- _doprnt_lock_initialized = TRUE;
- simple_lock_init(&_doprnt_lock);
- }
-}
-
void _doprnt(
- register const char *fmt,
+ const char *fmt,
va_list argp,
/* character output routine */
void (*putc)( char, vm_offset_t),
@@ -178,29 +163,14 @@ void _doprnt(
int prec;
boolean_t ladjust;
char padc;
- long n;
- unsigned long u;
+ long long n;
+ unsigned long long u;
+ int have_long_long;
int plus_sign;
int sign_char;
boolean_t altfmt, truncate;
int base;
- register char c;
-
- printf_init();
-
-#if 0
- /* Make sure that we get *some* printout, no matter what */
- simple_lock(&_doprnt_lock);
-#else
- {
- register int i = 0;
- while (i < 1*1024*1024) {
- if (simple_lock_try(&_doprnt_lock))
- break;
- i++;
- }
- }
-#endif
+ char c;
while ((c = *fmt) != '\0') {
if (c != '%') {
@@ -218,6 +188,7 @@ void _doprnt(
plus_sign = 0;
sign_char = 0;
altfmt = FALSE;
+ have_long_long = FALSE;
while (TRUE) {
c = *fmt;
@@ -276,6 +247,10 @@ void _doprnt(
if (c == 'l')
c = *++fmt; /* need it if sizeof(int) < sizeof(long) */
+ if (c == 'l') {
+ c = *++fmt; /* handle `long long' */
+ have_long_long = TRUE;
+ }
truncate = FALSE;
@@ -283,11 +258,14 @@ void _doprnt(
case 'b':
case 'B':
{
- register char *p;
- boolean_t any;
- register int i;
-
- u = va_arg(argp, unsigned long);
+ char *p;
+ boolean_t any;
+ int i;
+
+ if (! have_long_long)
+ u = va_arg(argp, unsigned long);
+ else
+ u = va_arg(argp, unsigned long long);
p = va_arg(argp, char *);
base = *p++;
printnum(u, base, putc, putc_arg);
@@ -302,7 +280,7 @@ void _doprnt(
/*
* Bit field
*/
- register int j;
+ int j;
if (any)
(*putc)(',', putc_arg);
else {
@@ -342,8 +320,8 @@ void _doprnt(
case 's':
{
- register char *p;
- register char *p2;
+ char *p;
+ char *p2;
if (prec == -1)
prec = 0x7fffffff; /* MAXINT */
@@ -431,7 +409,10 @@ void _doprnt(
goto print_unsigned;
print_signed:
- n = va_arg(argp, long);
+ if (! have_long_long)
+ n = va_arg(argp, long);
+ else
+ n = va_arg(argp, long long);
if (n >= 0) {
u = n;
sign_char = plus_sign;
@@ -443,13 +424,16 @@ void _doprnt(
goto print_num;
print_unsigned:
- u = va_arg(argp, unsigned long);
+ if (! have_long_long)
+ u = va_arg(argp, unsigned long);
+ else
+ u = va_arg(argp, unsigned long long);
goto print_num;
print_num:
{
char buf[MAXBUF]; /* build number here */
- register char * p = &buf[MAXBUF-1];
+ char * p = &buf[MAXBUF-1];
static char digits[] = "0123456789abcdef";
char *prefix = 0;
@@ -507,8 +491,6 @@ void _doprnt(
}
fmt++;
}
-
- simple_unlock(&_doprnt_lock);
}
/*
@@ -540,7 +522,7 @@ int indent = 0;
void iprintf(const char *fmt, ...)
{
va_list listp;
- register int i;
+ int i;
for (i = indent; i > 0; ){
if (i >= 8) {
@@ -567,8 +549,8 @@ sputc(
char c,
vm_offset_t arg)
{
- register char **bufp = (char **) arg;
- register char *p = *bufp;
+ char **bufp = (char **) arg;
+ char *p = *bufp;
*p++ = c;
*bufp = p;
}
@@ -615,13 +597,23 @@ vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
return cookie.index;
}
+int
+snprintf(char *buf, size_t size, const char *fmt, ...)
+{
+ int written;
+ va_list listp;
+ va_start(listp, fmt);
+ written = vsnprintf(buf, size, fmt, listp);
+ va_end(listp);
+ return written;
+}
-void safe_gets(str, maxlen)
- char *str;
- int maxlen;
+void safe_gets(
+ char *str,
+ int maxlen)
{
- register char *lp;
- register int c;
+ char *lp;
+ int c;
char *strmax = str + maxlen - 1; /* allow space for trailing 0 */
lp = str;
diff --git a/kern/printf.h b/kern/printf.h
index 8b4e7606..b72640aa 100644
--- a/kern/printf.h
+++ b/kern/printf.h
@@ -27,22 +27,26 @@
#include <sys/types.h>
#include <stdarg.h>
-extern void printf_init (void);
-
extern void _doprnt (const char *fmt,
va_list argp,
void (*putc)(char, vm_offset_t),
int radix,
vm_offset_t putc_arg);
-extern void printnum (unsigned long u, int base,
+extern void printnum (unsigned long long u, int base,
void (*putc)(char, vm_offset_t),
vm_offset_t putc_arg);
-extern int sprintf (char *buf, const char *fmt, ...);
-extern int vsnprintf (char *buf, size_t size, const char *fmt, va_list args);
+extern int sprintf (char *buf, const char *fmt, ...)
+ __attribute__ ((format (printf, 2, 3)));
+extern int snprintf (char *buf, size_t size, const char *fmt, ...)
+ __attribute__ ((format (printf, 3, 4)));
+extern int vsnprintf (char *buf, size_t size, const char *fmt, va_list args)
+ __attribute__ ((format (printf, 3, 0)));
+
-extern int printf (const char *fmt, ...);
+extern int printf (const char *fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
#define printf_once(fmt, ...) \
MACRO_BEGIN \
diff --git a/kern/priority.c b/kern/priority.c
index 17541b8b..587ea2f9 100644
--- a/kern/priority.c
+++ b/kern/priority.c
@@ -27,7 +27,7 @@
* the rights to redistribute these changes.
*/
/*
- * File: clock_prim.c
+ * File: priority.c
* Author: Avadis Tevanian, Jr.
* Date: 1986
*
@@ -74,16 +74,16 @@
* Called only from clock_interrupt().
*/
-void thread_quantum_update(mycpu, thread, nticks, state)
- register int mycpu;
- register thread_t thread;
- int nticks;
- int state;
+void thread_quantum_update(
+ int mycpu,
+ thread_t thread,
+ int nticks,
+ int state)
{
- register int quantum;
- register processor_t myprocessor;
+ int quantum;
+ processor_t myprocessor;
#if NCPUS > 1
- register processor_set_t pset;
+ processor_set_t pset;
#endif
spl_t s;
diff --git a/kern/priority.h b/kern/priority.h
new file mode 100644
index 00000000..2da93ebe
--- /dev/null
+++ b/kern/priority.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _KERN_PRIORITY_H_
+#define _KERN_PRIORITY_H_
+
+extern void thread_quantum_update(
+ int mycpu,
+ thread_t thread,
+ int nticks,
+ int state);
+
+#endif /* _KERN_PRIORITY_H_ */
diff --git a/kern/processor.c b/kern/processor.c
index 19868609..48e92731 100644
--- a/kern/processor.c
+++ b/kern/processor.c
@@ -66,18 +66,11 @@ processor_t master_processor;
processor_t processor_ptr[NCPUS];
/*
- * Forward declarations.
- */
-void quantum_set(processor_set_t);
-void pset_init(processor_set_t);
-void processor_init(processor_t, int);
-
-/*
* Bootstrap the processor/pset system so the scheduler can run.
*/
void pset_sys_bootstrap(void)
{
- register int i;
+ int i;
pset_init(&default_pset);
default_pset.empty = FALSE;
@@ -109,8 +102,8 @@ void pset_sys_bootstrap(void)
*/
void pset_sys_init(void)
{
- register int i;
- register processor_t processor;
+ int i;
+ processor_t processor;
/*
* Allocate the cache for processor sets.
@@ -138,7 +131,7 @@ void pset_sys_init(void)
*/
void pset_init(
- register processor_set_t pset)
+ processor_set_t pset)
{
int i;
@@ -189,7 +182,7 @@ void pset_init(
*/
void processor_init(
- register processor_t pr,
+ processor_t pr,
int slot_num)
{
int i;
@@ -414,14 +407,14 @@ void pset_reference(
kern_return_t
processor_info(
- register processor_t processor,
+ processor_t processor,
int flavor,
host_t *host,
processor_info_t info,
natural_t *count)
{
- register int slot_num, state;
- register processor_basic_info_t basic_info;
+ int slot_num, state;
+ processor_basic_info_t basic_info;
if (processor == PROCESSOR_NULL)
return KERN_INVALID_ARGUMENT;
@@ -503,7 +496,7 @@ void quantum_set(
processor_set_t pset)
{
#if NCPUS > 1
- register int i,ncpus;
+ int i, ncpus;
ncpus = pset->processor_count;
@@ -567,8 +560,8 @@ processor_set_create(
kern_return_t processor_set_destroy(
processor_set_t pset)
{
- register queue_entry_t elem;
- register queue_head_t *list;
+ queue_entry_t elem;
+ queue_head_t *list;
if (pset == PROCESSOR_SET_NULL || pset == &default_pset)
return KERN_INVALID_ARGUMENT;
@@ -647,18 +640,12 @@ processor_set_create(
processor_set_t *new_set,
processor_set_t *new_name)
{
-#ifdef lint
- host++; new_set++; new_name++;
-#endif /* lint */
return KERN_FAILURE;
}
kern_return_t processor_set_destroy(
processor_set_t pset)
{
-#ifdef lint
- pset++;
-#endif /* lint */
return KERN_FAILURE;
}
@@ -670,6 +657,8 @@ processor_get_assignment(
processor_set_t *pset)
{
int state;
+ if (processor == PROCESSOR_NULL)
+ return KERN_INVALID_ARGUMENT;
state = processor->state;
if (state == PROCESSOR_SHUTDOWN || state == PROCESSOR_OFF_LINE)
@@ -692,7 +681,7 @@ processor_set_info(
return KERN_INVALID_ARGUMENT;
if (flavor == PROCESSOR_SET_BASIC_INFO) {
- register processor_set_basic_info_t basic_info;
+ processor_set_basic_info_t basic_info;
if (*count < PROCESSOR_SET_BASIC_INFO_COUNT)
return KERN_FAILURE;
@@ -712,7 +701,7 @@ processor_set_info(
return KERN_SUCCESS;
}
else if (flavor == PROCESSOR_SET_SCHED_INFO) {
- register processor_set_sched_info_t sched_info;
+ processor_set_sched_info_t sched_info;
if (*count < PROCESSOR_SET_SCHED_INFO_COUNT)
return KERN_FAILURE;
@@ -757,8 +746,8 @@ processor_set_max_priority(
pset->max_priority = max_priority;
if (change_threads) {
- register queue_head_t *list;
- register thread_t thread;
+ queue_head_t *list;
+ thread_t thread;
list = &pset->threads;
queue_iterate(list, thread, thread_t, pset_threads) {
@@ -828,8 +817,8 @@ processor_set_policy_disable(
pset->policies &= ~policy;
if (change_threads) {
- register queue_head_t *list;
- register thread_t thread;
+ queue_head_t *list;
+ thread_t thread;
list = &pset->threads;
queue_iterate(list, thread, thread_t, pset_threads) {
diff --git a/kern/processor.h b/kern/processor.h
index 9a6c944b..b81526c0 100644
--- a/kern/processor.h
+++ b/kern/processor.h
@@ -320,4 +320,10 @@ extern kern_return_t processor_set_threads(
natural_t *count);
#endif
+void processor_doaction(processor_t processor);
+void processor_doshutdown(processor_t processor);
+void quantum_set(processor_set_t pset);
+void pset_init(processor_set_t pset);
+void processor_init(processor_t pr, int slot_num);
+
#endif /* _KERN_PROCESSOR_H_ */
diff --git a/kern/profile.c b/kern/profile.c
index e14d4116..55107218 100644
--- a/kern/profile.c
+++ b/kern/profile.c
@@ -194,7 +194,7 @@ thread_t th;
* Make a request to the profile_thread by inserting
* the buffer in the send queue, and wake it up.
* The last buffer must be inserted at the head of the
- * send queue, so the profile_thread handles it immediatly.
+ * send queue, so the profile_thread handles it immediately.
*/
if (kmem_alloc( kernel_map, &vm_buf_entry,
sizeof(struct buf_to_send)) != KERN_SUCCESS)
diff --git a/kern/queue.c b/kern/queue.c
index 98b74c20..d9396e54 100644
--- a/kern/queue.c
+++ b/kern/queue.c
@@ -35,8 +35,8 @@
* Insert element at head of queue.
*/
void enqueue_head(
- register queue_t que,
- register queue_entry_t elt)
+ queue_t que,
+ queue_entry_t elt)
{
elt->next = que->next;
elt->prev = que;
@@ -48,8 +48,8 @@ void enqueue_head(
* Insert element at tail of queue.
*/
void enqueue_tail(
- register queue_t que,
- register queue_entry_t elt)
+ queue_t que,
+ queue_entry_t elt)
{
elt->next = que;
elt->prev = que->prev;
@@ -61,9 +61,9 @@ void enqueue_tail(
* Remove and return element at head of queue.
*/
queue_entry_t dequeue_head(
- register queue_t que)
+ queue_t que)
{
- register queue_entry_t elt;
+ queue_entry_t elt;
if (que->next == que)
return((queue_entry_t)0);
@@ -78,9 +78,9 @@ queue_entry_t dequeue_head(
* Remove and return element at tail of queue.
*/
queue_entry_t dequeue_tail(
- register queue_t que)
+ queue_t que)
{
- register queue_entry_t elt;
+ queue_entry_t elt;
if (que->prev == que)
return((queue_entry_t)0);
@@ -100,7 +100,7 @@ queue_entry_t dequeue_tail(
/*ARGSUSED*/
void remqueue(
queue_t que,
- register queue_entry_t elt)
+ queue_entry_t elt)
{
elt->next->prev = elt->prev;
elt->prev->next = elt->next;
@@ -111,8 +111,8 @@ void remqueue(
* package.
*/
void insque(
- register struct queue_entry *entry,
- register struct queue_entry *pred)
+ struct queue_entry *entry,
+ struct queue_entry *pred)
{
entry->next = pred->next;
entry->prev = pred;
@@ -122,7 +122,7 @@ void insque(
struct queue_entry
*remque(
- register struct queue_entry *elt)
+ struct queue_entry *elt)
{
(elt->next)->prev = elt->prev;
(elt->prev)->next = elt->next;
diff --git a/kern/queue.h b/kern/queue.h
index 1846922a..f0b4002f 100644
--- a/kern/queue.h
+++ b/kern/queue.h
@@ -87,6 +87,14 @@ void remqueue(queue_t, queue_entry_t);
void insque(queue_entry_t, queue_entry_t);
/*
+ * Macro: queue_assert
+ * Function:
+ * Used by macros to assert that the given argument is a
+ * queue.
+ */
+#define queue_assert(q) (void) ((void) (q)->next, (q)->prev)
+
+/*
* Macro: queue_init
* Function:
* Initialize the given queue.
@@ -104,7 +112,7 @@ void insque(queue_entry_t, queue_entry_t);
* queue_entry_t queue_first(q)
* queue_t q; *IN*
*/
-#define queue_first(q) ((q)->next)
+#define queue_first(q) (queue_assert(q), (q)->next)
/*
* Macro: queue_next
@@ -114,7 +122,7 @@ void insque(queue_entry_t, queue_entry_t);
* queue_entry_t queue_next(qc)
* queue_t qc;
*/
-#define queue_next(qc) ((qc)->next)
+#define queue_next(qc) (queue_assert(qc), (qc)->next)
/*
* Macro: queue_last
@@ -124,7 +132,7 @@ void insque(queue_entry_t, queue_entry_t);
* queue_entry_t queue_last(q)
* queue_t q; *IN*
*/
-#define queue_last(q) ((q)->prev)
+#define queue_last(q) (queue_assert(q), (q)->prev)
/*
* Macro: queue_prev
@@ -134,7 +142,7 @@ void insque(queue_entry_t, queue_entry_t);
* queue_entry_t queue_prev(qc)
* queue_t qc;
*/
-#define queue_prev(qc) ((qc)->prev)
+#define queue_prev(qc) (queue_assert(qc), (qc)->prev)
/*
* Macro: queue_end
@@ -146,7 +154,8 @@ void insque(queue_entry_t, queue_entry_t);
* queue_t q;
* queue_entry_t qe;
*/
-#define queue_end(q, qe) ((q) == (qe))
+#define queue_end(q, qe) (queue_assert(q), queue_assert(qe), \
+ (q) == (qe))
/*
* Macro: queue_empty
@@ -179,7 +188,9 @@ void insque(queue_entry_t, queue_entry_t);
*/
#define queue_enter(head, elt, type, field) \
{ \
- register queue_entry_t prev; \
+ queue_assert(head); \
+ queue_assert(&(elt)->field); \
+ queue_entry_t prev; \
\
prev = (head)->prev; \
if ((head) == prev) { \
@@ -206,7 +217,9 @@ void insque(queue_entry_t, queue_entry_t);
*/
#define queue_enter_first(head, elt, type, field) \
{ \
- register queue_entry_t next; \
+ queue_assert(head); \
+ queue_assert(&(elt)->field); \
+ queue_entry_t next; \
\
next = (head)->next; \
if ((head) == next) { \
@@ -239,7 +252,9 @@ void insque(queue_entry_t, queue_entry_t);
*/
#define queue_remove(head, elt, type, field) \
{ \
- register queue_entry_t next, prev; \
+ queue_assert(head); \
+ queue_assert(&(elt)->field); \
+ queue_entry_t next, prev; \
\
next = (elt)->field.next; \
prev = (elt)->field.prev; \
@@ -266,7 +281,9 @@ void insque(queue_entry_t, queue_entry_t);
*/
#define queue_remove_first(head, entry, type, field) \
{ \
- register queue_entry_t next; \
+ queue_assert(head); \
+ queue_assert(&(entry)->field); \
+ queue_entry_t next; \
\
(entry) = (type) ((head)->next); \
next = (entry)->field.next; \
@@ -289,7 +306,9 @@ void insque(queue_entry_t, queue_entry_t);
*/
#define queue_remove_last(head, entry, type, field) \
{ \
- register queue_entry_t prev; \
+ queue_assert(head); \
+ queue_assert(&(entry)->field); \
+ queue_entry_t prev; \
\
(entry) = (type) ((head)->prev); \
prev = (entry)->field.prev; \
@@ -306,6 +325,8 @@ void insque(queue_entry_t, queue_entry_t);
*/
#define queue_assign(to, from, type, field) \
{ \
+ queue_assert(&(to)->field); \
+ queue_assert(&(from)->field); \
((type)((from)->prev))->field.next = (to); \
((type)((from)->next))->field.prev = (to); \
*to = *from; \
diff --git a/kern/rbtree.h b/kern/rbtree.h
index 5a65d1ef..16ef2736 100644
--- a/kern/rbtree.h
+++ b/kern/rbtree.h
@@ -31,13 +31,9 @@
#include <stddef.h>
#include <kern/assert.h>
-#include <kern/macro_help.h>
-#include <kern/rbtree.h>
+#include <kern/macros.h>
#include <sys/types.h>
-#define structof(ptr, type, member) \
- ((type *)((char *)ptr - offsetof(type, member)))
-
/*
* Indexes of the left and right nodes in the children array of a node.
*/
@@ -178,8 +174,8 @@ MACRO_END
* This macro performs a standard lookup to obtain the insertion point of
* the given node in the tree (it is assumed that the inserted node never
* compares equal to any other entry in the tree) and links the node. It
- * then It then checks red-black rules violations, and rebalances the tree
- * if necessary.
+ * then checks red-black rules violations, and rebalances the tree if
+ * necessary.
*
* Unlike rbtree_lookup(), the cmp_fn parameter must compare two complete
* entries, so it is suggested to use two different comparison inline
diff --git a/kern/rdxtree.c b/kern/rdxtree.c
new file mode 100644
index 00000000..78868b1f
--- /dev/null
+++ b/kern/rdxtree.c
@@ -0,0 +1,830 @@
+/*
+ * Copyright (c) 2011-2015 Richard Braun.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Upstream site with license notes :
+ * http://git.sceen.net/rbraun/librbraun.git/
+ */
+
+#include <kern/assert.h>
+#include <kern/slab.h>
+#include <mach/kern_return.h>
+#include <stddef.h>
+#include <string.h>
+
+#include "macros.h"
+#include "rdxtree.h"
+#include "rdxtree_i.h"
+
+/* XXX */
+#define CHAR_BIT 8U
+#define ERR_SUCCESS KERN_SUCCESS
+#define ERR_BUSY KERN_INVALID_ARGUMENT
+#define ERR_NOMEM KERN_RESOURCE_SHORTAGE
+
+/*
+ * Mask applied on an entry to obtain its address.
+ */
+#define RDXTREE_ENTRY_ADDR_MASK (~0x3UL)
+
+/*
+ * Global properties used to shape radix trees.
+ */
+#define RDXTREE_RADIX 6
+#define RDXTREE_RADIX_SIZE (1UL << RDXTREE_RADIX)
+#define RDXTREE_RADIX_MASK (RDXTREE_RADIX_SIZE - 1)
+
+#if RDXTREE_RADIX < 6
+typedef unsigned long rdxtree_bm_t;
+#define rdxtree_ffs(x) __builtin_ffsl(x)
+#elif RDXTREE_RADIX == 6 /* RDXTREE_RADIX < 6 */
+typedef unsigned long long rdxtree_bm_t;
+#define rdxtree_ffs(x) __builtin_ffsll(x)
+#else /* RDXTREE_RADIX < 6 */
+#error "radix too high"
+#endif /* RDXTREE_RADIX < 6 */
+
+/*
+ * Allocation bitmap size in bits.
+ */
+#define RDXTREE_BM_SIZE (sizeof(rdxtree_bm_t) * CHAR_BIT)
+
+/*
+ * Empty/full allocation bitmap words.
+ */
+#define RDXTREE_BM_EMPTY ((rdxtree_bm_t)0)
+#define RDXTREE_BM_FULL \
+ ((~(rdxtree_bm_t)0) >> (RDXTREE_BM_SIZE - RDXTREE_RADIX_SIZE))
+
+/*
+ * These macros can be replaced by actual functions in an environment
+ * that provides lockless synchronization such as RCU.
+ */
+#define llsync_assign_ptr(ptr, value) ((ptr) = (value))
+#define llsync_read_ptr(ptr) (ptr)
+
+/*
+ * Radix tree node.
+ *
+ * The height of a tree is the number of nodes to traverse until stored
+ * pointers are reached. A height of 0 means the entries of a node (or the
+ * tree root) directly point to stored pointers.
+ *
+ * The index is valid if and only if the parent isn't NULL.
+ *
+ * Concerning the allocation bitmap, a bit is set when the node it denotes,
+ * or one of its children, can be used to allocate an entry. Conversely, a bit
+ * is clear when the matching node and all of its children have no free entry.
+ *
+ * In order to support safe lockless lookups, in particular during a resize,
+ * each node includes the height of its subtree, which is invariant during
+ * the entire node lifetime. Since the tree height does vary, it can't be
+ * used to determine whether the tree root is a node or a stored pointer.
+ * This implementation assumes that all nodes and stored pointers are at least
+ * 4-byte aligned, and uses the least significant bit of entries to indicate
+ * the pointer type. This bit is set for internal nodes, and clear for stored
+ * pointers so that they can be accessed from slots without conversion.
+ */
+struct rdxtree_node {
+ struct rdxtree_node *parent;
+ unsigned int index;
+ unsigned int height;
+ unsigned int nr_entries;
+ rdxtree_bm_t alloc_bm;
+ void *entries[RDXTREE_RADIX_SIZE];
+};
+
+/*
+ * We allocate nodes using the slab allocator.
+ */
+static struct kmem_cache rdxtree_node_cache;
+
+void
+rdxtree_cache_init(void)
+{
+ kmem_cache_init(&rdxtree_node_cache, "rdxtree_node",
+ sizeof(struct rdxtree_node), 0, NULL, NULL, NULL, 0);
+}
+
+#ifdef RDXTREE_ENABLE_NODE_CREATION_FAILURES
+unsigned int rdxtree_fail_node_creation_threshold;
+unsigned int rdxtree_nr_node_creations;
+#endif /* RDXTREE_ENABLE_NODE_CREATION_FAILURES */
+
+static inline int
+rdxtree_check_alignment(const void *ptr)
+{
+ return ((unsigned long)ptr & ~RDXTREE_ENTRY_ADDR_MASK) == 0;
+}
+
+static inline void *
+rdxtree_entry_addr(void *entry)
+{
+ return (void *)((unsigned long)entry & RDXTREE_ENTRY_ADDR_MASK);
+}
+
+static inline int
+rdxtree_entry_is_node(const void *entry)
+{
+ return ((unsigned long)entry & 1) != 0;
+}
+
+static inline void *
+rdxtree_node_to_entry(struct rdxtree_node *node)
+{
+ return (void *)((unsigned long)node | 1);
+}
+
+static int
+rdxtree_node_create(struct rdxtree_node **nodep, unsigned int height)
+{
+ struct rdxtree_node *node;
+
+#ifdef RDXTREE_ENABLE_NODE_CREATION_FAILURES
+ if (rdxtree_fail_node_creation_threshold != 0) {
+ rdxtree_nr_node_creations++;
+
+ if (rdxtree_nr_node_creations == rdxtree_fail_node_creation_threshold)
+ return ERR_NOMEM;
+ }
+#endif /* RDXTREE_ENABLE_NODE_CREATION_FAILURES */
+
+ node = (struct rdxtree_node *) kmem_cache_alloc(&rdxtree_node_cache);
+
+ if (node == NULL)
+ return ERR_NOMEM;
+
+ assert(rdxtree_check_alignment(node));
+ node->parent = NULL;
+ node->height = height;
+ node->nr_entries = 0;
+ node->alloc_bm = RDXTREE_BM_FULL;
+ memset(node->entries, 0, sizeof(node->entries));
+ *nodep = node;
+ return 0;
+}
+
+static void
+rdxtree_node_schedule_destruction(struct rdxtree_node *node)
+{
+ /*
+ * This function is intended to use the appropriate interface to defer
+ * destruction until all read-side references are dropped in an
+ * environment that provides lockless synchronization.
+ *
+ * Otherwise, it simply "schedules" destruction immediately.
+ */
+ kmem_cache_free(&rdxtree_node_cache, (vm_offset_t) node);
+}
+
+static inline void
+rdxtree_node_link(struct rdxtree_node *node, struct rdxtree_node *parent,
+ unsigned int index)
+{
+ node->parent = parent;
+ node->index = index;
+}
+
+static inline void
+rdxtree_node_unlink(struct rdxtree_node *node)
+{
+ assert(node->parent != NULL);
+ node->parent = NULL;
+}
+
+static inline int
+rdxtree_node_full(struct rdxtree_node *node)
+{
+ return (node->nr_entries == ARRAY_SIZE(node->entries));
+}
+
+static inline int
+rdxtree_node_empty(struct rdxtree_node *node)
+{
+ return (node->nr_entries == 0);
+}
+
+static inline void
+rdxtree_node_insert(struct rdxtree_node *node, unsigned int index,
+ void *entry)
+{
+ assert(index < ARRAY_SIZE(node->entries));
+ assert(node->entries[index] == NULL);
+
+ node->nr_entries++;
+ llsync_assign_ptr(node->entries[index], entry);
+}
+
+static inline void
+rdxtree_node_insert_node(struct rdxtree_node *node, unsigned int index,
+ struct rdxtree_node *child)
+{
+ rdxtree_node_insert(node, index, rdxtree_node_to_entry(child));
+}
+
+static inline void
+rdxtree_node_remove(struct rdxtree_node *node, unsigned int index)
+{
+ assert(index < ARRAY_SIZE(node->entries));
+ assert(node->entries[index] != NULL);
+
+ node->nr_entries--;
+ llsync_assign_ptr(node->entries[index], NULL);
+}
+
+static inline void *
+rdxtree_node_find(struct rdxtree_node *node, unsigned int *indexp)
+{
+ unsigned int index;
+ void *ptr;
+
+ index = *indexp;
+
+ while (index < ARRAY_SIZE(node->entries)) {
+ ptr = rdxtree_entry_addr(llsync_read_ptr(node->entries[index]));
+
+ if (ptr != NULL) {
+ *indexp = index;
+ return ptr;
+ }
+
+ index++;
+ }
+
+ return NULL;
+}
+
+static inline void
+rdxtree_node_bm_set(struct rdxtree_node *node, unsigned int index)
+{
+ node->alloc_bm |= (rdxtree_bm_t)1 << index;
+}
+
+static inline void
+rdxtree_node_bm_clear(struct rdxtree_node *node, unsigned int index)
+{
+ node->alloc_bm &= ~((rdxtree_bm_t)1 << index);
+}
+
+static inline int
+rdxtree_node_bm_is_set(struct rdxtree_node *node, unsigned int index)
+{
+ return (node->alloc_bm & ((rdxtree_bm_t)1 << index));
+}
+
+static inline int
+rdxtree_node_bm_empty(struct rdxtree_node *node)
+{
+ return (node->alloc_bm == RDXTREE_BM_EMPTY);
+}
+
+static inline unsigned int
+rdxtree_node_bm_first(struct rdxtree_node *node)
+{
+ return rdxtree_ffs(node->alloc_bm) - 1;
+}
+
+static inline rdxtree_key_t
+rdxtree_max_key(unsigned int height)
+{
+ size_t shift;
+
+ shift = RDXTREE_RADIX * height;
+
+ if (likely(shift < (sizeof(rdxtree_key_t) * CHAR_BIT)))
+ return ((rdxtree_key_t)1 << shift) - 1;
+ else
+ return ~((rdxtree_key_t)0);
+}
+
+static void
+rdxtree_shrink(struct rdxtree *tree)
+{
+ struct rdxtree_node *node;
+ void *entry;
+
+ while (tree->height > 0) {
+ node = rdxtree_entry_addr(tree->root);
+
+ if (node->nr_entries != 1)
+ break;
+
+ entry = node->entries[0];
+
+ if (entry == NULL)
+ break;
+
+ tree->height--;
+
+ if (tree->height > 0)
+ rdxtree_node_unlink(rdxtree_entry_addr(entry));
+
+ llsync_assign_ptr(tree->root, entry);
+ rdxtree_node_schedule_destruction(node);
+ }
+}
+
+static int
+rdxtree_grow(struct rdxtree *tree, rdxtree_key_t key)
+{
+ struct rdxtree_node *root, *node;
+ unsigned int new_height;
+ int error;
+
+ new_height = tree->height + 1;
+
+ while (key > rdxtree_max_key(new_height))
+ new_height++;
+
+ if (tree->root == NULL) {
+ tree->height = new_height;
+ return ERR_SUCCESS;
+ }
+
+ root = rdxtree_entry_addr(tree->root);
+
+ do {
+ error = rdxtree_node_create(&node, tree->height);
+
+ if (error) {
+ rdxtree_shrink(tree);
+ return error;
+ }
+
+ if (tree->height == 0)
+ rdxtree_node_bm_clear(node, 0);
+ else {
+ rdxtree_node_link(root, node, 0);
+
+ if (rdxtree_node_bm_empty(root))
+ rdxtree_node_bm_clear(node, 0);
+ }
+
+ rdxtree_node_insert(node, 0, tree->root);
+ tree->height++;
+ llsync_assign_ptr(tree->root, rdxtree_node_to_entry(node));
+ root = node;
+ } while (new_height > tree->height);
+
+ return ERR_SUCCESS;
+}
+
+static void
+rdxtree_cleanup(struct rdxtree *tree, struct rdxtree_node *node)
+{
+ struct rdxtree_node *prev;
+
+ for (;;) {
+ if (likely(!rdxtree_node_empty(node))) {
+ if (unlikely(node->parent == NULL))
+ rdxtree_shrink(tree);
+
+ break;
+ }
+
+ if (node->parent == NULL) {
+ tree->height = 0;
+ llsync_assign_ptr(tree->root, NULL);
+ rdxtree_node_schedule_destruction(node);
+ break;
+ }
+
+ prev = node;
+ node = node->parent;
+ rdxtree_node_unlink(prev);
+ rdxtree_node_remove(node, prev->index);
+ rdxtree_node_schedule_destruction(prev);
+ }
+}
+
+static void
+rdxtree_insert_bm_clear(struct rdxtree_node *node, unsigned int index)
+{
+ for (;;) {
+ rdxtree_node_bm_clear(node, index);
+
+ if (!rdxtree_node_full(node) || (node->parent == NULL))
+ break;
+
+ index = node->index;
+ node = node->parent;
+ }
+}
+
+int
+rdxtree_insert_common(struct rdxtree *tree, rdxtree_key_t key,
+ void *ptr, void ***slotp)
+{
+ struct rdxtree_node *node, *prev;
+ unsigned int height, shift, index = index;
+ int error;
+
+ assert(ptr != NULL);
+ assert(rdxtree_check_alignment(ptr));
+
+ if (unlikely(key > rdxtree_max_key(tree->height))) {
+ error = rdxtree_grow(tree, key);
+
+ if (error)
+ return error;
+ }
+
+ height = tree->height;
+
+ if (unlikely(height == 0)) {
+ if (tree->root != NULL)
+ return ERR_BUSY;
+
+ llsync_assign_ptr(tree->root, ptr);
+
+ if (slotp != NULL)
+ *slotp = &tree->root;
+
+ return ERR_SUCCESS;
+ }
+
+ node = rdxtree_entry_addr(tree->root);
+ shift = (height - 1) * RDXTREE_RADIX;
+ prev = NULL;
+
+ do {
+ if (node == NULL) {
+ error = rdxtree_node_create(&node, height - 1);
+
+ if (error) {
+ if (prev == NULL)
+ tree->height = 0;
+ else
+ rdxtree_cleanup(tree, prev);
+
+ return error;
+ }
+
+ if (prev == NULL)
+ llsync_assign_ptr(tree->root, rdxtree_node_to_entry(node));
+ else {
+ rdxtree_node_link(node, prev, index);
+ rdxtree_node_insert_node(prev, index, node);
+ }
+ }
+
+ prev = node;
+ index = (unsigned int)(key >> shift) & RDXTREE_RADIX_MASK;
+ node = rdxtree_entry_addr(prev->entries[index]);
+ shift -= RDXTREE_RADIX;
+ height--;
+ } while (height > 0);
+
+ if (unlikely(node != NULL))
+ return ERR_BUSY;
+
+ rdxtree_node_insert(prev, index, ptr);
+ rdxtree_insert_bm_clear(prev, index);
+
+ if (slotp != NULL)
+ *slotp = &prev->entries[index];
+
+ return ERR_SUCCESS;
+}
+
+int
+rdxtree_insert_alloc_common(struct rdxtree *tree, void *ptr,
+ rdxtree_key_t *keyp, void ***slotp)
+{
+ struct rdxtree_node *node, *prev;
+ unsigned int height, shift, index = index;
+ rdxtree_key_t key;
+ int error;
+
+ assert(ptr != NULL);
+ assert(rdxtree_check_alignment(ptr));
+
+ height = tree->height;
+
+ if (unlikely(height == 0)) {
+ if (tree->root == NULL) {
+ llsync_assign_ptr(tree->root, ptr);
+ *keyp = 0;
+
+ if (slotp != NULL)
+ *slotp = &tree->root;
+
+ return ERR_SUCCESS;
+ }
+
+ goto grow;
+ }
+
+ node = rdxtree_entry_addr(tree->root);
+ key = 0;
+ shift = (height - 1) * RDXTREE_RADIX;
+ prev = NULL;
+
+ do {
+ if (node == NULL) {
+ error = rdxtree_node_create(&node, height - 1);
+
+ if (error) {
+ rdxtree_cleanup(tree, prev);
+ return error;
+ }
+
+ rdxtree_node_link(node, prev, index);
+ rdxtree_node_insert_node(prev, index, node);
+ }
+
+ prev = node;
+ index = rdxtree_node_bm_first(node);
+
+ if (index == (unsigned int)-1)
+ goto grow;
+
+ key |= (rdxtree_key_t)index << shift;
+ node = rdxtree_entry_addr(node->entries[index]);
+ shift -= RDXTREE_RADIX;
+ height--;
+ } while (height > 0);
+
+ rdxtree_node_insert(prev, index, ptr);
+ rdxtree_insert_bm_clear(prev, index);
+
+ if (slotp != NULL)
+ *slotp = &prev->entries[index];
+
+ goto out;
+
+grow:
+ key = rdxtree_max_key(height) + 1;
+ error = rdxtree_insert_common(tree, key, ptr, slotp);
+
+ if (error)
+ return error;
+
+out:
+ *keyp = key;
+ return ERR_SUCCESS;
+}
+
+static void
+rdxtree_remove_bm_set(struct rdxtree_node *node, unsigned int index)
+{
+ do {
+ rdxtree_node_bm_set(node, index);
+
+ if (node->parent == NULL)
+ break;
+
+ index = node->index;
+ node = node->parent;
+ } while (!rdxtree_node_bm_is_set(node, index));
+}
+
+void *
+rdxtree_remove(struct rdxtree *tree, rdxtree_key_t key)
+{
+ struct rdxtree_node *node, *prev;
+ unsigned int height, shift, index;
+
+ height = tree->height;
+
+ if (unlikely(key > rdxtree_max_key(height)))
+ return NULL;
+
+ node = rdxtree_entry_addr(tree->root);
+
+ if (unlikely(height == 0)) {
+ llsync_assign_ptr(tree->root, NULL);
+ return node;
+ }
+
+ shift = (height - 1) * RDXTREE_RADIX;
+
+ do {
+ if (node == NULL)
+ return NULL;
+
+ prev = node;
+ index = (unsigned int)(key >> shift) & RDXTREE_RADIX_MASK;
+ node = rdxtree_entry_addr(node->entries[index]);
+ shift -= RDXTREE_RADIX;
+ height--;
+ } while (height > 0);
+
+ if (node == NULL)
+ return NULL;
+
+ rdxtree_node_remove(prev, index);
+ rdxtree_remove_bm_set(prev, index);
+ rdxtree_cleanup(tree, prev);
+ return node;
+}
+
+void *
+rdxtree_lookup_common(const struct rdxtree *tree, rdxtree_key_t key,
+ int get_slot)
+{
+ struct rdxtree_node *node, *prev;
+ unsigned int height, shift, index;
+ void *entry;
+
+ entry = llsync_read_ptr(tree->root);
+
+ if (entry == NULL) {
+ node = NULL;
+ height = 0;
+ } else {
+ node = rdxtree_entry_addr(entry);
+ height = rdxtree_entry_is_node(entry) ? node->height + 1 : 0;
+ }
+
+ if (key > rdxtree_max_key(height))
+ return NULL;
+
+ if (height == 0) {
+ if (node == NULL)
+ return NULL;
+
+ return get_slot ? (void *)&tree->root : node;
+ }
+
+ shift = (height - 1) * RDXTREE_RADIX;
+
+ do {
+ if (node == NULL)
+ return NULL;
+
+ prev = node;
+ index = (unsigned int)(key >> shift) & RDXTREE_RADIX_MASK;
+ entry = llsync_read_ptr(node->entries[index]);
+ node = rdxtree_entry_addr(entry);
+ shift -= RDXTREE_RADIX;
+ height--;
+ } while (height > 0);
+
+ if (node == NULL)
+ return NULL;
+
+ return get_slot ? (void *)&prev->entries[index] : node;
+}
+
+void *
+rdxtree_replace_slot(void **slot, void *ptr)
+{
+ void *old;
+
+ assert(ptr != NULL);
+ assert(rdxtree_check_alignment(ptr));
+
+ old = *slot;
+ assert(old != NULL);
+ assert(rdxtree_check_alignment(old));
+ llsync_assign_ptr(*slot, ptr);
+ return old;
+}
+
+static void *
+rdxtree_walk_next(struct rdxtree *tree, struct rdxtree_iter *iter)
+{
+ struct rdxtree_node *root, *node, *prev;
+ unsigned int height, shift, index, orig_index;
+ rdxtree_key_t key;
+ void *entry;
+
+ entry = llsync_read_ptr(tree->root);
+
+ if (entry == NULL)
+ return NULL;
+
+ if (!rdxtree_entry_is_node(entry)) {
+ if (iter->key != (rdxtree_key_t)-1)
+ return NULL;
+ else {
+ iter->key = 0;
+ return rdxtree_entry_addr(entry);
+ }
+ }
+
+ key = iter->key + 1;
+
+ if ((key == 0) && (iter->node != NULL))
+ return NULL;
+
+ root = rdxtree_entry_addr(entry);
+
+restart:
+ node = root;
+ height = root->height + 1;
+
+ if (key > rdxtree_max_key(height))
+ return NULL;
+
+ shift = (height - 1) * RDXTREE_RADIX;
+
+ do {
+ prev = node;
+ index = (key >> shift) & RDXTREE_RADIX_MASK;
+ orig_index = index;
+ node = rdxtree_node_find(node, &index);
+
+ if (node == NULL) {
+ shift += RDXTREE_RADIX;
+ key = ((key >> shift) + 1) << shift;
+
+ if (key == 0)
+ return NULL;
+
+ goto restart;
+ }
+
+ if (orig_index != index)
+ key = ((key >> shift) + (index - orig_index)) << shift;
+
+ shift -= RDXTREE_RADIX;
+ height--;
+ } while (height > 0);
+
+ iter->node = prev;
+ iter->key = key;
+ return node;
+}
+
+void *
+rdxtree_walk(struct rdxtree *tree, struct rdxtree_iter *iter)
+{
+ unsigned int index, orig_index;
+ void *ptr;
+
+ if (iter->node == NULL)
+ return rdxtree_walk_next(tree, iter);
+
+ index = (iter->key + 1) & RDXTREE_RADIX_MASK;
+
+ if (index != 0) {
+ orig_index = index;
+ ptr = rdxtree_node_find(iter->node, &index);
+
+ if (ptr != NULL) {
+ iter->key += (index - orig_index) + 1;
+ return ptr;
+ }
+ }
+
+ return rdxtree_walk_next(tree, iter);
+}
+
+void
+rdxtree_remove_all(struct rdxtree *tree)
+{
+ struct rdxtree_node *node, *parent;
+ struct rdxtree_iter iter;
+
+ if (tree->height == 0) {
+ if (tree->root != NULL)
+ llsync_assign_ptr(tree->root, NULL);
+
+ return;
+ }
+
+ for (;;) {
+ rdxtree_iter_init(&iter);
+ rdxtree_walk_next(tree, &iter);
+
+ if (iter.node == NULL)
+ break;
+
+ node = iter.node;
+ parent = node->parent;
+
+ if (parent == NULL)
+ rdxtree_init(tree);
+ else {
+ rdxtree_node_remove(parent, node->index);
+ rdxtree_remove_bm_set(parent, node->index);
+ rdxtree_cleanup(tree, parent);
+ node->parent = NULL;
+ }
+
+ rdxtree_node_schedule_destruction(node);
+ }
+}
diff --git a/kern/rdxtree.h b/kern/rdxtree.h
new file mode 100644
index 00000000..1f8456e0
--- /dev/null
+++ b/kern/rdxtree.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2011-2015 Richard Braun.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Radix tree.
+ *
+ * In addition to the standard insertion operation, this implementation
+ * can allocate keys for the caller at insertion time.
+ *
+ * Upstream site with license notes :
+ * http://git.sceen.net/rbraun/librbraun.git/
+ */
+
+#ifndef _RDXTREE_H
+#define _RDXTREE_H
+
+#include <stddef.h>
+#include <sys/types.h>
+
+/*
+ * Initialize the node cache.
+ */
+void rdxtree_cache_init(void);
+
+/*
+ * This macro selects between 32 or 64-bits (the default) keys.
+ */
+#if 0
+#define RDXTREE_KEY_32
+#endif
+
+#ifdef RDXTREE_KEY_32
+typedef uint32_t rdxtree_key_t;
+#else /* RDXTREE_KEY_32 */
+typedef uint64_t rdxtree_key_t;
+#endif /* RDXTREE_KEY_32 */
+
+/*
+ * Radix tree.
+ */
+struct rdxtree;
+
+/*
+ * Radix tree iterator.
+ */
+struct rdxtree_iter;
+
+/*
+ * Static tree initializer.
+ */
+#define RDXTREE_INITIALIZER { 0, NULL }
+
+#include "rdxtree_i.h"
+
+/*
+ * Initialize a tree.
+ */
+static inline void
+rdxtree_init(struct rdxtree *tree)
+{
+ tree->height = 0;
+ tree->root = NULL;
+}
+
+/*
+ * Insert a pointer in a tree.
+ *
+ * The ptr parameter must not be NULL.
+ */
+static inline int
+rdxtree_insert(struct rdxtree *tree, rdxtree_key_t key, void *ptr)
+{
+ return rdxtree_insert_common(tree, key, ptr, NULL);
+}
+
+/*
+ * Insert a pointer in a tree and obtain its slot.
+ *
+ * The ptr and slotp parameters must not be NULL. If successful, the slot of
+ * the newly inserted pointer is stored at the address pointed to by the slotp
+ * parameter.
+ */
+static inline int
+rdxtree_insert_slot(struct rdxtree *tree, rdxtree_key_t key,
+ void *ptr, void ***slotp)
+{
+ return rdxtree_insert_common(tree, key, ptr, slotp);
+}
+
+/*
+ * Insert a pointer in a tree, for which a new key is allocated.
+ *
+ * The ptr and keyp parameters must not be NULL. The newly allocated key is
+ * stored at the address pointed to by the keyp parameter.
+ */
+static inline int
+rdxtree_insert_alloc(struct rdxtree *tree, void *ptr, rdxtree_key_t *keyp)
+{
+ return rdxtree_insert_alloc_common(tree, ptr, keyp, NULL);
+}
+
+/*
+ * Insert a pointer in a tree, for which a new key is allocated, and obtain
+ * its slot.
+ *
+ * The ptr, keyp and slotp parameters must not be NULL. The newly allocated
+ * key is stored at the address pointed to by the keyp parameter while the
+ * slot of the inserted pointer is stored at the address pointed to by the
+ * slotp parameter.
+ */
+static inline int
+rdxtree_insert_alloc_slot(struct rdxtree *tree, void *ptr,
+ rdxtree_key_t *keyp, void ***slotp)
+{
+ return rdxtree_insert_alloc_common(tree, ptr, keyp, slotp);
+}
+
+/*
+ * Remove a pointer from a tree.
+ *
+ * The matching pointer is returned if successful, NULL otherwise.
+ */
+void * rdxtree_remove(struct rdxtree *tree, rdxtree_key_t key);
+
+/*
+ * Look up a pointer in a tree.
+ *
+ * The matching pointer is returned if successful, NULL otherwise.
+ */
+static inline void *
+rdxtree_lookup(const struct rdxtree *tree, rdxtree_key_t key)
+{
+ return rdxtree_lookup_common(tree, key, 0);
+}
+
+/*
+ * Look up a slot in a tree.
+ *
+ * A slot is a pointer to a stored pointer in a tree. It can be used as
+ * a placeholder for fast replacements to avoid multiple lookups on the same
+ * key.
+ *
+ * A slot for the matching pointer is returned if successful, NULL otherwise.
+ *
+ * See rdxtree_replace_slot().
+ */
+static inline void **
+rdxtree_lookup_slot(const struct rdxtree *tree, rdxtree_key_t key)
+{
+ return rdxtree_lookup_common(tree, key, 1);
+}
+
+/*
+ * Replace a pointer in a tree.
+ *
+ * The ptr parameter must not be NULL. The previous pointer is returned.
+ *
+ * See rdxtree_lookup_slot().
+ */
+void * rdxtree_replace_slot(void **slot, void *ptr);
+
+/*
+ * Forge a loop to process all pointers of a tree.
+ */
+#define rdxtree_for_each(tree, iter, ptr) \
+for (rdxtree_iter_init(iter), ptr = rdxtree_walk(tree, iter); \
+ ptr != NULL; \
+ ptr = rdxtree_walk(tree, iter))
+
+/*
+ * Return the key of the current pointer from an iterator.
+ */
+static inline rdxtree_key_t
+rdxtree_iter_key(const struct rdxtree_iter *iter)
+{
+ return iter->key;
+}
+
+/*
+ * Remove all pointers from a tree.
+ *
+ * The common way to destroy a tree and its pointers is to loop over all
+ * the pointers using rdxtree_for_each(), freeing them, then call this
+ * function.
+ */
+void rdxtree_remove_all(struct rdxtree *tree);
+
+#endif /* _RDXTREE_H */
diff --git a/kern/rdxtree_i.h b/kern/rdxtree_i.h
new file mode 100644
index 00000000..1bd1f64a
--- /dev/null
+++ b/kern/rdxtree_i.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2013-2015 Richard Braun.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * Upstream site with license notes :
+ * http://git.sceen.net/rbraun/librbraun.git/
+ */
+
+#ifndef _RDXTREE_I_H
+#define _RDXTREE_I_H
+
+/*
+ * Radix tree.
+ */
+struct rdxtree {
+ unsigned int height;
+ void *root;
+};
+
+/*
+ * Radix tree iterator.
+ *
+ * The node member refers to the node containing the current pointer, if any.
+ * The key member refers to the current pointer, and is valid if and only if
+ * rdxtree_walk() has been called at least once on the iterator.
+ */
+struct rdxtree_iter {
+ void *node;
+ rdxtree_key_t key;
+};
+
+/*
+ * Initialize an iterator.
+ */
+static inline void
+rdxtree_iter_init(struct rdxtree_iter *iter)
+{
+ iter->node = NULL;
+ iter->key = (rdxtree_key_t)-1;
+}
+
+int rdxtree_insert_common(struct rdxtree *tree, rdxtree_key_t key,
+ void *ptr, void ***slotp);
+
+int rdxtree_insert_alloc_common(struct rdxtree *tree, void *ptr,
+ rdxtree_key_t *keyp, void ***slotp);
+
+void * rdxtree_lookup_common(const struct rdxtree *tree, rdxtree_key_t key,
+ int get_slot);
+
+void * rdxtree_walk(struct rdxtree *tree, struct rdxtree_iter *iter);
+
+#endif /* _RDXTREE_I_H */
diff --git a/kern/refcount.h b/kern/refcount.h
index 7fd6cdfb..f32feb87 100644
--- a/kern/refcount.h
+++ b/kern/refcount.h
@@ -27,9 +27,7 @@
#ifndef _KERN_REFCOUNT_H_
#define _KERN_REFCOUNT_H_
-#include <kern/macro_help.h>
-
-#include "refcount.h" /*XXX*/
+#include <kern/macros.h>
/* Unless the above include file specified otherwise,
use the system-independent (unoptimized) atomic reference counter. */
@@ -65,6 +63,6 @@ typedef struct RefCount RefCount;
if (new_value == 0) { func; } \
MACRO_END
-#endif
+#endif /* MACHINE_REFCOUNT */
-#endif _KERN_REFCOUNT_H_
+#endif /* _KERN_REFCOUNT_H_ */
diff --git a/kern/sched.h b/kern/sched.h
index 434e0228..f82f9f56 100644
--- a/kern/sched.h
+++ b/kern/sched.h
@@ -38,7 +38,7 @@
#include <kern/queue.h>
#include <kern/lock.h>
#include <kern/kern_types.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#if MACH_FIXPRI
#include <mach/policy.h>
@@ -60,7 +60,7 @@
#include <machine/sched_param.h>
#endif /* STAT_TIME */
-#define NRQS 32 /* 32 run queues per cpu */
+#define NRQS 50 /* 50 run queues per cpu */
struct run_queue {
queue_head_t runq[NRQS]; /* one for each priority */
@@ -118,7 +118,7 @@ extern int min_quantum; /* defines max context switch rate */
* Default base priorities for threads.
*/
#define BASEPRI_SYSTEM 6
-#define BASEPRI_USER 12
+#define BASEPRI_USER 25
/*
* Macro to check for invalid priorities.
@@ -153,7 +153,7 @@ extern unsigned sched_tick;
#define thread_timer_delta(thread) \
MACRO_BEGIN \
- register unsigned delta; \
+ unsigned delta; \
\
delta = 0; \
TIMER_DELTA((thread)->system_timer, \
diff --git a/kern/sched_prim.c b/kern/sched_prim.c
index ba2dc8ab..e8f260e3 100644
--- a/kern/sched_prim.c
+++ b/kern/sched_prim.c
@@ -44,7 +44,7 @@
#include <kern/lock.h>
#include <kern/mach_clock.h>
#include <kern/mach_factor.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#include <kern/processor.h>
#include <kern/queue.h>
#include <kern/sched.h>
@@ -70,18 +70,8 @@ int sched_usec;
thread_t sched_thread_id;
-void set_pri(thread_t, int, boolean_t);
-void do_thread_scan(void);
-
-thread_t choose_pset_thread();
-
timer_elt_data_t recompute_priorities_timer;
-#if DEBUG
-void checkrq(run_queue_t, char *);
-void thread_check(thread_t, run_queue_t);
-#endif
-
/*
* State machine
*
@@ -150,7 +140,7 @@ decl_simple_lock_data(, wait_lock[NUMQUEUES])
void wait_queue_init(void)
{
- register int i;
+ int i;
for (i = 0; i < NUMQUEUES; i++) {
queue_init(&wait_queue[i]);
@@ -165,7 +155,7 @@ void sched_init(void)
min_quantum = hz / 10; /* context switch 10 times/second */
wait_queue_init();
- pset_sys_bootstrap(); /* initialize processer mgmt. */
+ pset_sys_bootstrap(); /* initialize processor mgmt. */
queue_init(&action_queue);
simple_lock_init(&action_lock);
sched_tick = 0;
@@ -199,8 +189,8 @@ void thread_timeout(
void thread_set_timeout(
int t) /* timeout interval in ticks */
{
- register thread_t thread = current_thread();
- register spl_t s;
+ thread_t thread = current_thread();
+ spl_t s;
s = splsched();
thread_lock(thread);
@@ -215,7 +205,7 @@ void thread_set_timeout(
* Set up thread timeout element when thread is created.
*/
void thread_timeout_setup(
- register thread_t thread)
+ thread_t thread)
{
thread->timer.fcn = thread_timeout;
thread->timer.param = thread;
@@ -233,12 +223,10 @@ void assert_wait(
event_t event,
boolean_t interruptible)
{
- register queue_t q;
- register int index;
- register thread_t thread;
-#if MACH_SLOCKS
- register simple_lock_t lock;
-#endif /* MACH_SLOCKS */
+ queue_t q;
+ int index;
+ thread_t thread;
+ decl_simple_lock_data( , *lock);
spl_t s;
thread = current_thread();
@@ -250,12 +238,10 @@ void assert_wait(
if (event != 0) {
index = wait_hash(event);
q = &wait_queue[index];
-#if MACH_SLOCKS
lock = &wait_lock[index];
-#endif /* MACH_SLOCKS */
simple_lock(lock);
thread_lock(thread);
- enqueue_tail(q, (queue_entry_t) thread);
+ enqueue_tail(q, &(thread->links));
thread->wait_event = event;
if (interruptible)
thread->state |= TH_WAIT;
@@ -288,16 +274,14 @@ void assert_wait(
* interruptible.
*/
void clear_wait(
- register thread_t thread,
+ thread_t thread,
int result,
boolean_t interrupt_only)
{
- register int index;
- register queue_t q;
-#if MACH_SLOCKS
- register simple_lock_t lock;
-#endif /* MACH_SLOCKS */
- register event_t event;
+ int index;
+ queue_t q;
+ decl_simple_lock_data( , *lock);
+ event_t event;
spl_t s;
s = splsched();
@@ -316,9 +300,7 @@ void clear_wait(
thread_unlock(thread);
index = wait_hash(event);
q = &wait_queue[index];
-#if MACH_SLOCKS
lock = &wait_lock[index];
-#endif /* MACH_SLOCKS */
simple_lock(lock);
/*
* If the thread is still waiting on that event,
@@ -335,7 +317,7 @@ void clear_wait(
simple_unlock(lock);
}
if (event == 0) {
- register int state = thread->state;
+ int state = thread->state;
reset_timeout_check(&thread->timer);
@@ -376,7 +358,7 @@ void clear_wait(
}
static inline void __attribute__((noreturn))
-state_panic(thread_t thread, const char *caller)
+state_panic(const thread_t thread, const char *caller)
{
panic ("%s: thread %x has unexpected state %x",
caller, thread, thread->state);
@@ -394,21 +376,17 @@ void thread_wakeup_prim(
boolean_t one_thread,
int result)
{
- register queue_t q;
- register int index;
- register thread_t thread, next_th;
-#if MACH_SLOCKS
- register simple_lock_t lock;
-#endif /* MACH_SLOCKS */
+ queue_t q;
+ int index;
+ thread_t thread, next_th;
+ decl_simple_lock_data( , *lock);
spl_t s;
- register int state;
+ int state;
index = wait_hash(event);
q = &wait_queue[index];
s = splsched();
-#if MACH_SLOCKS
lock = &wait_lock[index];
-#endif /* MACH_SLOCKS */
simple_lock(lock);
thread = (thread_t) queue_first(q);
while (!queue_end(q, (queue_entry_t)thread)) {
@@ -490,8 +468,8 @@ void thread_sleep(
* xxx - DO NOT export this to users.
*/
void thread_bind(
- register thread_t thread,
- processor_t processor)
+ thread_t thread,
+ processor_t processor)
{
spl_t s;
@@ -509,9 +487,9 @@ void thread_bind(
*/
thread_t thread_select(
- register processor_t myprocessor)
+ processor_t myprocessor)
{
- register thread_t thread;
+ thread_t thread;
myprocessor->first_quantum = TRUE;
/*
@@ -523,7 +501,7 @@ thread_t thread_select(
myprocessor->quantum = min_quantum;
}
else {
- register processor_set_t pset;
+ processor_set_t pset;
#if MACH_HOST
pset = myprocessor->processor_set;
@@ -559,7 +537,7 @@ thread_t thread_select(
}
}
else {
- register queue_t q;
+ queue_t q;
/*
* If there is a thread at hint, grab it,
@@ -622,9 +600,9 @@ thread_t thread_select(
*/
boolean_t thread_invoke(
- register thread_t old_thread,
- continuation_t continuation,
- register thread_t new_thread)
+ thread_t old_thread,
+ continuation_t continuation,
+ thread_t new_thread)
{
/*
* Check for invoking the same thread.
@@ -637,7 +615,7 @@ boolean_t thread_invoke(
thread_lock(new_thread);
new_thread->state &= ~TH_UNINT;
thread_unlock(new_thread);
- thread_wakeup(&new_thread->state);
+ thread_wakeup(TH_EV_STATE(new_thread));
if (continuation != (void (*)()) 0) {
(void) spl0();
@@ -659,7 +637,7 @@ boolean_t thread_invoke(
new_thread->state &= ~(TH_SWAPPED | TH_UNINT);
thread_unlock(new_thread);
- thread_wakeup(&new_thread->state);
+ thread_wakeup(TH_EV_STATE(new_thread));
#if NCPUS > 1
new_thread->last_processor = current_processor();
@@ -698,7 +676,7 @@ boolean_t thread_invoke(
if (old_thread->wake_active) {
old_thread->wake_active = FALSE;
thread_unlock(old_thread);
- thread_wakeup((event_t)&old_thread->wake_active);
+ thread_wakeup(TH_EV_WAKE_ACTIVE(old_thread));
goto after_old_thread;
}
@@ -748,7 +726,7 @@ boolean_t thread_invoke(
* running out of stack.
*/
- counter_always(c_thread_invoke_hits++);
+ counter(c_thread_invoke_hits++);
(void) spl0();
call_continuation(new_thread->swap_func);
/*NOTREACHED*/
@@ -760,7 +738,7 @@ boolean_t thread_invoke(
*/
thread_swapin(new_thread);
thread_unlock(new_thread);
- counter_always(c_thread_invoke_misses++);
+ counter(c_thread_invoke_misses++);
return FALSE;
case 0:
@@ -781,7 +759,7 @@ boolean_t thread_invoke(
{
thread_swapin(new_thread);
thread_unlock(new_thread);
- counter_always(c_thread_invoke_misses++);
+ counter(c_thread_invoke_misses++);
return FALSE;
}
}
@@ -789,7 +767,7 @@ boolean_t thread_invoke(
new_thread->state &= ~(TH_SWAPPED | TH_UNINT);
thread_unlock(new_thread);
- thread_wakeup(&new_thread->state);
+ thread_wakeup(TH_EV_STATE(new_thread));
/*
* Thread is now interruptible.
@@ -810,7 +788,7 @@ boolean_t thread_invoke(
* changing address spaces. It updates active_threads.
* It returns only if a continuation is not supplied.
*/
- counter_always(c_thread_invoke_csw++);
+ counter(c_thread_invoke_csw++);
old_thread = switch_context(old_thread, continuation, new_thread);
/*
@@ -829,9 +807,9 @@ boolean_t thread_invoke(
* Called at splsched.
*/
void thread_continue(
- register thread_t old_thread)
+ thread_t old_thread)
{
- register continuation_t continuation = current_thread()->swap_func;
+ continuation_t continuation = current_thread()->swap_func;
/*
* We must dispatch the old thread and then
@@ -865,9 +843,9 @@ void thread_continue(
void thread_block(
continuation_t continuation)
{
- register thread_t thread = current_thread();
- register processor_t myprocessor = cpu_to_processor(cpu_number());
- register thread_t new_thread;
+ thread_t thread = current_thread();
+ processor_t myprocessor = cpu_to_processor(cpu_number());
+ thread_t new_thread;
spl_t s;
check_simple_locks();
@@ -906,10 +884,10 @@ void thread_block(
*/
void thread_run(
continuation_t continuation,
- register thread_t new_thread)
+ thread_t new_thread)
{
- register thread_t thread = current_thread();
- register processor_t myprocessor = cpu_to_processor(cpu_number());
+ thread_t thread = current_thread();
+ processor_t myprocessor = cpu_to_processor(cpu_number());
spl_t s;
check_simple_locks();
@@ -928,7 +906,7 @@ void thread_run(
*/
void thread_dispatch(
- register thread_t thread)
+ thread_t thread)
{
/*
* If we are discarding the thread's stack, we must do it
@@ -954,7 +932,7 @@ void thread_dispatch(
if (thread->wake_active) {
thread->wake_active = FALSE;
thread_unlock(thread);
- thread_wakeup((event_t)&thread->wake_active);
+ thread_wakeup(TH_EV_WAKE_ACTIVE(thread));
return;
}
break;
@@ -1020,7 +998,7 @@ shift_data_t wait_shift[32] = {
(pri) = (th)->priority /* start with base priority */ \
+ ((th)->sched_usage >> (PRI_SHIFT + SCHED_SHIFT)) \
+ ((th)->sched_usage >> (PRI_SHIFT_2 + SCHED_SHIFT)); \
- if ((pri) > 31) (pri) = 31; \
+ if ((pri) > NRQS - 1) (pri) = NRQS - 1; \
MACRO_END
#else /* PRI_SHIFT_2 */
#define do_priority_computation(th, pri) \
@@ -1028,7 +1006,7 @@ shift_data_t wait_shift[32] = {
(pri) = (th)->priority /* start with base priority */ \
+ ((th)->sched_usage >> (PRI_SHIFT + SCHED_SHIFT)) \
- ((th)->sched_usage >> (SCHED_SHIFT - PRI_SHIFT_2)); \
- if ((pri) > 31) (pri) = 31; \
+ if ((pri) > NRQS - 1) (pri) = NRQS - 1; \
MACRO_END
#endif /* PRI_SHIFT_2 */
#else /* defined(PRI_SHIFT_2) */
@@ -1036,7 +1014,7 @@ shift_data_t wait_shift[32] = {
MACRO_BEGIN \
(pri) = (th)->priority /* start with base priority */ \
+ ((th)->sched_usage >> (PRI_SHIFT + SCHED_SHIFT)); \
- if ((pri) > 31) (pri) = 31; \
+ if ((pri) > NRQS - 1) (pri) = NRQS - 1; \
MACRO_END
#endif /* defined(PRI_SHIFT_2) */
@@ -1053,10 +1031,10 @@ shift_data_t wait_shift[32] = {
*/
void compute_priority(
- register thread_t thread,
+ thread_t thread,
boolean_t resched)
{
- register int pri;
+ int pri;
#if MACH_FIXPRI
if (thread->policy == POLICY_TIMESHARE) {
@@ -1085,9 +1063,9 @@ void compute_priority(
*/
void compute_my_priority(
- register thread_t thread)
+ thread_t thread)
{
- register int temp_pri;
+ int temp_pri;
do_priority_computation(thread,temp_pri);
thread->sched_pri = temp_pri;
@@ -1132,11 +1110,11 @@ void recompute_priorities(void *param)
* can only be called by the thread on itself.
*/
void update_priority(
- register thread_t thread)
+ thread_t thread)
{
- register unsigned int ticks;
- register shift_t shiftp;
- register int temp_pri;
+ unsigned int ticks;
+ shift_t shiftp;
+ int temp_pri;
ticks = sched_tick - thread->sched_stamp;
@@ -1196,7 +1174,7 @@ void update_priority(
#if DEBUG
#define run_queue_enqueue(rq, th) \
MACRO_BEGIN \
- register unsigned int whichq; \
+ unsigned int whichq; \
\
whichq = (th)->sched_pri; \
if (whichq >= NRQS) { \
@@ -1206,7 +1184,7 @@ void update_priority(
\
simple_lock(&(rq)->lock); /* lock the run queue */ \
checkrq((rq), "thread_setrun: before adding thread"); \
- enqueue_tail(&(rq)->runq[whichq], (queue_entry_t) (th)); \
+ enqueue_tail(&(rq)->runq[whichq], &((th)->links)); \
\
if (whichq < (rq)->low || (rq)->count == 0) \
(rq)->low = whichq; /* minimize */ \
@@ -1220,7 +1198,7 @@ void update_priority(
#else /* DEBUG */
#define run_queue_enqueue(rq, th) \
MACRO_BEGIN \
- register unsigned int whichq; \
+ unsigned int whichq; \
\
whichq = (th)->sched_pri; \
if (whichq >= NRQS) { \
@@ -1229,7 +1207,7 @@ void update_priority(
} \
\
simple_lock(&(rq)->lock); /* lock the run queue */ \
- enqueue_tail(&(rq)->runq[whichq], (queue_entry_t) (th)); \
+ enqueue_tail(&(rq)->runq[whichq], &((th)->links)); \
\
if (whichq < (rq)->low || (rq)->count == 0) \
(rq)->low = whichq; /* minimize */ \
@@ -1249,13 +1227,13 @@ void update_priority(
*/
void thread_setrun(
- register thread_t th,
+ thread_t th,
boolean_t may_preempt)
{
- register processor_t processor;
- register run_queue_t rq;
+ processor_t processor;
+ run_queue_t rq;
#if NCPUS > 1
- register processor_set_t pset;
+ processor_set_t pset;
#endif /* NCPUS > 1 */
/*
@@ -1423,7 +1401,7 @@ void set_pri(
int pri,
boolean_t resched)
{
- register struct run_queue *rq;
+ struct run_queue *rq;
rq = rem_runq(th);
th->sched_pri = pri;
@@ -1448,7 +1426,7 @@ void set_pri(
struct run_queue *rem_runq(
thread_t th)
{
- register struct run_queue *rq;
+ struct run_queue *rq;
rq = th->runq;
/*
@@ -1514,10 +1492,10 @@ thread_t choose_thread(
processor_t myprocessor)
{
thread_t th;
- register queue_t q;
- register run_queue_t runq;
- register int i;
- register processor_set_t pset;
+ queue_t q;
+ run_queue_t runq;
+ int i;
+ processor_set_t pset;
runq = &myprocessor->runq;
@@ -1558,13 +1536,13 @@ thread_t choose_thread(
*/
thread_t choose_pset_thread(
- register processor_t myprocessor,
+ processor_t myprocessor,
processor_set_t pset)
{
- register run_queue_t runq;
- register thread_t th;
- register queue_t q;
- register int i;
+ run_queue_t runq;
+ thread_t th;
+ queue_t q;
+ int i;
runq = &pset->runq;
@@ -1640,14 +1618,14 @@ int no_dispatch_count = 0;
* to execute.
*/
-void idle_thread_continue(void)
+void __attribute__((noreturn)) idle_thread_continue(void)
{
- register processor_t myprocessor;
- register volatile thread_t *threadp;
- register volatile int *gcount;
- register volatile int *lcount;
- register thread_t new_thread;
- register int state;
+ processor_t myprocessor;
+ volatile thread_t *threadp;
+ volatile int *gcount;
+ volatile int *lcount;
+ thread_t new_thread;
+ int state;
int mycpu;
spl_t s;
@@ -1746,7 +1724,7 @@ retry:
thread_run(idle_thread_continue, new_thread);
}
else if (state == PROCESSOR_IDLE) {
- register processor_set_t pset;
+ processor_set_t pset;
pset = myprocessor->processor_set;
simple_lock(&pset->idle_lock);
@@ -1797,14 +1775,14 @@ retry:
void idle_thread(void)
{
- register thread_t self = current_thread();
+ thread_t self = current_thread();
spl_t s;
stack_privilege(self);
s = splsched();
- self->priority = 31;
- self->sched_pri = 31;
+ self->priority = NRQS-1;
+ self->sched_pri = NRQS-1;
/*
* Set the idle flag to indicate that this is an idle thread,
@@ -1900,10 +1878,10 @@ boolean_t
do_runq_scan(
run_queue_t runq)
{
- register spl_t s;
- register queue_t q;
- register thread_t thread;
- register int count;
+ spl_t s;
+ queue_t q;
+ thread_t thread;
+ int count;
s = splsched();
simple_lock(&runq->lock);
@@ -1964,11 +1942,11 @@ if (do_thread_scan_debug)
void do_thread_scan(void)
{
- register spl_t s;
- register boolean_t restart_needed = 0;
- register thread_t thread;
+ spl_t s;
+ boolean_t restart_needed = 0;
+ thread_t thread;
#if MACH_HOST
- register processor_set_t pset;
+ processor_set_t pset;
#endif /* MACH_HOST */
do {
@@ -2012,12 +1990,12 @@ void do_thread_scan(void)
#if DEBUG
void checkrq(
run_queue_t rq,
- char *msg)
+ const char *msg)
{
- register queue_t q1;
- register int i, j;
- register queue_entry_t e;
- register int low;
+ queue_t q1;
+ int i, j;
+ queue_entry_t e;
+ int low;
low = -1;
j = 0;
@@ -2048,10 +2026,10 @@ void checkrq(
}
void thread_check(
- register thread_t th,
- register run_queue_t rq)
+ thread_t th,
+ run_queue_t rq)
{
- register unsigned int whichq;
+ unsigned int whichq;
whichq = th->sched_pri;
if (whichq >= NRQS) {
diff --git a/kern/sched_prim.h b/kern/sched_prim.h
index 5311d160..62698dc2 100644
--- a/kern/sched_prim.h
+++ b/kern/sched_prim.h
@@ -69,7 +69,7 @@ extern void thread_sleep(
event_t event,
simple_lock_t lock,
boolean_t interruptible);
-extern void thread_wakeup(); /* for function pointers */
+extern void thread_wakeup(void); /* for function pointers */
extern void thread_wakeup_prim(
event_t event,
boolean_t one_thread,
@@ -103,7 +103,7 @@ extern boolean_t thread_handoff(
thread_t old_thread,
continuation_t continuation,
thread_t new_thread);
-extern void recompute_priorities();
+extern void recompute_priorities(void *param);
extern void update_priority(
thread_t thread);
extern void compute_my_priority(
@@ -115,7 +115,7 @@ extern void compute_priority(
thread_t thread,
boolean_t resched);
extern void thread_timeout_setup(
- register thread_t thread);
+ thread_t thread);
/*
* Routines defined as macros
@@ -132,13 +132,10 @@ extern void thread_timeout_setup(
* Machine-dependent code must define these functions.
*/
-extern void thread_bootstrap_return(void);
-extern void thread_exception_return(void);
-#ifdef __GNUC__
+extern void thread_bootstrap_return(void) __attribute__((noreturn));
+extern void thread_exception_return(void) __attribute__((noreturn));
extern void __attribute__((__noreturn__)) thread_syscall_return(kern_return_t);
-#else
-extern void thread_syscall_return(kern_return_t);
-#endif
+
extern thread_t switch_context(
thread_t old_thread,
continuation_t continuation,
@@ -153,7 +150,7 @@ extern void stack_handoff(
* or are defined directly by machine-dependent code.
*/
-extern void stack_alloc(
+extern kern_return_t stack_alloc(
thread_t thread,
void (*resume)(thread_t));
extern boolean_t stack_alloc_try(
@@ -172,4 +169,16 @@ extern void stack_free(
#define convert_ipc_timeout_to_ticks(millis) \
(((millis) * hz + 999) / 1000)
+void set_pri(thread_t th, int pri, boolean_t resched);
+void do_thread_scan(void);
+thread_t choose_pset_thread(processor_t myprocessor, processor_set_t pset);
+
+#if DEBUG
+void checkrq(run_queue_t rq, char *msg);
+void thread_check(thread_t th, run_queue_t rq);
+#endif /* DEBUG */
+
+extern void idle_thread(void) __attribute__((noreturn));
+extern void sched_thread(void);
+
#endif /* _KERN_SCHED_PRIM_H_ */
diff --git a/kern/server_loop.ch b/kern/server_loop.ch
deleted file mode 100644
index 409e013d..00000000
--- a/kern/server_loop.ch
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: kern/server_loop.c
- *
- * A common server loop for builtin tasks.
- */
-
-/*
- * Must define symbols for:
- * SERVER_NAME String name of this module
- * SERVER_LOOP Routine name for the loop
- * SERVER_DISPATCH MiG function(s) to handle message
- *
- * Must redefine symbols for pager_server functions.
- */
-
-#include <kern/debug.h>
-#include <kern/kalloc.h>
-#include <mach/port.h>
-#include <mach/message.h>
-#include <vm/vm_kern.h> /* for kernel_map */
-
-void SERVER_LOOP(rcv_set, max_size)
-{
- register mach_msg_header_t *in_msg;
- register mach_msg_header_t *out_msg;
- register mach_msg_header_t *tmp_msg;
- vm_offset_t messages;
- mach_msg_return_t r;
-
- /*
- * Allocate our message buffers.
- */
-
- messages = kalloc(2 * max_size);
- if (messages == 0)
- panic(SERVER_NAME);
- in_msg = (mach_msg_header_t *) messages;
- out_msg = (mach_msg_header_t *) (messages + max_size);
-
- /*
- * Service loop... receive messages and process them.
- */
-
- for (;;) {
- /* receive first message */
-
- receive_msg:
- r = mach_msg(in_msg, MACH_RCV_MSG, 0, max_size, rcv_set,
- MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
- if (r == MACH_MSG_SUCCESS)
- break;
-
- printf("%s: receive failed, 0x%x.\n", SERVER_NAME, r);
- }
-
- for (;;) {
- /* process request message */
-
- (void) SERVER_DISPATCH(in_msg, out_msg);
-
- /* send reply and receive next request */
-
- if (out_msg->msgh_remote_port == MACH_PORT_NULL)
- goto receive_msg;
-
- r = mach_msg(out_msg, MACH_SEND_MSG|MACH_RCV_MSG,
- out_msg->msgh_size, max_size, rcv_set,
- MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
- if (r != MACH_MSG_SUCCESS) {
- printf("%s: send/receive failed, 0x%x.\n",
- SERVER_NAME, r);
- goto receive_msg;
- }
-
- /* swap message buffers */
-
- tmp_msg = in_msg; in_msg = out_msg; out_msg = tmp_msg;
- }
-}
diff --git a/kern/shuttle.h b/kern/shuttle.h
index e8e574b6..0b1c2c5e 100644
--- a/kern/shuttle.h
+++ b/kern/shuttle.h
@@ -68,4 +68,4 @@ typedef struct Shuttle Shuttle;
-#endif _KERN_SHUTTLE_H_
+#endif /* _KERN_SHUTTLE_H_ */
diff --git a/kern/slab.c b/kern/slab.c
index 99d5bca3..1114cfa3 100644
--- a/kern/slab.c
+++ b/kern/slab.c
@@ -79,6 +79,7 @@
#include <string.h>
#include <kern/assert.h>
#include <kern/mach_clock.h>
+#include <kern/macros.h>
#include <kern/printf.h>
#include <kern/slab.h>
#include <kern/kalloc.h>
@@ -96,7 +97,6 @@
/*
* Utility macros.
*/
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define P2ALIGNED(x, a) (((x) & ((a) - 1)) == 0)
#define ISP2(x) P2ALIGNED(x, x)
#define P2ALIGN(x, a) ((x) & -(a))
@@ -165,7 +165,7 @@
/*
* Size of the VM submap from which default backend functions allocate.
*/
-#define KMEM_MAP_SIZE (128 * 1024 * 1024)
+#define KMEM_MAP_SIZE (96 * 1024 * 1024)
/*
* Shift for the first kalloc cache size.
@@ -289,8 +289,8 @@ vm_map_t kmem_map = &kmem_map_store;
static unsigned long kmem_gc_last_tick;
#define kmem_error(format, ...) \
- printf("mem: error: %s(): " format "\n", __func__, \
- ## __VA_ARGS__)
+ panic("mem: error: %s(): " format "\n", __func__, \
+ ## __VA_ARGS__)
#define kmem_warn(format, ...) \
printf("mem: warning: %s(): " format "\n", __func__, \
@@ -615,18 +615,24 @@ static inline void kmem_cpu_pool_push(struct kmem_cpu_pool *cpu_pool, void *obj)
static int kmem_cpu_pool_fill(struct kmem_cpu_pool *cpu_pool,
struct kmem_cache *cache)
{
- void *obj;
+ kmem_cache_ctor_t ctor;
+ void *buf;
int i;
+ ctor = (cpu_pool->flags & KMEM_CF_VERIFY) ? NULL : cache->ctor;
+
simple_lock(&cache->lock);
for (i = 0; i < cpu_pool->transfer_size; i++) {
- obj = kmem_cache_alloc_from_slab(cache);
+ buf = kmem_cache_alloc_from_slab(cache);
- if (obj == NULL)
+ if (buf == NULL)
break;
- kmem_cpu_pool_push(cpu_pool, obj);
+ if (ctor != NULL)
+ ctor(buf);
+
+ kmem_cpu_pool_push(cpu_pool, buf);
}
simple_unlock(&cache->lock);
@@ -656,7 +662,7 @@ static void kmem_cache_error(struct kmem_cache *cache, void *buf, int error,
{
struct kmem_buftag *buftag;
- kmem_error("cache: %s, buffer: %p", cache->name, (void *)buf);
+ kmem_warn("cache: %s, buffer: %p", cache->name, (void *)buf);
switch(error) {
case KMEM_ERR_INVALID:
@@ -696,9 +702,9 @@ static void kmem_cache_error(struct kmem_cache *cache, void *buf, int error,
*/
static void kmem_cache_compute_sizes(struct kmem_cache *cache, int flags)
{
- size_t i, buffers, buf_size, slab_size, free_slab_size, optimal_size;
+ size_t i, buffers, buf_size, slab_size, free_slab_size, optimal_size = 0;
size_t waste, waste_min;
- int embed, optimal_embed = optimal_embed;
+ int embed, optimal_embed = 0;
buf_size = cache->buf_size;
@@ -739,6 +745,7 @@ static void kmem_cache_compute_sizes(struct kmem_cache *cache, int flags)
} while ((buffers < KMEM_MIN_BUFS_PER_SLAB)
&& (slab_size < KMEM_SLAB_SIZE_THRESHOLD));
+ assert(optimal_size > 0);
assert(!(flags & KMEM_CACHE_NOOFFSLAB) || optimal_embed);
cache->slab_size = optimal_size;
@@ -878,7 +885,7 @@ static int kmem_cache_grow(struct kmem_cache *cache)
simple_lock(&cache->lock);
if (slab != NULL) {
- list_insert_tail(&cache->free_slabs, &slab->list_node);
+ list_insert_head(&cache->free_slabs, &slab->list_node);
cache->nr_bufs += cache->bufs_per_slab;
cache->nr_slabs++;
cache->nr_free_slabs++;
@@ -899,31 +906,28 @@ static void kmem_cache_reap(struct kmem_cache *cache)
{
struct kmem_slab *slab;
struct list dead_slabs;
+ unsigned long nr_free_slabs;
if (cache->flags & KMEM_CF_NO_RECLAIM)
return;
- list_init(&dead_slabs);
-
simple_lock(&cache->lock);
-
- while (!list_empty(&cache->free_slabs)) {
- slab = list_first_entry(&cache->free_slabs, struct kmem_slab,
- list_node);
- list_remove(&slab->list_node);
- list_insert(&dead_slabs, &slab->list_node);
- cache->nr_bufs -= cache->bufs_per_slab;
- cache->nr_slabs--;
- cache->nr_free_slabs--;
- }
-
+ list_set_head(&dead_slabs, &cache->free_slabs);
+ list_init(&cache->free_slabs);
+ nr_free_slabs = cache->nr_free_slabs;
+ cache->nr_bufs -= cache->bufs_per_slab * nr_free_slabs;
+ cache->nr_slabs -= nr_free_slabs;
+ cache->nr_free_slabs = 0;
simple_unlock(&cache->lock);
while (!list_empty(&dead_slabs)) {
slab = list_first_entry(&dead_slabs, struct kmem_slab, list_node);
list_remove(&slab->list_node);
kmem_slab_destroy(slab, cache);
+ nr_free_slabs--;
}
+
+ assert(nr_free_slabs == 0);
}
/*
@@ -951,49 +955,20 @@ static void * kmem_cache_alloc_from_slab(struct kmem_cache *cache)
slab->nr_refs++;
cache->nr_objs++;
- /*
- * The slab has become complete.
- */
if (slab->nr_refs == cache->bufs_per_slab) {
+ /* The slab has become complete */
list_remove(&slab->list_node);
if (slab->nr_refs == 1)
cache->nr_free_slabs--;
} else if (slab->nr_refs == 1) {
/*
- * The slab has become partial.
+ * The slab has become partial. Insert the new slab at the end of
+ * the list to reduce fragmentation.
*/
list_remove(&slab->list_node);
list_insert_tail(&cache->partial_slabs, &slab->list_node);
cache->nr_free_slabs--;
- } else if (!list_singular(&cache->partial_slabs)) {
- struct list *node;
- struct kmem_slab *tmp;
-
- /*
- * The slab remains partial. If there are more than one partial slabs,
- * maintain the list sorted.
- */
-
- assert(slab->nr_refs > 1);
-
- for (node = list_prev(&slab->list_node);
- !list_end(&cache->partial_slabs, node);
- node = list_prev(node)) {
- tmp = list_entry(node, struct kmem_slab, list_node);
-
- if (tmp->nr_refs >= slab->nr_refs)
- break;
- }
-
- /*
- * If the direct neighbor was found, the list is already sorted.
- * If no slab was found, the slab is inserted at the head of the list.
- */
- if (node != list_prev(&slab->list_node)) {
- list_remove(&slab->list_node);
- list_insert_after(node, &slab->list_node);
- }
}
if ((slab->nr_refs == 1) && kmem_slab_use_tree(cache->flags))
@@ -1036,54 +1011,20 @@ static void kmem_cache_free_to_slab(struct kmem_cache *cache, void *buf)
slab->nr_refs--;
cache->nr_objs--;
- /*
- * The slab has become free.
- */
if (slab->nr_refs == 0) {
+ /* The slab has become free */
+
if (kmem_slab_use_tree(cache->flags))
rbtree_remove(&cache->active_slabs, &slab->tree_node);
- /*
- * The slab was partial.
- */
if (cache->bufs_per_slab > 1)
list_remove(&slab->list_node);
- list_insert_tail(&cache->free_slabs, &slab->list_node);
+ list_insert_head(&cache->free_slabs, &slab->list_node);
cache->nr_free_slabs++;
} else if (slab->nr_refs == (cache->bufs_per_slab - 1)) {
- /*
- * The slab has become partial.
- */
- list_insert(&cache->partial_slabs, &slab->list_node);
- } else if (!list_singular(&cache->partial_slabs)) {
- struct list *node;
- struct kmem_slab *tmp;
-
- /*
- * The slab remains partial. If there are more than one partial slabs,
- * maintain the list sorted.
- */
-
- assert(slab->nr_refs > 0);
-
- for (node = list_next(&slab->list_node);
- !list_end(&cache->partial_slabs, node);
- node = list_next(node)) {
- tmp = list_entry(node, struct kmem_slab, list_node);
-
- if (tmp->nr_refs <= slab->nr_refs)
- break;
- }
-
- /*
- * If the direct neighbor was found, the list is already sorted.
- * If no slab was found, the slab is inserted at the tail of the list.
- */
- if (node != list_next(&slab->list_node)) {
- list_remove(&slab->list_node);
- list_insert_before(node, &slab->list_node);
- }
+ /* The slab has become partial */
+ list_insert_head(&cache->partial_slabs, &slab->list_node);
}
}
@@ -1295,6 +1236,7 @@ fast_free:
simple_unlock(&cpu_pool->lock);
kmem_cache_free(cache->cpu_pool_type->array_cache,
(vm_offset_t)array);
+ simple_lock(&cpu_pool->lock);
goto fast_free;
}
@@ -1305,7 +1247,9 @@ fast_free:
slab_free:
#endif /* SLAB_USE_CPU_POOLS */
+ simple_lock(&cache->lock);
kmem_cache_free_to_slab(cache, (void *)obj);
+ simple_unlock(&cache->lock);
}
void slab_collect(void)
@@ -1386,7 +1330,6 @@ void kalloc_init(void)
{
char name[KMEM_CACHE_NAME_SIZE];
size_t i, size;
- vm_offset_t min, max;
size = 1 << KALLOC_FIRST_SHIFT;
@@ -1508,7 +1451,7 @@ void slab_info(void)
mem_usage = (cache->nr_slabs * cache->slab_size) >> 10;
mem_reclaimable = (cache->nr_free_slabs * cache->slab_size) >> 10;
- printf("%-19s %6lu %3luk %4lu %6lu %6lu %7luk %10luk\n",
+ printf("%-19s %6lu %3luk %4lu %6lu %6lu %7uk %10uk\n",
cache->name, cache->obj_size, cache->slab_size >> 10,
cache->bufs_per_slab, cache->nr_objs, cache->nr_bufs,
mem_usage, mem_reclaimable);
@@ -1526,7 +1469,7 @@ kern_return_t host_slab_info(host_t host, cache_info_array_t *infop,
struct kmem_cache *cache;
cache_info_t *info;
unsigned int i, nr_caches;
- vm_size_t info_size = info_size;
+ vm_size_t info_size = 0;
kern_return_t kr;
if (host == HOST_NULL)
@@ -1560,7 +1503,7 @@ kern_return_t host_slab_info(host_t host, cache_info_array_t *infop,
i = 0;
list_for_each_entry(&kmem_cache_list, cache, node) {
- simple_lock(&cache_lock);
+ simple_lock(&cache->lock);
info[i].flags = ((cache->flags & KMEM_CF_NO_CPU_POOL)
? CACHE_FLAGS_NO_CPU_POOL : 0)
| ((cache->flags & KMEM_CF_SLAB_EXTERNAL)
diff --git a/kern/slab.h b/kern/slab.h
index 47bef218..c7be1692 100644
--- a/kern/slab.h
+++ b/kern/slab.h
@@ -47,6 +47,7 @@
#ifndef _KERN_SLAB_H
#define _KERN_SLAB_H
+#include <cache.h>
#include <kern/lock.h>
#include <kern/list.h>
#include <kern/rbtree.h>
@@ -147,21 +148,20 @@ typedef vm_offset_t (*kmem_slab_alloc_fn_t)(vm_size_t);
typedef void (*kmem_slab_free_fn_t)(vm_offset_t, vm_size_t);
/*
- * Cache name buffer size.
+ * Cache name buffer size. The size is chosen so that struct
+ * kmem_cache fits into two cache lines. The size of a cache line on
+ * a typical CPU is 64 bytes.
*/
-#define KMEM_CACHE_NAME_SIZE 32
+#define KMEM_CACHE_NAME_SIZE 24
/*
* Cache of objects.
*
* Locking order : cpu_pool -> cache. CPU pools locking is ordered by CPU ID.
*
- * The partial slabs list is sorted by slab references. Slabs with a high
- * number of references are placed first on the list to reduce fragmentation.
- * Sorting occurs at insertion/removal of buffers in a slab. As the list
- * is maintained sorted, and the number of references only changes by one,
- * this is a very cheap operation in the average case and the worst (linear)
- * case is very unlikely.
+ * Currently, SLAB_USE_CPU_POOLS is not defined. KMEM_CACHE_NAME_SIZE
+ * is chosen so that the struct fits into two cache lines. The first
+ * cache line contains all hot fields.
*/
struct kmem_cache {
#if SLAB_USE_CPU_POOLS
@@ -177,25 +177,27 @@ struct kmem_cache {
struct list free_slabs;
struct rbtree active_slabs;
int flags;
+ size_t bufctl_dist; /* Distance from buffer to bufctl */
+ size_t slab_size;
+ unsigned long bufs_per_slab;
+ unsigned long nr_objs; /* Number of allocated objects */
+ unsigned long nr_free_slabs;
+ kmem_cache_ctor_t ctor;
+ /* All fields below are cold */
size_t obj_size; /* User-provided size */
+ /* Assuming ! SLAB_USE_CPU_POOLS, here is the cacheline boundary */
size_t align;
size_t buf_size; /* Aligned object size */
- size_t bufctl_dist; /* Distance from buffer to bufctl */
- size_t slab_size;
size_t color;
size_t color_max;
- unsigned long bufs_per_slab;
- unsigned long nr_objs; /* Number of allocated objects */
unsigned long nr_bufs; /* Total number of buffers */
unsigned long nr_slabs;
- unsigned long nr_free_slabs;
- kmem_cache_ctor_t ctor;
kmem_slab_alloc_fn_t slab_alloc_fn;
kmem_slab_free_fn_t slab_free_fn;
char name[KMEM_CACHE_NAME_SIZE];
size_t buftag_dist; /* Distance from buffer to buftag */
size_t redzone_pad; /* Bytes from end of object to redzone word */
-};
+} __cacheline_aligned;
/*
* Mach-style declarations for struct kmem_cache.
diff --git a/kern/startup.c b/kern/startup.c
index 0c04ccf8..de21ca4a 100644
--- a/kern/startup.c
+++ b/kern/startup.c
@@ -39,51 +39,41 @@
#include <kern/machine.h>
#include <kern/mach_factor.h>
#include <kern/mach_clock.h>
-#include <kern/printf.h>
#include <kern/processor.h>
+#include <kern/rdxtree.h>
#include <kern/sched_prim.h>
#include <kern/task.h>
#include <kern/thread.h>
#include <kern/thread_swap.h>
#include <kern/timer.h>
#include <kern/xpr.h>
+#include <kern/bootstrap.h>
#include <kern/time_stamp.h>
+#include <kern/startup.h>
#include <vm/vm_kern.h>
#include <vm/vm_map.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
+#include <vm/vm_init.h>
+#include <vm/vm_pageout.h>
#include <machine/machspl.h>
#include <machine/pcb.h>
#include <machine/pmap.h>
#include <machine/model_dep.h>
#include <mach/version.h>
+#include <device/device_init.h>
-
-
-extern void vm_mem_init();
-extern void vm_mem_bootstrap();
-extern void init_timeout();
-extern void machine_init();
-
-extern void idle_thread();
-extern void vm_pageout();
-extern void reaper_thread();
-extern void swapin_thread();
-extern void sched_thread();
-
-extern void bootstrap_create();
-extern void device_service_create();
-
-void cpu_launch_first_thread(); /* forward */
-void start_kernel_threads(); /* forward */
+#if MACH_KDB
+#include <device/cons.h>
+#endif /* MACH_KDB */
#if ! MACH_KBD
-boolean_t reboot_on_panic = 1;
+boolean_t reboot_on_panic = TRUE;
#endif
#if NCPUS > 1
-extern void start_other_cpus();
-extern void action_thread();
+#include <machine/mp_desc.h>
+#include <kern/machine.h>
#endif /* NCPUS > 1 */
/* XX */
@@ -96,7 +86,7 @@ extern char *kernel_cmdline;
*
* Assumes that master_cpu is set.
*/
-void setup_main()
+void setup_main(void)
{
thread_t startup_thread;
@@ -113,15 +103,15 @@ void setup_main()
}
#else /* MACH_KDB */
if (strstr (kernel_cmdline, "-H ")) {
- reboot_on_panic = 0;
+ reboot_on_panic = FALSE;
}
#endif /* MACH_KDB */
panic_init();
- printf_init();
sched_init();
vm_mem_bootstrap();
+ rdxtree_cache_init();
ipc_bootstrap();
vm_mem_init();
ipc_init();
@@ -169,7 +159,7 @@ void setup_main()
* Kick off the time-out driven routines by calling
* them the first time.
*/
- recompute_priorities();
+ recompute_priorities(NULL);
compute_mach_factor();
/*
@@ -212,9 +202,9 @@ void setup_main()
* Now running in a thread. Create the rest of the kernel threads
* and the bootstrap task.
*/
-void start_kernel_threads()
+void start_kernel_threads(void)
{
- register int i;
+ int i;
/*
* Create the idle threads and the other
@@ -280,7 +270,7 @@ void start_kernel_threads()
}
#if NCPUS > 1
-void slave_main()
+void slave_main(void)
{
cpu_launch_first_thread(THREAD_NULL);
}
@@ -290,10 +280,9 @@ void slave_main()
* Start up the first thread on a CPU.
* First thread is specified for the master CPU.
*/
-void cpu_launch_first_thread(th)
- register thread_t th;
+void cpu_launch_first_thread(thread_t th)
{
- register int mycpu;
+ int mycpu;
mycpu = cpu_number();
diff --git a/kern/startup.h b/kern/startup.h
new file mode 100644
index 00000000..d924d154
--- /dev/null
+++ b/kern/startup.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013 Free Software Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _KERN_STARTUP_H_
+#define _KERN_STARTUP_H_
+
+#include <kern/thread.h>
+
+extern void setup_main(void);
+void cpu_launch_first_thread(thread_t th);
+void start_kernel_threads(void);
+
+#endif /* _KERN_STARTUP_H_ */
diff --git a/kern/strings.c b/kern/strings.c
index 3676f98e..e299534a 100644
--- a/kern/strings.c
+++ b/kern/strings.c
@@ -50,15 +50,15 @@
* the contents are identical up to the length of s2.
* It returns < 0 if the first differing character is smaller
* in s1 than in s2 or if s1 is shorter than s2 and the
- * contents are identical upto the length of s1.
+ * contents are identical up to the length of s1.
*/
-int
+int __attribute__ ((pure))
strcmp(
- register const char *s1,
- register const char *s2)
+ const char *s1,
+ const char *s2)
{
- register unsigned int a, b;
+ unsigned int a, b;
do {
a = *s1++;
@@ -80,13 +80,13 @@ strcmp(
* comparison runs for at most "n" characters.
*/
-int
+int __attribute__ ((pure))
strncmp(
- register const char *s1,
- register const char *s2,
+ const char *s1,
+ const char *s2,
size_t n)
{
- register unsigned int a, b;
+ unsigned int a, b;
while (n != 0) {
a = *s1++;
@@ -113,10 +113,10 @@ strncmp(
char *
strcpy(
- register char *to,
- register const char *from)
+ char *to,
+ const char *from)
{
- register char *ret = to;
+ char *ret = to;
while ((*to++ = *from++) != '\0')
continue;
@@ -135,11 +135,11 @@ strcpy(
char *
strncpy(
- register char *to,
- register const char *from,
- register size_t count)
+ char *to,
+ const char *from,
+ size_t count)
{
- register char *ret = to;
+ char *ret = to;
while (count != 0) {
count--;
@@ -157,15 +157,15 @@ strncpy(
/*
* Abstract:
- * strlen returns the number of characters in "string" preceeding
+ * strlen returns the number of characters in "string" preceding
* the terminating null character.
*/
-size_t
+size_t __attribute__ ((pure))
strlen(
- register const char *string)
+ const char *string)
{
- register const char *ret = string;
+ const char *ret = string;
while (*string++ != '\0')
continue;
diff --git a/kern/syscall_emulation.c b/kern/syscall_emulation.c
index c1c3096c..95e91d55 100644
--- a/kern/syscall_emulation.c
+++ b/kern/syscall_emulation.c
@@ -57,7 +57,7 @@
/*
* eml_init: initialize user space emulation code
*/
-void eml_init()
+void eml_init(void)
{
}
@@ -68,10 +68,11 @@ void eml_init()
* vector.
*/
-void eml_task_reference(task, parent)
- task_t task, parent;
+void eml_task_reference(
+ task_t task,
+ task_t parent)
{
- register eml_dispatch_t eml;
+ eml_dispatch_t eml;
if (parent == TASK_NULL)
eml = EML_DISPATCH_NULL;
@@ -94,9 +95,9 @@ void eml_task_reference(task, parent)
*/
void eml_task_deallocate(task)
- task_t task;
+ const task_t task;
{
- register eml_dispatch_t eml;
+ eml_dispatch_t eml;
eml = task->eml_dispatch;
if (eml != EML_DISPATCH_NULL) {
@@ -116,12 +117,11 @@ void eml_task_deallocate(task)
* set a list of emulated system calls for this task.
*/
kern_return_t
-task_set_emulation_vector_internal(task, vector_start, emulation_vector,
- emulation_vector_count)
- task_t task;
- int vector_start;
- emulation_vector_t emulation_vector;
- unsigned int emulation_vector_count;
+task_set_emulation_vector_internal(
+ task_t task,
+ int vector_start,
+ emulation_vector_t emulation_vector,
+ unsigned int emulation_vector_count)
{
eml_dispatch_t cur_eml, new_eml, old_eml;
vm_size_t new_size;
@@ -295,12 +295,11 @@ task_set_emulation_vector_internal(task, vector_start, emulation_vector,
* The list is out-of-line.
*/
kern_return_t
-task_set_emulation_vector(task, vector_start, emulation_vector,
- emulation_vector_count)
- task_t task;
- int vector_start;
- emulation_vector_t emulation_vector;
- unsigned int emulation_vector_count;
+task_set_emulation_vector(
+ task_t task,
+ int vector_start,
+ emulation_vector_t emulation_vector,
+ unsigned int emulation_vector_count)
{
kern_return_t kr;
vm_offset_t emul_vector_addr;
@@ -342,12 +341,11 @@ task_set_emulation_vector(task, vector_start, emulation_vector,
* List is returned out-of-line.
*/
kern_return_t
-task_get_emulation_vector(task, vector_start, emulation_vector,
- emulation_vector_count)
- task_t task;
- int *vector_start; /* out */
- emulation_vector_t *emulation_vector; /* out */
- unsigned int *emulation_vector_count; /* out */
+task_get_emulation_vector(
+ task_t task,
+ int *vector_start, /* out */
+ emulation_vector_t *emulation_vector, /* out */
+ unsigned int *emulation_vector_count) /* out */
{
eml_dispatch_t eml;
vm_size_t vector_size, size;
@@ -445,10 +443,10 @@ task_get_emulation_vector(task, vector_start, emulation_vector,
* task_set_emulation: [Server Entry]
* set up for user space emulation of syscalls within this task.
*/
-kern_return_t task_set_emulation(task, routine_entry_pt, routine_number)
- task_t task;
- vm_offset_t routine_entry_pt;
- int routine_number;
+kern_return_t task_set_emulation(
+ task_t task,
+ vm_offset_t routine_entry_pt,
+ int routine_number)
{
return task_set_emulation_vector_internal(task, routine_number,
&routine_entry_pt, 1);
diff --git a/kern/syscall_emulation.h b/kern/syscall_emulation.h
index 501b0a83..bf20e441 100644
--- a/kern/syscall_emulation.h
+++ b/kern/syscall_emulation.h
@@ -33,6 +33,7 @@
#ifndef __ASSEMBLER__
#include <mach/machine/vm_types.h>
#include <kern/lock.h>
+#include <kern/task.h>
typedef vm_offset_t eml_routine_t;
@@ -56,6 +57,11 @@ typedef vm_offset_t *emulation_vector_t; /* Variable-length array */
#define EML_MOD (err_kern|err_sub(2))
#define EML_BAD_TASK (EML_MOD|0x0001)
#define EML_BAD_CNT (EML_MOD|0x0002)
+
+extern void eml_init(void);
+extern void eml_task_reference(task_t task, task_t parent);
+extern void eml_task_deallocate(task_t task);
+
#endif /* __ASSEMBLER__ */
#endif /* _KERN_SYSCALL_EMULATION_H_ */
diff --git a/kern/syscall_subr.c b/kern/syscall_subr.c
index ae2d7d73..6d23462c 100644
--- a/kern/syscall_subr.c
+++ b/kern/syscall_subr.c
@@ -48,8 +48,6 @@
#include <mach/policy.h>
#endif /* MACH_FIXPRI */
-
-
/*
* swtch and swtch_pri both attempt to context switch (logic in
* thread_block no-ops the context switch if nothing would happen).
@@ -63,12 +61,9 @@
* returned, the thread should make one more check on the
* lock and then be a good citizen and really suspend.
*/
-
-void thread_depress_priority(thread_t, mach_msg_timeout_t);
-
void swtch_continue(void)
{
- register processor_t myprocessor;
+ processor_t myprocessor;
myprocessor = current_processor();
thread_syscall_return(myprocessor->runq.count > 0 ||
@@ -78,7 +73,7 @@ void swtch_continue(void)
boolean_t swtch(void)
{
- register processor_t myprocessor;
+ processor_t myprocessor;
#if NCPUS > 1
myprocessor = current_processor();
@@ -96,8 +91,8 @@ boolean_t swtch(void)
void swtch_pri_continue(void)
{
- register thread_t thread = current_thread();
- register processor_t myprocessor;
+ thread_t thread = current_thread();
+ processor_t myprocessor;
if (thread->depress_priority >= 0)
(void) thread_depress_abort(thread);
@@ -107,15 +102,10 @@ void swtch_pri_continue(void)
/*NOTREACHED*/
}
-boolean_t swtch_pri(pri)
- int pri;
+boolean_t swtch_pri(int pri)
{
- register thread_t thread = current_thread();
- register processor_t myprocessor;
-
-#ifdef lint
- pri++;
-#endif /* lint */
+ thread_t thread = current_thread();
+ processor_t myprocessor;
#if NCPUS > 1
myprocessor = current_processor();
@@ -142,7 +132,7 @@ boolean_t swtch_pri(pri)
void thread_switch_continue(void)
{
- register thread_t cur_thread = current_thread();
+ thread_t cur_thread = current_thread();
/*
* Restore depressed priority
@@ -161,13 +151,13 @@ void thread_switch_continue(void)
* Fixed priority threads that call this get what they asked for
* even if that violates priority order.
*/
-kern_return_t thread_switch(thread_name, option, option_time)
-mach_port_t thread_name;
-int option;
-mach_msg_timeout_t option_time;
+kern_return_t thread_switch(
+ mach_port_t thread_name,
+ int option,
+ mach_msg_timeout_t option_time)
{
- register thread_t cur_thread = current_thread();
- register processor_t myprocessor;
+ thread_t cur_thread = current_thread();
+ processor_t myprocessor;
ipc_port_t port;
/*
@@ -208,8 +198,8 @@ mach_msg_timeout_t option_time;
* Get corresponding thread.
*/
if (ip_active(port) && (ip_kotype(port) == IKOT_THREAD)) {
- register thread_t thread;
- register spl_t s;
+ thread_t thread;
+ spl_t s;
thread = (thread_t) port->ip_kobject;
/*
@@ -289,9 +279,9 @@ mach_msg_timeout_t option_time;
* of zero will result in no timeout being scheduled.
*/
void
-thread_depress_priority(thread, depress_time)
-register thread_t thread;
-mach_msg_timeout_t depress_time;
+thread_depress_priority(
+ thread_t thread,
+ mach_msg_timeout_t depress_time)
{
unsigned int ticks;
spl_t s;
@@ -312,8 +302,8 @@ mach_msg_timeout_t depress_time;
* sched_pri to their lowest possible values.
*/
thread->depress_priority = thread->priority;
- thread->priority = 31;
- thread->sched_pri = 31;
+ thread->priority = NRQS-1;
+ thread->sched_pri = NRQS-1;
if (ticks != 0)
set_timeout(&thread->depress_timer, ticks);
@@ -327,8 +317,7 @@ mach_msg_timeout_t depress_time;
* Timeout routine for priority depression.
*/
void
-thread_depress_timeout(thread)
-register thread_t thread;
+thread_depress_timeout(thread_t thread)
{
spl_t s;
@@ -356,8 +345,7 @@ register thread_t thread;
* Prematurely abort priority depression if there is one.
*/
kern_return_t
-thread_depress_abort(thread)
-register thread_t thread;
+thread_depress_abort(thread_t thread)
{
spl_t s;
diff --git a/kern/syscall_subr.h b/kern/syscall_subr.h
index a2e39205..b6b61ab2 100644
--- a/kern/syscall_subr.h
+++ b/kern/syscall_subr.h
@@ -37,5 +37,6 @@ extern int thread_switch(mach_port_t, int, mach_msg_timeout_t);
extern void thread_depress_timeout(thread_t);
extern kern_return_t thread_depress_abort(thread_t);
extern void mach_print(const char *);
+extern void thread_depress_priority(thread_t thread, mach_msg_timeout_t depress_time);
#endif /* _KERN_SYSCALL_SUBR_H_ */
diff --git a/kern/syscall_sw.c b/kern/syscall_sw.c
index 607d843e..a383e467 100644
--- a/kern/syscall_sw.c
+++ b/kern/syscall_sw.c
@@ -36,6 +36,8 @@
#include <mach/mach_traps.h>
#include <mach/message.h>
#include <kern/syscall_subr.h>
+#include <kern/ipc_mig.h>
+#include <kern/eventcount.h>
#include <ipc/mach_port.h>
@@ -56,41 +58,20 @@
* the positive numbers) are reserved for Unix.
*/
-int kern_invalid_debug = 0;
+boolean_t kern_invalid_debug = FALSE;
-mach_port_t null_port()
+mach_port_t null_port(void)
{
if (kern_invalid_debug) SoftDebugger("null_port mach trap");
return(MACH_PORT_NULL);
}
-kern_return_t kern_invalid()
+kern_return_t kern_invalid(void)
{
if (kern_invalid_debug) SoftDebugger("kern_invalid mach trap");
return(KERN_INVALID_ARGUMENT);
}
-extern kern_return_t syscall_vm_map();
-extern kern_return_t syscall_vm_allocate();
-extern kern_return_t syscall_vm_deallocate();
-
-extern kern_return_t syscall_task_create();
-extern kern_return_t syscall_task_terminate();
-extern kern_return_t syscall_task_suspend();
-extern kern_return_t syscall_task_set_special_port();
-
-extern kern_return_t syscall_mach_port_allocate();
-extern kern_return_t syscall_mach_port_deallocate();
-extern kern_return_t syscall_mach_port_insert_right();
-extern kern_return_t syscall_mach_port_allocate_name();
-
-extern kern_return_t syscall_thread_depress_abort();
-extern kern_return_t evc_wait();
-extern kern_return_t evc_wait_clear();
-
-extern kern_return_t syscall_device_write_request();
-extern kern_return_t syscall_device_writev_request();
-
mach_trap_t mach_trap_table[] = {
MACH_TRAP(kern_invalid, 0), /* 0 */ /* Unix */
MACH_TRAP(kern_invalid, 0), /* 1 */ /* Unix */
diff --git a/kern/task.c b/kern/task.c
index 114dd319..b384347f 100644
--- a/kern/task.c
+++ b/kern/task.c
@@ -37,6 +37,7 @@
#include <mach/vm_param.h>
#include <mach/task_info.h>
#include <mach/task_special_ports.h>
+#include <mach_debug/mach_debug_types.h>
#include <ipc/ipc_space.h>
#include <ipc/ipc_types.h>
#include <kern/debug.h>
@@ -45,17 +46,19 @@
#include <kern/slab.h>
#include <kern/kalloc.h>
#include <kern/processor.h>
+#include <kern/printf.h>
#include <kern/sched_prim.h> /* for thread_wakeup */
#include <kern/ipc_tt.h>
+#include <kern/syscall_emulation.h>
+#include <kern/task_notify.user.h>
#include <vm/vm_kern.h> /* for kernel_map, ipc_kernel_map */
#include <machine/machspl.h> /* for splsched */
task_t kernel_task = TASK_NULL;
struct kmem_cache task_cache;
-extern void eml_init(void);
-extern void eml_task_reference(task_t, task_t);
-extern void eml_task_deallocate(task_t);
+/* Where to send notifications about newly created tasks. */
+ipc_port_t new_task_notification = NULL;
void task_init(void)
{
@@ -71,6 +74,7 @@ void task_init(void)
* for other initialization. (:-()
*/
(void) task_create(TASK_NULL, FALSE, &kernel_task);
+ (void) task_set_name(kernel_task, "gnumach");
}
kern_return_t task_create(
@@ -78,16 +82,15 @@ kern_return_t task_create(
boolean_t inherit_memory,
task_t *child_task) /* OUT */
{
- register task_t new_task;
- register processor_set_t pset;
+ task_t new_task;
+ processor_set_t pset;
#if FAST_TAS
int i;
#endif
new_task = (task_t) kmem_cache_alloc(&task_cache);
- if (new_task == TASK_NULL) {
- panic("task_create: no memory for task structure");
- }
+ if (new_task == TASK_NULL)
+ return KERN_RESOURCE_SHORTAGE;
/* one ref for just being alive; one for our caller */
new_task->ref_count = 2;
@@ -167,6 +170,21 @@ kern_return_t task_create(
}
#endif /* FAST_TAS */
+ if (parent_task == TASK_NULL)
+ snprintf (new_task->name, sizeof new_task->name, "%p",
+ new_task);
+ else
+ snprintf (new_task->name, sizeof new_task->name, "(%.*s)",
+ sizeof new_task->name - 3, parent_task->name);
+
+ if (new_task_notification != NULL) {
+ task_reference (new_task);
+ task_reference (parent_task);
+ mach_notify_new_task (new_task_notification,
+ convert_task_to_port (new_task),
+ convert_task_to_port (parent_task));
+ }
+
ipc_task_enable(new_task);
*child_task = new_task;
@@ -181,10 +199,10 @@ kern_return_t task_create(
* is never in this task.
*/
void task_deallocate(
- register task_t task)
+ task_t task)
{
- register int c;
- register processor_set_t pset;
+ int c;
+ processor_set_t pset;
if (task == TASK_NULL)
return;
@@ -210,7 +228,7 @@ void task_deallocate(
}
void task_reference(
- register task_t task)
+ task_t task)
{
if (task == TASK_NULL)
return;
@@ -227,11 +245,11 @@ void task_reference(
* (kern/thread.c) about problems with terminating the "current task."
*/
kern_return_t task_terminate(
- register task_t task)
+ task_t task)
{
- register thread_t thread, cur_thread;
- register queue_head_t *list;
- register task_t cur_task;
+ thread_t thread, cur_thread;
+ queue_head_t *list;
+ task_t cur_task;
spl_t s;
if (task == TASK_NULL)
@@ -270,6 +288,7 @@ kern_return_t task_terminate(
thread_terminate(cur_thread);
return KERN_FAILURE;
}
+ task_hold_locked(task);
task->active = FALSE;
queue_remove(list, cur_thread, thread_t, thread_list);
thread_unlock(cur_thread);
@@ -323,6 +342,7 @@ kern_return_t task_terminate(
task_unlock(task);
return KERN_FAILURE;
}
+ task_hold_locked(task);
task->active = FALSE;
task_unlock(task);
}
@@ -333,9 +353,8 @@ kern_return_t task_terminate(
* If this is the current task, the current thread will
* be left running.
*/
- ipc_task_disable(task);
- (void) task_hold(task);
(void) task_dowait(task,TRUE); /* may block */
+ ipc_task_disable(task);
/*
* Terminate each thread in the task.
@@ -400,20 +419,18 @@ kern_return_t task_terminate(
* Suspend execution of the specified task.
* This is a recursive-style suspension of the task, a count of
* suspends is maintained.
+ *
+ * CONDITIONS: the task is locked and active.
*/
-kern_return_t task_hold(
- register task_t task)
+void task_hold_locked(
+ task_t task)
{
- register queue_head_t *list;
- register thread_t thread, cur_thread;
+ queue_head_t *list;
+ thread_t thread, cur_thread;
- cur_thread = current_thread();
+ assert(task->active);
- task_lock(task);
- if (!task->active) {
- task_unlock(task);
- return KERN_FAILURE;
- }
+ cur_thread = current_thread();
task->suspend_count++;
@@ -427,6 +444,26 @@ kern_return_t task_hold(
if (thread != cur_thread)
thread_hold(thread);
}
+}
+
+/*
+ * task_hold:
+ *
+ * Suspend execution of the specified task.
+ * This is a recursive-style suspension of the task, a count of
+ * suspends is maintained.
+ */
+kern_return_t task_hold(
+ task_t task)
+{
+ task_lock(task);
+ if (!task->active) {
+ task_unlock(task);
+ return KERN_FAILURE;
+ }
+
+ task_hold_locked(task);
+
task_unlock(task);
return KERN_SUCCESS;
}
@@ -441,12 +478,12 @@ kern_return_t task_hold(
* must_wait is true.
*/
kern_return_t task_dowait(
- register task_t task,
+ task_t task,
boolean_t must_wait)
{
- register queue_head_t *list;
- register thread_t thread, cur_thread, prev_thread;
- register kern_return_t ret = KERN_SUCCESS;
+ queue_head_t *list;
+ thread_t thread, cur_thread, prev_thread;
+ kern_return_t ret = KERN_SUCCESS;
/*
* Iterate through all the threads.
@@ -493,10 +530,10 @@ kern_return_t task_dowait(
}
kern_return_t task_release(
- register task_t task)
+ task_t task)
{
- register queue_head_t *list;
- register thread_t thread, next;
+ queue_head_t *list;
+ thread_t thread, next;
task_lock(task);
if (!task->active) {
@@ -624,9 +661,9 @@ kern_return_t task_threads(
}
kern_return_t task_suspend(
- register task_t task)
+ task_t task)
{
- register boolean_t hold;
+ boolean_t hold;
if (task == TASK_NULL)
return KERN_INVALID_ARGUMENT;
@@ -675,9 +712,9 @@ kern_return_t task_suspend(
}
kern_return_t task_resume(
- register task_t task)
+ task_t task)
{
- register boolean_t release;
+ boolean_t release;
if (task == TASK_NULL)
return KERN_INVALID_ARGUMENT;
@@ -717,7 +754,7 @@ kern_return_t task_info(
switch (flavor) {
case TASK_BASIC_INFO:
{
- register task_basic_info_t basic_info;
+ task_basic_info_t basic_info;
/* Allow *task_info_count to be two words smaller than
the usual amount, because creation_time is a new member
@@ -756,7 +793,7 @@ kern_return_t task_info(
case TASK_EVENTS_INFO:
{
- register task_events_info_t event_info;
+ task_events_info_t event_info;
if (*task_info_count < TASK_EVENTS_INFO_COUNT) {
return KERN_INVALID_ARGUMENT;
@@ -764,7 +801,7 @@ kern_return_t task_info(
event_info = (task_events_info_t) task_info_out;
- task_lock(&task);
+ task_lock(task);
event_info->faults = task->faults;
event_info->zero_fills = task->zero_fills;
event_info->reactivations = task->reactivations;
@@ -772,7 +809,7 @@ kern_return_t task_info(
event_info->cow_faults = task->cow_faults;
event_info->messages_sent = task->messages_sent;
event_info->messages_received = task->messages_received;
- task_unlock(&task);
+ task_unlock(task);
*task_info_count = TASK_EVENTS_INFO_COUNT;
break;
@@ -780,8 +817,8 @@ kern_return_t task_info(
case TASK_THREAD_TIMES_INFO:
{
- register task_thread_times_info_t times_info;
- register thread_t thread;
+ task_thread_times_info_t times_info;
+ thread_t thread;
if (*task_info_count < TASK_THREAD_TIMES_INFO_COUNT) {
return KERN_INVALID_ARGUMENT;
@@ -837,9 +874,9 @@ task_assign(
boolean_t assign_threads)
{
kern_return_t ret = KERN_SUCCESS;
- register thread_t thread, prev_thread;
- register queue_head_t *list;
- register processor_set_t pset;
+ thread_t thread, prev_thread;
+ queue_head_t *list;
+ processor_set_t pset;
if (task == TASK_NULL || new_pset == PROCESSOR_SET_NULL) {
return KERN_INVALID_ARGUMENT;
@@ -1026,6 +1063,9 @@ kern_return_t task_get_assignment(
task_t task,
processor_set_t *pset)
{
+ if (task == TASK_NULL)
+ return KERN_INVALID_ARGUMENT;
+
if (!task->active)
return KERN_FAILURE;
@@ -1055,8 +1095,8 @@ task_priority(
task->priority = priority;
if (change_threads) {
- register thread_t thread;
- register queue_head_t *list;
+ thread_t thread;
+ queue_head_t *list;
list = &task->thread_list;
queue_iterate(list, thread, thread_t, thread_list) {
@@ -1071,6 +1111,22 @@ task_priority(
}
/*
+ * task_set_name
+ *
+ * Set the name of task TASK to NAME. This is a debugging aid.
+ * NAME will be used in error messages printed by the kernel.
+ */
+kern_return_t
+task_set_name(
+ task_t task,
+ kernel_debug_name_t name)
+{
+ strncpy(task->name, name, sizeof task->name - 1);
+ task->name[sizeof task->name - 1] = '\0';
+ return KERN_SUCCESS;
+}
+
+/*
* task_collect_scan:
*
* Attempt to free resources owned by tasks.
@@ -1078,7 +1134,7 @@ task_priority(
void task_collect_scan(void)
{
- register task_t task, prev_task;
+ task_t task, prev_task;
processor_set_t pset, prev_pset;
prev_task = TASK_NULL;
@@ -1209,6 +1265,27 @@ task_ras_control(
break;
}
task_unlock(task);
-#endif
+#endif /* FAST_TAS */
return ret;
}
+
+/*
+ * register_new_task_notification
+ *
+ * Register a port to which a notification about newly created
+ * tasks are sent.
+ */
+kern_return_t
+register_new_task_notification(
+ const host_t host,
+ ipc_port_t notification)
+{
+ if (host == HOST_NULL)
+ return KERN_INVALID_HOST;
+
+ if (new_task_notification != NULL)
+ return KERN_NO_ACCESS;
+
+ new_task_notification = notification;
+ return KERN_SUCCESS;
+}
diff --git a/kern/task.h b/kern/task.h
index 9bfea571..2a4c28fc 100644
--- a/kern/task.h
+++ b/kern/task.h
@@ -39,6 +39,7 @@
#include <mach/time_value.h>
#include <mach/mach_param.h>
#include <mach/task_info.h>
+#include <mach_debug/mach_debug_types.h>
#include <kern/kern_types.h>
#include <kern/lock.h>
#include <kern/queue.h>
@@ -48,11 +49,22 @@
#include <vm/vm_types.h>
#include <machine/task.h>
+/*
+ * Task name buffer size. The size is chosen so that struct task fits
+ * into three cache lines. The size of a cache line on a typical CPU
+ * is 64 bytes.
+ */
+#define TASK_NAME_SIZE 32
+
struct task {
/* Synchronization/destruction information */
decl_simple_lock_data(,lock) /* Task's lock */
int ref_count; /* Number of references to me */
- boolean_t active; /* Task has not been terminated */
+
+ /* Flags */
+ unsigned int active:1, /* Task has not been terminated */
+ /* boolean_t */ may_assign:1, /* can assigned pset be changed? */
+ assign_active:1; /* waiting for may_assign */
/* Miscellaneous */
vm_map_t map; /* Address space description */
@@ -63,8 +75,6 @@ struct task {
queue_head_t thread_list; /* list of threads */
int thread_count; /* number of threads */
processor_set_t processor_set; /* processor set for new threads */
- boolean_t may_assign; /* can assigned pset be changed? */
- boolean_t assign_active; /* waiting for may_assign */
/* User-visible scheduling information */
int user_stop_count; /* outstanding stops */
@@ -111,6 +121,8 @@ struct task {
natural_t cow_faults; /* copy-on-write faults counter */
natural_t messages_sent; /* messages sent counter */
natural_t messages_received; /* messages received counter */
+
+ char name[TASK_NAME_SIZE];
};
#define task_lock(task) simple_lock(&(task)->lock)
@@ -158,6 +170,9 @@ extern kern_return_t task_assign(
extern kern_return_t task_assign_default(
task_t task,
boolean_t assign_threads);
+extern kern_return_t task_set_name(
+ task_t task,
+ kernel_debug_name_t name);
extern void consider_task_collect(void);
/*
@@ -167,6 +182,7 @@ extern void consider_task_collect(void);
extern void task_init(void);
extern void task_reference(task_t);
extern void task_deallocate(task_t);
+extern void task_hold_locked(task_t);
extern kern_return_t task_hold(task_t);
extern kern_return_t task_dowait(task_t, boolean_t);
extern kern_return_t task_release(task_t);
diff --git a/kern/task_notify.cli b/kern/task_notify.cli
new file mode 100644
index 00000000..c6c85d99
--- /dev/null
+++ b/kern/task_notify.cli
@@ -0,0 +1,7 @@
+/* XXX */
+
+/* This is a client presentation file. */
+
+#define KERNEL_USER 1
+
+#include <mach/task_notify.defs>
diff --git a/kern/thread.c b/kern/thread.c
index 87be9231..1f47553f 100644
--- a/kern/thread.c
+++ b/kern/thread.c
@@ -57,9 +57,11 @@
#include <kern/slab.h>
#include <kern/mach_clock.h>
#include <vm/vm_kern.h>
+#include <vm/vm_user.h>
#include <ipc/ipc_kmsg.h>
#include <ipc/ipc_port.h>
#include <ipc/mach_msg.h>
+#include <ipc/mach_port.h>
#include <machine/machspl.h> /* for splsched */
#include <machine/pcb.h>
#include <machine/thread.h> /* for MACHINE_STACK */
@@ -72,15 +74,10 @@ struct kmem_cache thread_cache;
queue_head_t reaper_queue;
decl_simple_lock_data(, reaper_lock)
-extern void pcb_module_init(void);
-
/* private */
struct thread thread_template;
#if MACH_DEBUG
-void stack_init(vm_offset_t stack); /* forward */
-void stack_finalize(vm_offset_t stack); /* forward */
-
#define STACK_MARKER 0xdeadbeefU
boolean_t stack_check_usage = FALSE;
decl_simple_lock_data(, stack_usage_lock)
@@ -127,10 +124,6 @@ vm_offset_t stack_free_list; /* splsched only */
unsigned int stack_free_count = 0; /* splsched only */
unsigned int stack_free_limit = 1; /* patchable */
-unsigned int stack_alloc_hits = 0; /* debugging */
-unsigned int stack_alloc_misses = 0; /* debugging */
-unsigned int stack_alloc_max = 0; /* debugging */
-
/*
* The next field is at the base of the stack,
* so the low end is left unsullied.
@@ -149,7 +142,7 @@ boolean_t stack_alloc_try(
thread_t thread,
void (*resume)(thread_t))
{
- register vm_offset_t stack;
+ vm_offset_t stack;
stack_lock();
stack = stack_free_list;
@@ -163,10 +156,10 @@ boolean_t stack_alloc_try(
if (stack != 0) {
stack_attach(thread, stack, resume);
- stack_alloc_hits++;
+ counter(c_stack_alloc_hits++);
return TRUE;
} else {
- stack_alloc_misses++;
+ counter(c_stack_alloc_misses++);
return FALSE;
}
}
@@ -178,7 +171,7 @@ boolean_t stack_alloc_try(
* May block.
*/
-void stack_alloc(
+kern_return_t stack_alloc(
thread_t thread,
void (*resume)(thread_t))
{
@@ -202,15 +195,15 @@ void stack_alloc(
(void) splx(s);
if (stack == 0) {
+ kern_return_t kr;
/*
* Kernel stacks should be naturally aligned,
* so that it is easy to find the starting/ending
* addresses of a stack given an address in the middle.
*/
-
- if (kmem_alloc_aligned(kmem_map, &stack, KERNEL_STACK_SIZE)
- != KERN_SUCCESS)
- panic("stack_alloc");
+ kr = kmem_alloc_aligned(kmem_map, &stack, KERNEL_STACK_SIZE);
+ if (kr != KERN_SUCCESS)
+ return kr;
#if MACH_DEBUG
stack_init(stack);
@@ -218,6 +211,7 @@ void stack_alloc(
}
stack_attach(thread, stack, resume);
+ return KERN_SUCCESS;
}
/*
@@ -230,7 +224,7 @@ void stack_alloc(
void stack_free(
thread_t thread)
{
- register vm_offset_t stack;
+ vm_offset_t stack;
stack = stack_detach(thread);
@@ -238,8 +232,11 @@ void stack_free(
stack_lock();
stack_next(stack) = stack_free_list;
stack_free_list = stack;
- if (++stack_free_count > stack_alloc_max)
- stack_alloc_max = stack_free_count;
+ stack_free_count += 1;
+#if MACH_COUNTERS
+ if (stack_free_count > c_stack_alloc_max)
+ c_stack_alloc_max = stack_free_count;
+#endif /* MACH_COUNTERS */
stack_unlock();
}
}
@@ -253,7 +250,7 @@ void stack_free(
void stack_collect(void)
{
- register vm_offset_t stack;
+ vm_offset_t stack;
spl_t s;
s = splsched();
@@ -285,7 +282,7 @@ void stack_collect(void)
*/
void stack_privilege(
- register thread_t thread)
+ thread_t thread)
{
/*
* This implementation only works for the current thread.
@@ -398,11 +395,11 @@ void thread_init(void)
}
kern_return_t thread_create(
- register task_t parent_task,
+ task_t parent_task,
thread_t *child_thread) /* OUT */
{
- register thread_t new_thread;
- register processor_set_t pset;
+ thread_t new_thread;
+ processor_set_t pset;
if (parent_task == TASK_NULL)
return KERN_INVALID_ARGUMENT;
@@ -533,7 +530,6 @@ kern_return_t thread_create(
#endif /* HW_FOOTPRINT */
#if MACH_PCSAMPLE
- new_thread->pc_sample.buffer = 0;
new_thread->pc_sample.seqno = 0;
new_thread->pc_sample.sampletypes = 0;
#endif /* MACH_PCSAMPLE */
@@ -576,11 +572,11 @@ kern_return_t thread_create(
unsigned int thread_deallocate_stack = 0;
void thread_deallocate(
- register thread_t thread)
+ thread_t thread)
{
spl_t s;
- register task_t task;
- register processor_set_t pset;
+ task_t task;
+ processor_set_t pset;
time_value_t user_time, system_time;
@@ -711,7 +707,7 @@ void thread_deallocate(
}
void thread_reference(
- register thread_t thread)
+ thread_t thread)
{
spl_t s;
@@ -745,10 +741,10 @@ void thread_reference(
* since it needs a kernel stack to execute.)
*/
kern_return_t thread_terminate(
- register thread_t thread)
+ thread_t thread)
{
- register thread_t cur_thread = current_thread();
- register task_t cur_task;
+ thread_t cur_thread = current_thread();
+ task_t cur_task;
spl_t s;
if (thread == THREAD_NULL)
@@ -851,6 +847,28 @@ kern_return_t thread_terminate(
return KERN_SUCCESS;
}
+kern_return_t thread_terminate_release(
+ thread_t thread,
+ task_t task,
+ mach_port_t thread_name,
+ mach_port_t reply_port,
+ vm_offset_t address,
+ vm_size_t size)
+{
+ if (task == NULL)
+ return KERN_INVALID_ARGUMENT;
+
+ mach_port_deallocate(task->itk_space, thread_name);
+
+ if (reply_port != MACH_PORT_NULL)
+ mach_port_destroy(task->itk_space, reply_port);
+
+ if ((address != 0) || (size != 0))
+ vm_deallocate(task->map, address, size);
+
+ return thread_terminate(thread);
+}
+
/*
* thread_force_terminate:
*
@@ -860,9 +878,9 @@ kern_return_t thread_terminate(
*/
void
thread_force_terminate(
- register thread_t thread)
+ thread_t thread)
{
- boolean_t deallocate_here = FALSE;
+ boolean_t deallocate_here;
spl_t s;
ipc_thread_disable(thread);
@@ -902,11 +920,11 @@ thread_force_terminate(
*
*/
kern_return_t thread_halt(
- register thread_t thread,
+ thread_t thread,
boolean_t must_halt)
{
- register thread_t cur_thread = current_thread();
- register kern_return_t ret;
+ thread_t cur_thread = current_thread();
+ kern_return_t ret;
spl_t s;
if (thread == cur_thread)
@@ -950,7 +968,7 @@ kern_return_t thread_halt(
* operation can never cause a deadlock.)
*/
if (cur_thread->ast & AST_HALT) {
- thread_wakeup_with_result((event_t)&cur_thread->wake_active,
+ thread_wakeup_with_result(TH_EV_WAKE_ACTIVE(cur_thread),
THREAD_INTERRUPTED);
thread_unlock(thread);
thread_unlock(cur_thread);
@@ -988,7 +1006,7 @@ kern_return_t thread_halt(
*/
while ((thread->ast & AST_HALT) && (!(thread->state & TH_HALTED))) {
thread->wake_active = TRUE;
- thread_sleep((event_t) &thread->wake_active,
+ thread_sleep(TH_EV_WAKE_ACTIVE(thread),
simple_lock_addr(thread->lock), TRUE);
if (thread->state & TH_HALTED) {
@@ -1027,7 +1045,7 @@ kern_return_t thread_halt(
s = splsched();
thread_lock(thread);
thread_ast_clear(thread, AST_HALT);
- thread_wakeup_with_result((event_t)&thread->wake_active,
+ thread_wakeup_with_result(TH_EV_WAKE_ACTIVE(thread),
THREAD_INTERRUPTED);
thread_unlock(thread);
(void) splx(s);
@@ -1105,7 +1123,7 @@ kern_return_t thread_halt(
}
}
-void walking_zombie(void)
+void __attribute__((noreturn)) walking_zombie(void)
{
panic("the zombie walks!");
}
@@ -1116,7 +1134,7 @@ void walking_zombie(void)
*/
void thread_halt_self(void)
{
- register thread_t thread = current_thread();
+ thread_t thread = current_thread();
spl_t s;
if (thread->ast & AST_TERMINATE) {
@@ -1131,7 +1149,7 @@ void thread_halt_self(void)
s = splsched();
simple_lock(&reaper_lock);
- enqueue_tail(&reaper_queue, (queue_entry_t) thread);
+ enqueue_tail(&reaper_queue, &(thread->links));
simple_unlock(&reaper_lock);
thread_lock(thread);
@@ -1170,7 +1188,7 @@ void thread_halt_self(void)
* suspends is maintained.
*/
void thread_hold(
- register thread_t thread)
+ thread_t thread)
{
spl_t s;
@@ -1192,11 +1210,11 @@ void thread_hold(
*/
kern_return_t
thread_dowait(
- register thread_t thread,
+ thread_t thread,
boolean_t must_halt)
{
- register boolean_t need_wakeup;
- register kern_return_t ret = KERN_SUCCESS;
+ boolean_t need_wakeup;
+ kern_return_t ret = KERN_SUCCESS;
spl_t s;
if (thread == current_thread())
@@ -1266,7 +1284,7 @@ thread_dowait(
* Check for failure if interrupted.
*/
thread->wake_active = TRUE;
- thread_sleep((event_t) &thread->wake_active,
+ thread_sleep(TH_EV_WAKE_ACTIVE(thread),
simple_lock_addr(thread->lock), TRUE);
thread_lock(thread);
if ((current_thread()->wait_result != THREAD_AWAKENED) &&
@@ -1290,13 +1308,13 @@ thread_dowait(
(void) splx(s);
if (need_wakeup)
- thread_wakeup((event_t) &thread->wake_active);
+ thread_wakeup(TH_EV_WAKE_ACTIVE(thread));
return ret;
}
void thread_release(
- register thread_t thread)
+ thread_t thread)
{
spl_t s;
@@ -1315,9 +1333,9 @@ void thread_release(
}
kern_return_t thread_suspend(
- register thread_t thread)
+ thread_t thread)
{
- register boolean_t hold;
+ boolean_t hold;
spl_t spl;
if (thread == THREAD_NULL)
@@ -1328,7 +1346,7 @@ kern_return_t thread_suspend(
thread_lock(thread);
/* Wait for thread to get interruptible */
while (thread->state & TH_UNINT) {
- assert_wait(&thread->state, TRUE);
+ assert_wait(TH_EV_STATE(thread), TRUE);
thread_unlock(thread);
thread_block(NULL);
thread_lock(thread);
@@ -1361,9 +1379,9 @@ kern_return_t thread_suspend(
kern_return_t thread_resume(
- register thread_t thread)
+ thread_t thread)
{
- register kern_return_t ret;
+ kern_return_t ret;
spl_t s;
if (thread == THREAD_NULL)
@@ -1399,7 +1417,7 @@ kern_return_t thread_resume(
* Return thread's machine-dependent state.
*/
kern_return_t thread_get_state(
- register thread_t thread,
+ thread_t thread,
int flavor,
thread_state_t old_state, /* pointer to OUT array */
natural_t *old_state_count) /*IN/OUT*/
@@ -1423,7 +1441,7 @@ kern_return_t thread_get_state(
* Change thread's machine-dependent state.
*/
kern_return_t thread_set_state(
- register thread_t thread,
+ thread_t thread,
int flavor,
thread_state_t new_state,
natural_t new_state_count)
@@ -1444,7 +1462,7 @@ kern_return_t thread_set_state(
}
kern_return_t thread_info(
- register thread_t thread,
+ thread_t thread,
int flavor,
thread_info_t thread_info_out, /* pointer to OUT array */
natural_t *thread_info_count) /*IN/OUT*/
@@ -1456,7 +1474,7 @@ kern_return_t thread_info(
return KERN_INVALID_ARGUMENT;
if (flavor == THREAD_BASIC_INFO) {
- register thread_basic_info_t basic_info;
+ thread_basic_info_t basic_info;
/* Allow *thread_info_count to be one smaller than the
usual amount, because creation_time is a new member
@@ -1542,7 +1560,7 @@ kern_return_t thread_info(
return KERN_SUCCESS;
}
else if (flavor == THREAD_SCHED_INFO) {
- register thread_sched_info_t sched_info;
+ thread_sched_info_t sched_info;
if (*thread_info_count < THREAD_SCHED_INFO_COUNT) {
return KERN_INVALID_ARGUMENT;
@@ -1584,7 +1602,7 @@ kern_return_t thread_info(
}
kern_return_t thread_abort(
- register thread_t thread)
+ thread_t thread)
{
if (thread == THREAD_NULL || thread == current_thread()) {
return KERN_INVALID_ARGUMENT;
@@ -1649,9 +1667,13 @@ thread_t kernel_thread(
continuation_t start,
void * arg)
{
+ kern_return_t kr;
thread_t thread;
- (void) thread_create(task, &thread);
+ kr = thread_create(task, &thread);
+ if (kr != KERN_SUCCESS)
+ return THREAD_NULL;
+
/* release "extra" ref that thread_create gave us */
thread_deallocate(thread);
thread_start(thread, start);
@@ -1675,10 +1697,10 @@ thread_t kernel_thread(
* This kernel thread runs forever looking for threads to destroy
* (when they request that they be destroyed, of course).
*/
-void reaper_thread_continue(void)
+void __attribute__((noreturn)) reaper_thread_continue(void)
{
for (;;) {
- register thread_t thread;
+ thread_t thread;
spl_t s;
s = splsched();
@@ -1793,12 +1815,12 @@ thread_unfreeze(
void
thread_doassign(
- register thread_t thread,
- register processor_set_t new_pset,
+ thread_t thread,
+ processor_set_t new_pset,
boolean_t release_freeze)
{
- register processor_set_t pset;
- register boolean_t old_empty, new_empty;
+ processor_set_t pset;
+ boolean_t old_empty, new_empty;
boolean_t recompute_pri = FALSE;
spl_t s;
@@ -1956,6 +1978,9 @@ kern_return_t thread_get_assignment(
thread_t thread,
processor_set_t *pset)
{
+ if (thread == THREAD_NULL)
+ return KERN_INVALID_ARGUMENT;
+
*pset = thread->processor_set;
pset_reference(*pset);
return KERN_SUCCESS;
@@ -2101,8 +2126,8 @@ thread_policy(
int data)
{
#if MACH_FIXPRI
- register kern_return_t ret = KERN_SUCCESS;
- register int temp;
+ kern_return_t ret = KERN_SUCCESS;
+ int temp;
spl_t s;
#endif /* MACH_FIXPRI */
@@ -2218,7 +2243,6 @@ thread_wire(
void thread_collect_scan(void)
{
-#if 0
register thread_t thread, prev_thread;
processor_set_t pset, prev_pset;
@@ -2271,7 +2295,6 @@ void thread_collect_scan(void)
thread_deallocate(prev_thread);
if (prev_pset != PROCESSOR_SET_NULL)
pset_deallocate(prev_pset);
-#endif /* 0 */
}
boolean_t thread_collect_allowed = TRUE;
@@ -2305,7 +2328,7 @@ void consider_thread_collect(void)
#if MACH_DEBUG
vm_size_t stack_usage(
- register vm_offset_t stack)
+ vm_offset_t stack)
{
int i;
@@ -2322,7 +2345,7 @@ vm_size_t stack_usage(
*/
void stack_init(
- register vm_offset_t stack)
+ vm_offset_t stack)
{
if (stack_check_usage) {
int i;
@@ -2338,7 +2361,7 @@ void stack_init(
*/
void stack_finalize(
- register vm_offset_t stack)
+ vm_offset_t stack)
{
if (stack_check_usage) {
vm_size_t used = stack_usage(stack);
@@ -2431,8 +2454,8 @@ kern_return_t processor_set_stack_usage(
vm_size_t maxusage;
vm_offset_t maxstack;
- register thread_t *threads;
- register thread_t tmp_thread;
+ thread_t *threads;
+ thread_t tmp_thread;
unsigned int actual; /* this many things */
unsigned int i;
@@ -2550,7 +2573,7 @@ kern_return_t processor_set_stack_usage(
void
thread_stats(void)
{
- register thread_t thread;
+ thread_t thread;
int total = 0, rpcreply = 0;
queue_iterate(&default_pset.threads, thread, thread_t, pset_threads) {
diff --git a/kern/thread.h b/kern/thread.h
index 3959dfce..0e85d8c4 100644
--- a/kern/thread.h
+++ b/kern/thread.h
@@ -70,6 +70,22 @@ struct thread {
task_t task; /* Task to which I belong */
queue_chain_t thread_list; /* list of threads in task */
+ /* Flags */
+ /* The flags are grouped here, but documented at the original
+ position. */
+ union {
+ struct {
+ unsigned state:16;
+ unsigned wake_active:1;
+ unsigned vm_privilege:1;
+ unsigned active:1;
+ };
+ event_t event_key;
+/* These keys can be used with thread_wakeup and friends. */
+#define TH_EV_WAKE_ACTIVE(t) ((event_t) (&(t)->event_key + 0))
+#define TH_EV_STATE(t) ((event_t) (&(t)->event_key + 1))
+ };
+
/* Thread bookkeeping */
queue_chain_t pset_threads; /* list of all threads in proc set*/
@@ -92,9 +108,10 @@ struct thread {
kern_return_t wait_result; /* outcome of wait -
may be examined by this thread
WITHOUT locking */
- boolean_t wake_active; /* someone is waiting for this
+ /* Defined above */
+ /* boolean_t wake_active; someone is waiting for this
thread to become suspended */
- int state; /* Thread state: */
+ /* int state; Thread state: */
/*
* Thread states [bits or'ed]
*/
@@ -129,7 +146,8 @@ struct thread {
/* VM global variables */
vm_offset_t recover; /* page fault recovery (copyin/out) */
- boolean_t vm_privilege; /* Can use reserved memory? */
+ /* Defined above */
+ /* boolean_t vm_privilege; Can use reserved memory? */
/* User-visible scheduling state */
int user_stop_count; /* outstanding stops */
@@ -194,7 +212,8 @@ struct thread {
timer_elt_data_t depress_timer; /* timer for priority depression */
/* Ast/Halt data structures */
- boolean_t active; /* how alive is the thread */
+ /* Defined above */
+ /* boolean_t active; how alive is the thread */
int ast; /* ast's needed. See ast.h */
/* Processor data structures */
@@ -259,6 +278,13 @@ extern kern_return_t thread_create(
thread_t *child_thread);
extern kern_return_t thread_terminate(
thread_t thread);
+extern kern_return_t thread_terminate_release(
+ thread_t thread,
+ task_t task,
+ mach_port_t thread_name,
+ mach_port_t reply_port,
+ vm_offset_t address,
+ vm_size_t size);
extern kern_return_t thread_suspend(
thread_t thread);
extern kern_return_t thread_resume(
@@ -338,14 +364,12 @@ extern kern_return_t thread_halt(
boolean_t must_halt);
extern void thread_halt_self(void);
extern void thread_force_terminate(thread_t);
-extern void thread_set_own_priority(
- int priority);
extern thread_t kernel_thread(
task_t task,
void (*start)(void),
void * arg);
-extern void reaper_thread(void);
+extern void reaper_thread(void) __attribute__((noreturn));
#if MACH_HOST
extern void thread_freeze(
@@ -384,4 +408,9 @@ extern void thread_unfreeze(
#define current_space() (current_task()->itk_space)
#define current_map() (current_task()->map)
+#if MACH_DEBUG
+void stack_init(vm_offset_t stack);
+void stack_finalize(vm_offset_t stack);
+#endif /* MACH_DEBUG */
+
#endif /* _KERN_THREAD_H_ */
diff --git a/kern/thread_swap.c b/kern/thread_swap.c
index f29bd5b7..20ad0409 100644
--- a/kern/thread_swap.c
+++ b/kern/thread_swap.c
@@ -86,8 +86,7 @@ void swapper_init(void)
* our callers have already tried that route.
*/
-void thread_swapin(thread)
- thread_t thread;
+void thread_swapin(thread_t thread)
{
switch (thread->state & TH_SWAP_STATE) {
case TH_SWAPPED:
@@ -97,7 +96,7 @@ void thread_swapin(thread)
thread->state = (thread->state & ~TH_SWAP_STATE)
| TH_SW_COMING_IN;
swapper_lock();
- enqueue_tail(&swapin_queue, (queue_entry_t) thread);
+ enqueue_tail(&swapin_queue, &(thread->links));
swapper_unlock();
thread_wakeup((event_t) &swapin_queue);
break;
@@ -124,16 +123,18 @@ void thread_swapin(thread)
* it on a run queue. No locks should be held on entry, as it is
* likely that this routine will sleep (waiting for stack allocation).
*/
-void thread_doswapin(thread)
- register thread_t thread;
+kern_return_t thread_doswapin(thread_t thread)
{
+ kern_return_t kr;
spl_t s;
/*
* Allocate the kernel stack.
*/
- stack_alloc(thread, thread_continue);
+ kr = stack_alloc(thread, thread_continue);
+ if (kr != KERN_SUCCESS)
+ return kr;
/*
* Place on run queue.
@@ -146,6 +147,7 @@ void thread_doswapin(thread)
thread_setrun(thread, TRUE);
thread_unlock(thread);
(void) splx(s);
+ return KERN_SUCCESS;
}
/*
@@ -154,10 +156,10 @@ void thread_doswapin(thread)
* This procedure executes as a kernel thread. Threads that need to
* be swapped in are swapped in by this thread.
*/
-void swapin_thread_continue(void)
+void __attribute__((noreturn)) swapin_thread_continue(void)
{
for (;;) {
- register thread_t thread;
+ thread_t thread;
spl_t s;
s = splsched();
@@ -165,13 +167,20 @@ void swapin_thread_continue(void)
while ((thread = (thread_t) dequeue_head(&swapin_queue))
!= THREAD_NULL) {
+ kern_return_t kr;
swapper_unlock();
(void) splx(s);
- thread_doswapin(thread); /* may block */
+ kr = thread_doswapin(thread); /* may block */
s = splsched();
swapper_lock();
+
+ if (kr != KERN_SUCCESS) {
+ enqueue_head(&swapin_queue,
+ (queue_entry_t) thread);
+ break;
+ }
}
assert_wait((event_t) &swapin_queue, FALSE);
diff --git a/kern/thread_swap.h b/kern/thread_swap.h
index 31130301..d032accf 100644
--- a/kern/thread_swap.h
+++ b/kern/thread_swap.h
@@ -37,8 +37,7 @@
*/
extern void swapper_init(void);
extern void thread_swapin(thread_t thread);
-extern void thread_doswapin(thread_t thread);
-extern void swapin_thread(void);
-extern void thread_swapout(thread_t thread);
+extern kern_return_t thread_doswapin(thread_t thread);
+extern void swapin_thread(void) __attribute__((noreturn));
#endif /* _KERN_THREAD_SWAP_H_ */
diff --git a/kern/time_stamp.c b/kern/time_stamp.c
index 22885b18..ee141a0e 100644
--- a/kern/time_stamp.c
+++ b/kern/time_stamp.c
@@ -32,31 +32,18 @@
/*
* ts.c - kern_timestamp system call.
*/
-#ifdef multimax
-#include <mmax/timer.h>
-#endif /* multimax */
-
-
-
kern_return_t
-kern_timestamp(tsp)
-struct tsval *tsp;
+kern_timestamp(struct tsval *tsp)
{
-#ifdef multimax
- struct tsval temp;
- temp.low_val = FRcounter;
- temp.high_val = 0;
-#else /* multimax */
/*
temp.low_val = 0;
temp.high_val = ts_tick_count;
*/
time_value_t temp;
temp = time;
-#endif /* multimax */
- if (copyout((char *)&temp,
- (char *)tsp,
+ if (copyout(&temp,
+ tsp,
sizeof(struct tsval)) != KERN_SUCCESS)
return(KERN_INVALID_ADDRESS);
return(KERN_SUCCESS);
@@ -66,10 +53,7 @@ struct tsval *tsp;
* Initialization procedure.
*/
-void timestamp_init()
+void timestamp_init(void)
{
-#ifdef multimax
-#else /* multimax */
ts_tick_count = 0;
-#endif /* multimax */
}
diff --git a/kern/timer.c b/kern/timer.c
index ec0524a8..79ada27e 100644
--- a/kern/timer.c
+++ b/kern/timer.c
@@ -33,24 +33,22 @@
#include <kern/cpu_number.h>
#include <kern/assert.h>
-#include <kern/macro_help.h>
+#include <kern/macros.h>
timer_t current_timer[NCPUS];
timer_data_t kernel_timer[NCPUS];
-void timer_init(); /* forward */
-
/*
* init_timers initializes all non-thread timers and puts the
* service routine on the callout queue. All timers must be
* serviced by the callout routine once an hour.
*/
-void init_timers()
+void init_timers(void)
{
- register int i;
- register timer_t this_timer;
+ int i;
+ timer_t this_timer;
/*
* Initialize all the kernel timers and start the one
@@ -68,9 +66,7 @@ void init_timers()
/*
* timer_init initializes a single timer.
*/
-void timer_init(this_timer)
-register
-timer_t this_timer;
+void timer_init(timer_t this_timer)
{
this_timer->low_bits = 0;
this_timer->high_bits = 0;
@@ -94,8 +90,7 @@ timer_t this_timer;
* exactly once for each cpu during the boot sequence.
*/
void
-start_timer(timer)
-timer_t timer;
+start_timer(timer_t timer)
{
timer->tstamp = get_timestamp();
current_timer[cpu_number()] = timer;
@@ -108,8 +103,7 @@ timer_t timer;
* from user mode.
*/
void
-time_trap_uentry(ts)
-unsigned ts;
+time_trap_uentry(unsigned ts)
{
int elapsed;
int mycpu;
@@ -150,7 +144,7 @@ unsigned ts;
* user mode.
*/
void
-time_trap_uexit(ts)
+time_trap_uexit(int ts)
{
int elapsed;
int mycpu;
@@ -194,9 +188,9 @@ time_trap_uexit(ts)
* saved for time_int_exit.
*/
timer_t
-time_int_entry(ts,new_timer)
-unsigned ts;
-timer_t new_timer;
+time_int_entry(
+ unsigned ts,
+ timer_t new_timer)
{
int elapsed;
int mycpu;
@@ -235,9 +229,9 @@ timer_t new_timer;
* it.
*/
void
-time_int_exit(ts, old_timer)
-unsigned ts;
-timer_t old_timer;
+time_int_exit(
+ unsigned ts,
+ timer_t old_timer)
{
int elapsed;
int mycpu;
@@ -282,8 +276,7 @@ timer_t old_timer;
* Caller must lock out interrupts.
*/
void
-timer_switch(new_timer)
-timer_t new_timer;
+timer_switch(timer_t new_timer)
{
int elapsed;
int mycpu;
@@ -328,9 +321,7 @@ timer_t new_timer;
* timer_normalize normalizes the value of a timer. It is
* called only rarely, to make sure low_bits never overflows.
*/
-void timer_normalize(timer)
-register
-timer_t timer;
+void timer_normalize(timer_t timer)
{
unsigned int high_increment;
@@ -356,9 +347,9 @@ timer_t timer;
* Keep coherent with db_time_grab below.
*/
-static void timer_grab(timer, save)
-timer_t timer;
-timer_save_t save;
+static void timer_grab(
+ timer_t timer,
+ timer_save_t save)
{
#if MACH_ASSERT
unsigned int passes=0;
@@ -390,9 +381,9 @@ timer_save_t save;
* above.
*
*/
-void db_timer_grab(timer, save)
-timer_t timer;
-timer_save_t save;
+void db_timer_grab(
+ timer_t timer,
+ timer_save_t save)
{
/* Don't worry about coherency */
@@ -409,10 +400,9 @@ timer_save_t save;
*/
void
-timer_read(timer, tv)
-timer_t timer;
-register
-time_value_t *tv;
+timer_read(
+ timer_t timer,
+ time_value_t *tv)
{
timer_save_data_t temp;
@@ -436,13 +426,13 @@ time_value_t *tv;
*
* Needs to be kept coherent with thread_read_times ahead.
*/
-void thread_read_times(thread, user_time_p, system_time_p)
- thread_t thread;
- time_value_t *user_time_p;
- time_value_t *system_time_p;
+void thread_read_times(
+ thread_t thread,
+ time_value_t *user_time_p,
+ time_value_t *system_time_p)
{
timer_save_data_t temp;
- register timer_t timer;
+ timer_t timer;
timer = &thread->user_timer;
timer_grab(timer, &temp);
@@ -470,13 +460,13 @@ void thread_read_times(thread, user_time_p, system_time_p)
* thread_read_times above.
*
*/
-void db_thread_read_times(thread, user_time_p, system_time_p)
- thread_t thread;
- time_value_t *user_time_p;
- time_value_t *system_time_p;
+void db_thread_read_times(
+ thread_t thread,
+ time_value_t *user_time_p,
+ time_value_t *system_time_p)
{
timer_save_data_t temp;
- register timer_t timer;
+ timer_t timer;
timer = &thread->user_timer;
db_timer_grab(timer, &temp);
@@ -505,13 +495,12 @@ void db_thread_read_times(thread, user_time_p, system_time_p)
*/
unsigned
-timer_delta(timer, save)
-register
-timer_t timer;
-timer_save_t save;
+timer_delta(
+ timer_t timer,
+ timer_save_t save)
{
timer_save_data_t new_save;
- register unsigned result;
+ unsigned result;
timer_grab(timer,&new_save);
result = (new_save.high - save->high) * TIMER_HIGH_UNIT +
diff --git a/kern/timer.h b/kern/timer.h
index 817fa356..2f473cf8 100644
--- a/kern/timer.h
+++ b/kern/timer.h
@@ -27,7 +27,7 @@
#ifndef _KERN_TIMER_H_
#define _KERN_TIMER_H_
-#include <kern/macro_help.h>
+#include <kern/macros.h>
#if STAT_TIME
/*
@@ -168,7 +168,7 @@ extern void time_int_exit(unsigned, timer_t);
#define TIMER_DELTA(timer, save, result) \
MACRO_BEGIN \
- register unsigned temp; \
+ unsigned temp; \
\
temp = (timer).low_bits; \
if ((save).high != (timer).high_bits_check) { \
@@ -182,4 +182,6 @@ MACRO_END
extern void init_timers(void);
+void timer_init(timer_t this_timer);
+
#endif /* _KERN_TIMER_H_ */
diff --git a/kern/xpr.c b/kern/xpr.c
index 465ba7bb..46cb2273 100644
--- a/kern/xpr.c
+++ b/kern/xpr.c
@@ -56,12 +56,16 @@ struct xprbuf *xprptr; /* Currently allocated xprbuf */
struct xprbuf *xprlast; /* Pointer to end of circular buffer */
/*VARARGS1*/
-void xpr(msg, arg1, arg2, arg3, arg4, arg5)
-char *msg;
-int arg1, arg2, arg3, arg4, arg5;
+void xpr(
+ char *msg,
+ int arg1,
+ int arg2,
+ int arg3,
+ int arg4,
+ int arg5)
{
- register spl_t s;
- register struct xprbuf *x;
+ spl_t s;
+ struct xprbuf *x;
/* If we aren't initialized, ignore trace request */
if (!xprenable || (xprptr == 0))
@@ -115,7 +119,7 @@ void xprbootstrap(void)
* the previous buffer contents.
*/
- memset((char *) addr, 0, size);
+ memset((void *) addr, 0, size);
}
xprbase = (struct xprbuf *) addr;
@@ -132,9 +136,8 @@ void xprinit(void)
#if MACH_KDB
#include <machine/setjmp.h>
+#include <ddb/db_output.h>
-
-extern void db_printf();
extern jmp_buf_t *db_recover;
/*
@@ -145,16 +148,16 @@ extern jmp_buf_t *db_recover;
* Called with arguments, it can dump xpr buffers in user tasks,
* assuming they use the same format as the kernel.
*/
-void xpr_dump(base, nbufs)
- struct xprbuf *base;
- int nbufs;
+void xpr_dump(
+ struct xprbuf *base,
+ int nbufs)
{
jmp_buf_t db_jmpbuf;
jmp_buf_t *prev;
struct xprbuf *last, *ptr;
- register struct xprbuf *x;
+ struct xprbuf *x;
int i;
- spl_t s;
+ spl_t s = s;
if (base == 0) {
base = xprbase;
diff --git a/kern/xpr.h b/kern/xpr.h
index 4a06216a..72f68170 100644
--- a/kern/xpr.h
+++ b/kern/xpr.h
@@ -34,7 +34,7 @@
* which will expand into the following code:
* if (xprflags & XPR_SYSCALLS)
* xpr("syscall: %d, 0x%x\n", syscallno, arg1);
- * Xpr will log the pointer to the printf string and up to 6 arguements,
+ * Xpr will log the pointer to the printf string and up to 6 arguments,
* along with a timestamp and cpuinfo (for multi-processor systems), into
* a circular buffer. The actual printf processing is delayed until after
* the buffer has been collected. It is assumed that the text/data segments