[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnumach] 01/01: Imported Upstream version 1.6+git20160502
From: |
Samuel Thibault |
Subject: |
[gnumach] 01/01: Imported Upstream version 1.6+git20160502 |
Date: |
Tue, 03 May 2016 00:37:41 +0000 |
This is an automated email from the git hooks/post-receive script.
sthibault pushed a commit to branch upstream
in repository gnumach.
commit 17ba451bfe5a5f26423350ba422f302bbc1b5909
Author: Samuel Thibault <address@hidden>
Date: Mon May 2 22:50:50 2016 +0000
Imported Upstream version 1.6+git20160502
---
ChangeLog | 133 ++++++++++
Makefile.am | 2 +-
Makefile.in | 106 ++++----
Makefrag.am | 2 +
NEWS | 19 ++
config.h.in | 6 +
configfrag.ac | 11 +
configure | 81 +++++-
ddb/db_elf.c | 10 +-
doc/mach.info | 4 +-
doc/mach.info-1 | 8 +-
doc/mach.info-2 | 4 +-
doc/stamp-vti | 8 +-
doc/version.texi | 8 +-
i386/Makefrag.am | 4 +-
i386/configfrag.ac | 5 +
i386/i386/hardclock.c | 9 +-
i386/i386/pcb.c | 2 +-
i386/i386/spl.S | 9 +
i386/i386/xen.h | 4 +-
i386/i386at/model_dep.c | 15 +-
i386/include/mach/i386/machine_types.defs | 4 +-
i386/include/mach/i386/vm_types.h | 24 --
i386/xen/xen.c | 7 +-
include/device/device_types.defs | 6 +-
include/mach/gnumach.defs | 52 ++++
include/mach/kern_return.h | 6 +
include/mach/std_types.defs | 8 +-
include/stdint.h | 55 ++++
include/sys/types.h | 15 +-
ipc/ipc_kmsg.c | 8 +-
kern/exception.c | 2 +-
kern/gsync.c | 413 ++++++++++++++++++++++++++++++
kern/gsync.h | 41 +++
kern/mach_clock.c | 10 +-
kern/mach_clock.h | 3 +-
kern/pc_sample.c | 10 +-
kern/pc_sample.h | 10 +-
kern/rdxtree.h | 2 +-
kern/startup.c | 3 +
linux/dev/include/linux/types.h | 10 -
version.m4 | 2 +-
vm/vm_fault.c | 2 +-
vm/vm_resident.c | 6 +-
xen/block.c | 4 +-
xen/net.c | 12 +-
xen/public/elfstructs.h | 2 +-
xen/ring.h | 2 +-
xen/store.c | 4 +-
xen/store.h | 2 +-
xen/time.c | 32 +--
xen/time.h | 2 +-
52 files changed, 1003 insertions(+), 206 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index b909aba..7c95736 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,136 @@
+2016-04-21 Samuel Thibault <address@hidden>
+
+ Fix xen boot
+ * i386/i386/pcb.c (pcb_init): Make sure there is a thread before calling
+ current_task().
+
+2016-04-20 Justus Winter <address@hidden>
+
+ Fix type of program counter argument
+ * i386/i386/hardclock.c (hardclock): Use '0' instead of 'NULL'.
+ * vm/vm_fault (vm_fault_cleanup): Likewise.
+
+ xen: fix build
+ * i386/xen/xen.c (hypclock_machine_intr): Fix 'clock_interrupt' call.
+ * xen/time.c (clkstart): Likewise.
+
+2016-04-20 Samuel Thibault <address@hidden>
+
+ Add kernel profiling through sampling
+ * NEWS: Advertise feature.
+ * configfrac.ac (--enable-kernsample): Add option.
+ * kern/pc_sample.h (take_pc_sample): Add usermode and pc parameter.
+ (take_pc_sample_macro): Take usermode and pc parameters, pass as such to
+ take_pc_sample.
+ * kern/pc_sample.c (take_pc_sample): Use pc parameter when usermode is
1.
+ * kern/mach_clock.c (clock_interrupt): Add pc parameter. Pass usermode
and
+ pc to take_pc_sample_macro call.
+ * i386/i386/hardclock.c (hardclock): Pass regs->eip to clock_interrupt
call
+ on normal interrupts, NULL on interrupt interrupt.
+ * vm/vm_fault.c (vm_fault_cleanup): Set usermode to 1 and pc to NULL in
+ take_pc_sample_macro call.
+
+2016-04-17 Samuel Thibault <address@hidden>
+
+ Add memory barrier to spl*
+ * i386/i386/spl.S (mb): Define macro
+ (SETIPL, spl0, spl7): Call mb.
+
+ Avoid using C99 for variable declaration for now
+ * kern/gsync.c (gsync_setup): Declare `i' variable out of for loop.
+
+2016-04-15 Samuel Thibault <address@hidden>
+
+ update NEWS file
+
+2016-04-15 Agustina Arzille <address@hidden>
+
+ Lightweight synchronization mechanism
+ * Makefrag.am (libkernel_a_SOURCES): Add kern/gsync.c and kern/gsync.h.
+ * include/mach/gnumach.defs (gsync_wait, gsync_wake, gsync_requeue): New
+ routines.
+ * include/mach/kern_return.h (KERN_TIMEDOUT, KERN_INTERRUPTED): New
error
+ codes.
+ * kern/gsync.c: New file.
+ * kern/gsync.h: New file.
+ * kern/startup.c: Include <kern/gsync.h>
+ (setup_main): Call gsync_setup.
+
+2016-04-15 Justus Winter <address@hidden>
+
+ Update NEWS file
+
+ Add --disable-assert flag to disable assertions
+ * configfrag.ac: Use 'AC_HEADER_ASSERT'.
+
+ i386: Fix error handling
+ * i386/i386at/model_dep.c (i386at_init): Fix error handling.
+
+2016-04-05 Flavio Cruz <address@hidden>
+
+ Fix bootstraping issues with stdint.h.
+ * include/mach/std_types.h: Do not include stdint.h.
+ * kern/rdxtree.h: Replace sys/types.h with stdint.h.
+
+2016-04-04 Samuel Thibault <address@hidden>
+
+ Follow-up stdint use
+ 7bbfa39f59dcbc55b21d31abb9e2febef6a51ebb ('Use uint32_t instead of
+ unsigned32_t.') missed some Xen code
+
+ * xen/net.c (recompute_checksum): Use stdint.h types.
+ * xen/time.c (hyp_get_stime): Likewise.
+
+2016-04-04 Flavio Cruz <address@hidden>
+
+ Use uint32_t instead of unsigned32_t.
+ Implement stdint.h and use it in gnumach.
+
+ Remove old type definitions such as signed* and unsigned*.
+
+ * Makefile.am: Add -ffreestanding.
+ * i386/i386/xen.h: Use uint64_t.
+ * i386/include/mach/i386/machine_types.defs: Use uint32_t and int32_t.
+ * i386/include/mach/i386/vm_types.h: Remove definitions of int*, uint*,
+ unsigned* and signed* types.
+ * i386/xen/xen.c: Use uint64_t.
+ * include/device/device_types.defs: Use uint32_t.
+ * include/mach/std_types.defs: Use POSIX types.
+ * include/mach/std_types.h: Include stdint.h.
+ * include/stdint.h: New file with POSIX types.
+ * include/sys/types.h: Include stdint.h.
+ * ipc/ipc_kmsg.c: Use uint64_t.
+ * kern/exception.c: Use uint32_t.
+ * linux/dev/include/linux/types.h: Remove POSIX types.
+ * xen/block.c: Use uint64_t.
+ * xen/net.c: Do not use removed unsigned*_t types.
+ * xen/ring.h: Use uint32_t instead.
+ * xen/store.c: Use uint32_t.
+ * xen/store.h: Use uint32_t.
+ * xen/time.c: Use POSIX types only.
+ * xen/time.h: Use uint64_t.
+
+2016-03-19 Samuel Thibault <address@hidden>
+
+ Make kernel mapping start address configurable
+ and move it to 16MiB by default to free 24bit DMA area
+
+ * i386/configfrag.ac (--with-_START_MAP): Add option, default to
0x1000000.
+ * i386/Makefrag.am (_START_MAP): Set to $(_START_MAP).
+ (_START): Set to _START_MAP+0xC0000000.
+
+2016-03-19 Samuel Thibault <address@hidden>
+
+ Fix getting ELF symbol bind and type
+ ddb/db_elf.c (elf_db_search_symbol): Use ELF32_ST_BIND and
ELF32_ST_TYPE to
+ access symbol bind and type.
+
+2016-03-13 Richard Braun <address@hidden>
+
+ Avoid panics on physical memory exhaustion
+ * vm/vm_resident (vm_page_grab_contig): Return NULL instead of calling
+ panic on memory exhaustion.
+
2016-03-11 Samuel Thibault <address@hidden>
Ship missing files
diff --git a/Makefile.am b/Makefile.am
index 1c1bfff..bbcfc11 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -42,7 +42,7 @@ AM_LDFLAGS =
#
AM_CPPFLAGS += \
- -nostdinc -imacros config.h
+ -ffreestanding -nostdinc -imacros config.h
AM_CPPFLAGS += \
-I$(systype) \
diff --git a/Makefile.in b/Makefile.in
index 23a8556..f38eef3 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1144,8 +1144,8 @@ noinst_PROGRAMS = gnumach.o$(EXEEXT)
@HOST_ix86_TRUE@ i386/i386/mach_i386.server.msgids \
@HOST_ix86_TRUE@ i386/i386/i386asm.h
@HOST_ix86_TRUE@@address@hidden = \
address@hidden@@PLATFORM_at_TRUE@ --defsym _START=0xC0100000 \
address@hidden@@PLATFORM_at_TRUE@ --defsym _START_MAP=0x100000 \
address@hidden@@PLATFORM_at_TRUE@ --defsym _START_MAP=$(_START_MAP) \
address@hidden@@PLATFORM_at_TRUE@ --defsym _START=_START_MAP+0xC0000000 \
@HOST_ix86_TRUE@@PLATFORM_at_TRUE@ -T '$(srcdir)'/i386/ldscript
@address@hidden = \
@@ -1249,20 +1249,20 @@ am__libkernel_a_SOURCES_DIST = ddb/db_access.c
ddb/db_access.h \
kern/boot_script.h kern/bootstrap.c kern/bootstrap.h \
kern/counters.c kern/counters.h kern/cpu_number.h kern/debug.c \
kern/debug.h kern/eventcount.c kern/eventcount.h \
- kern/exception.c kern/exception.h kern/host.c kern/host.h \
- kern/ipc_host.c kern/ipc_host.h kern/ipc_kobject.c \
- kern/ipc_kobject.h kern/ipc_mig.c kern/ipc_mig.h \
- kern/ipc_sched.c kern/ipc_sched.h kern/ipc_tt.c kern/ipc_tt.h \
- kern/kalloc.h kern/kern_types.h kern/list.h kern/lock.c \
- kern/lock.h kern/lock_mon.c kern/log2.h kern/mach_clock.c \
- kern/mach_clock.h kern/mach_factor.c kern/mach_factor.h \
- kern/machine.c kern/machine.h kern/macros.h kern/pc_sample.c \
- kern/pc_sample.h kern/printf.c kern/printf.h kern/priority.c \
- kern/priority.h kern/processor.c kern/processor.h \
- kern/profile.c kern/queue.c kern/queue.h kern/rbtree.c \
- kern/rbtree.h kern/rbtree_i.h kern/rdxtree.c kern/rdxtree.h \
- kern/rdxtree_i.h kern/refcount.h kern/slab.c kern/slab.h \
- kern/sched.h kern/sched_prim.c kern/sched_prim.h \
+ kern/exception.c kern/exception.h kern/gsync.c kern/gsync.h \
+ kern/host.c kern/host.h kern/ipc_host.c kern/ipc_host.h \
+ kern/ipc_kobject.c kern/ipc_kobject.h kern/ipc_mig.c \
+ kern/ipc_mig.h kern/ipc_sched.c kern/ipc_sched.h kern/ipc_tt.c \
+ kern/ipc_tt.h kern/kalloc.h kern/kern_types.h kern/list.h \
+ kern/lock.c kern/lock.h kern/lock_mon.c kern/log2.h \
+ kern/mach_clock.c kern/mach_clock.h kern/mach_factor.c \
+ kern/mach_factor.h kern/machine.c kern/machine.h kern/macros.h \
+ kern/pc_sample.c kern/pc_sample.h kern/printf.c kern/printf.h \
+ kern/priority.c kern/priority.h kern/processor.c \
+ kern/processor.h kern/profile.c kern/queue.c kern/queue.h \
+ kern/rbtree.c kern/rbtree.h kern/rbtree_i.h kern/rdxtree.c \
+ kern/rdxtree.h kern/rdxtree_i.h kern/refcount.h kern/slab.c \
+ kern/slab.h kern/sched.h kern/sched_prim.c kern/sched_prim.h \
kern/shuttle.h kern/startup.c kern/startup.h kern/strings.c \
kern/syscall_emulation.c kern/syscall_emulation.h \
kern/syscall_subr.c kern/syscall_subr.h kern/syscall_sw.c \
@@ -1461,25 +1461,25 @@ am_libkernel_a_OBJECTS = $(am__objects_2)
ipc/ipc_entry.$(OBJEXT) \
ipc/mach_debug.$(OBJEXT) kern/act.$(OBJEXT) kern/ast.$(OBJEXT) \
kern/bootstrap.$(OBJEXT) kern/counters.$(OBJEXT) \
kern/debug.$(OBJEXT) kern/eventcount.$(OBJEXT) \
- kern/exception.$(OBJEXT) kern/host.$(OBJEXT) \
- kern/ipc_host.$(OBJEXT) kern/ipc_kobject.$(OBJEXT) \
- kern/ipc_mig.$(OBJEXT) kern/ipc_sched.$(OBJEXT) \
- kern/ipc_tt.$(OBJEXT) kern/lock.$(OBJEXT) \
- kern/lock_mon.$(OBJEXT) kern/mach_clock.$(OBJEXT) \
- kern/mach_factor.$(OBJEXT) kern/machine.$(OBJEXT) \
- kern/pc_sample.$(OBJEXT) kern/printf.$(OBJEXT) \
- kern/priority.$(OBJEXT) kern/processor.$(OBJEXT) \
- kern/profile.$(OBJEXT) kern/queue.$(OBJEXT) \
- kern/rbtree.$(OBJEXT) kern/rdxtree.$(OBJEXT) \
- kern/slab.$(OBJEXT) kern/sched_prim.$(OBJEXT) \
- kern/startup.$(OBJEXT) kern/strings.$(OBJEXT) \
- kern/syscall_emulation.$(OBJEXT) kern/syscall_subr.$(OBJEXT) \
- kern/syscall_sw.$(OBJEXT) kern/task.$(OBJEXT) \
- kern/thread.$(OBJEXT) kern/thread_swap.$(OBJEXT) \
- kern/time_stamp.$(OBJEXT) kern/timer.$(OBJEXT) \
- kern/xpr.$(OBJEXT) kern/elf-load.$(OBJEXT) \
- kern/boot_script.$(OBJEXT) util/putchar.$(OBJEXT) \
- util/puts.$(OBJEXT) util/atoi.$(OBJEXT) \
+ kern/exception.$(OBJEXT) kern/gsync.$(OBJEXT) \
+ kern/host.$(OBJEXT) kern/ipc_host.$(OBJEXT) \
+ kern/ipc_kobject.$(OBJEXT) kern/ipc_mig.$(OBJEXT) \
+ kern/ipc_sched.$(OBJEXT) kern/ipc_tt.$(OBJEXT) \
+ kern/lock.$(OBJEXT) kern/lock_mon.$(OBJEXT) \
+ kern/mach_clock.$(OBJEXT) kern/mach_factor.$(OBJEXT) \
+ kern/machine.$(OBJEXT) kern/pc_sample.$(OBJEXT) \
+ kern/printf.$(OBJEXT) kern/priority.$(OBJEXT) \
+ kern/processor.$(OBJEXT) kern/profile.$(OBJEXT) \
+ kern/queue.$(OBJEXT) kern/rbtree.$(OBJEXT) \
+ kern/rdxtree.$(OBJEXT) kern/slab.$(OBJEXT) \
+ kern/sched_prim.$(OBJEXT) kern/startup.$(OBJEXT) \
+ kern/strings.$(OBJEXT) kern/syscall_emulation.$(OBJEXT) \
+ kern/syscall_subr.$(OBJEXT) kern/syscall_sw.$(OBJEXT) \
+ kern/task.$(OBJEXT) kern/thread.$(OBJEXT) \
+ kern/thread_swap.$(OBJEXT) kern/time_stamp.$(OBJEXT) \
+ kern/timer.$(OBJEXT) kern/xpr.$(OBJEXT) \
+ kern/elf-load.$(OBJEXT) kern/boot_script.$(OBJEXT) \
+ util/putchar.$(OBJEXT) util/puts.$(OBJEXT) util/atoi.$(OBJEXT) \
vm/memory_object_proxy.$(OBJEXT) vm/memory_object.$(OBJEXT) \
vm/vm_debug.$(OBJEXT) vm/vm_external.$(OBJEXT) \
vm/vm_fault.$(OBJEXT) vm/vm_init.$(OBJEXT) \
@@ -2378,6 +2378,7 @@ SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
+_START_MAP = @_START_MAP@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
@@ -2501,8 +2502,8 @@ DISTCLEANFILES = Makefile.orig config.status.orig
#
# Compilation flags
#
-AM_CPPFLAGS = -nostdinc -imacros config.h -I$(systype) -I. \
- -I$(top_srcdir)/$(systype) \
+AM_CPPFLAGS = -ffreestanding -nostdinc -imacros config.h -I$(systype) \
+ -I. -I$(top_srcdir)/$(systype) \
-I$(top_srcdir)/$(systype)/include/mach/sa \
-I$(top_srcdir)/include
AM_CCASFLAGS =
@@ -2580,20 +2581,20 @@ libkernel_a_SOURCES = $(am__append_2) ipc/ipc_entry.c
ipc/ipc_entry.h \
kern/boot_script.h kern/bootstrap.c kern/bootstrap.h \
kern/counters.c kern/counters.h kern/cpu_number.h kern/debug.c \
kern/debug.h kern/eventcount.c kern/eventcount.h \
- kern/exception.c kern/exception.h kern/host.c kern/host.h \
- kern/ipc_host.c kern/ipc_host.h kern/ipc_kobject.c \
- kern/ipc_kobject.h kern/ipc_mig.c kern/ipc_mig.h \
- kern/ipc_sched.c kern/ipc_sched.h kern/ipc_tt.c kern/ipc_tt.h \
- kern/kalloc.h kern/kern_types.h kern/list.h kern/lock.c \
- kern/lock.h kern/lock_mon.c kern/log2.h kern/mach_clock.c \
- kern/mach_clock.h kern/mach_factor.c kern/mach_factor.h \
- kern/machine.c kern/machine.h kern/macros.h kern/pc_sample.c \
- kern/pc_sample.h kern/printf.c kern/printf.h kern/priority.c \
- kern/priority.h kern/processor.c kern/processor.h \
- kern/profile.c kern/queue.c kern/queue.h kern/rbtree.c \
- kern/rbtree.h kern/rbtree_i.h kern/rdxtree.c kern/rdxtree.h \
- kern/rdxtree_i.h kern/refcount.h kern/slab.c kern/slab.h \
- kern/sched.h kern/sched_prim.c kern/sched_prim.h \
+ kern/exception.c kern/exception.h kern/gsync.c kern/gsync.h \
+ kern/host.c kern/host.h kern/ipc_host.c kern/ipc_host.h \
+ kern/ipc_kobject.c kern/ipc_kobject.h kern/ipc_mig.c \
+ kern/ipc_mig.h kern/ipc_sched.c kern/ipc_sched.h kern/ipc_tt.c \
+ kern/ipc_tt.h kern/kalloc.h kern/kern_types.h kern/list.h \
+ kern/lock.c kern/lock.h kern/lock_mon.c kern/log2.h \
+ kern/mach_clock.c kern/mach_clock.h kern/mach_factor.c \
+ kern/mach_factor.h kern/machine.c kern/machine.h kern/macros.h \
+ kern/pc_sample.c kern/pc_sample.h kern/printf.c kern/printf.h \
+ kern/priority.c kern/priority.h kern/processor.c \
+ kern/processor.h kern/profile.c kern/queue.c kern/queue.h \
+ kern/rbtree.c kern/rbtree.h kern/rbtree_i.h kern/rdxtree.c \
+ kern/rdxtree.h kern/rdxtree_i.h kern/refcount.h kern/slab.c \
+ kern/slab.h kern/sched.h kern/sched_prim.c kern/sched_prim.h \
kern/shuttle.h kern/startup.c kern/startup.h kern/strings.c \
kern/syscall_emulation.c kern/syscall_emulation.h \
kern/syscall_subr.c kern/syscall_subr.h kern/syscall_sw.c \
@@ -3186,6 +3187,8 @@ kern/eventcount.$(OBJEXT): kern/$(am__dirstamp) \
kern/$(DEPDIR)/$(am__dirstamp)
kern/exception.$(OBJEXT): kern/$(am__dirstamp) \
kern/$(DEPDIR)/$(am__dirstamp)
+kern/gsync.$(OBJEXT): kern/$(am__dirstamp) \
+ kern/$(DEPDIR)/$(am__dirstamp)
kern/host.$(OBJEXT): kern/$(am__dirstamp) \
kern/$(DEPDIR)/$(am__dirstamp)
kern/ipc_host.$(OBJEXT): kern/$(am__dirstamp) \
@@ -4299,6 +4302,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
address@hidden@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
@AMDEP_TRUE@@am__include@ @address@hidden/$(DEPDIR)/address@hidden@
diff --git a/Makefrag.am b/Makefrag.am
index 6ffc8cc..e001d65 100644
--- a/Makefrag.am
+++ b/Makefrag.am
@@ -144,6 +144,8 @@ libkernel_a_SOURCES += \
kern/eventcount.h \
kern/exception.c \
kern/exception.h \
+ kern/gsync.c \
+ kern/gsync.h \
kern/host.c \
kern/host.h \
kern/ipc_host.c \
diff --git a/NEWS b/NEWS
index e8bb33f..1239482 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,22 @@
+Version 1.7 (2016-04-XX)
+
+The code has been updated to work with newer versions of the compiler,
+and numerous bugs have been fixed throughout the code. The code uses
+integer types from 'stdint.h' now instead of the old Mach types.
+
+The VM cache policy change has been merged. The kernel now caches
+unreferenced VM objects unconditionally instead of using a fixed
+limit.
+
+The physical page allocator of the X15 kernel has been integrated, and
+is now used directly by the slab allocator. This increases the kernel
+heap addressing important scalability issues.
+
+A synchronization mechanism was added, similar to the Linux futexes, to
+allow efficient and powerful userland synchronization.
+
+Support for profiling kernel code from userland through sampling was added.
+
Version 1.6 (2015-10-31)
The code has been updated to work with newer versions of the compiler,
diff --git a/config.h.in b/config.h.in
index aff1fa6..81763e0 100644
--- a/config.h.in
+++ b/config.h.in
@@ -470,6 +470,9 @@
/* Standalone MACH kernel */
#undef MACH_KERNEL
+/* MACH_KERNSAMPLE */
+#undef MACH_KERNSAMPLE
+
/* enable use of kmsg device */
#undef MACH_KMSG
@@ -524,6 +527,9 @@
/* number of CPUs */
#undef NCPUS
+/* Define to 1 if assertions should be disabled. */
+#undef NDEBUG
+
/* NLPR */
#undef NLPR
diff --git a/configfrag.ac b/configfrag.ac
index c0e04b3..3d7033e 100644
--- a/configfrag.ac
+++ b/configfrag.ac
@@ -85,6 +85,15 @@ AC_DEFINE([MACH_PAGEMAP], [1], [MACH_PAGEMAP])
# Do pc sample histogram.
AC_DEFINE([MACH_PCSAMPLE], [1], [MACH_PCSAMPLE])
+# Sample kernel too.
+AC_ARG_ENABLE([kernsample],
+ AS_HELP_STRING([--enable-kernsample], [enable sampling kernel]))
+[if [ x"$enable_kernsample" = xyes ]; then]
+ AC_DEFINE([MACH_KERNSAMPLE], [1], [MACH_KERNSAMPLE])
+[else]
+ AC_DEFINE([MACH_KERNSAMPLE], [0], [MACH_KERNSAMPLE])
+[fi]
+
# TTD Remote Kernel Debugging.
AC_DEFINE([MACH_TTD], [0], [MACH_TTD])
@@ -113,6 +122,8 @@ AC_DEFINE([SLAB_USE_CPU_POOLS], [0], [SLAB_USE_CPU_POOLS])
# Options.
#
+AC_HEADER_ASSERT()
+
AC_ARG_ENABLE([kdb],
AS_HELP_STRING([--enable-kdb], [enable use of in-kernel debugger]))
[if [ x"$enable_kdb" = xyes ]; then]
diff --git a/configure b/configure
index f4e3f76..99c1c31 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for GNU Mach 1.6+git20160311.
+# Generated by GNU Autoconf 2.69 for GNU Mach 1.6+git20160502.
#
# Report bugs to <address@hidden>.
#
@@ -579,8 +579,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='GNU Mach'
PACKAGE_TARNAME='gnumach'
-PACKAGE_VERSION='1.6+git20160311'
-PACKAGE_STRING='GNU Mach 1.6+git20160311'
+PACKAGE_VERSION='1.6+git20160502'
+PACKAGE_STRING='GNU Mach 1.6+git20160502'
PACKAGE_BUGREPORT='address@hidden'
PACKAGE_URL=''
@@ -793,6 +793,7 @@ enable_kmsg_FALSE
enable_kmsg_TRUE
enable_kdb_FALSE
enable_kdb_TRUE
+_START_MAP
enable_pae_FALSE
enable_pae_TRUE
enable_lpr_FALSE
@@ -930,6 +931,9 @@ enable_pv_descriptors
enable_ring1
enable_lpr
enable_pae
+with__START_MAP
+enable_kernsample
+enable_assert
enable_kdb
enable_kmsg
enable_floppy
@@ -1595,7 +1599,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures GNU Mach 1.6+git20160311 to adapt to many kinds of
systems.
+\`configure' configures GNU Mach 1.6+git20160502 to adapt to many kinds of
systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1666,7 +1670,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of GNU Mach 1.6+git20160311:";;
+ short | recursive ) echo "Configuration of GNU Mach 1.6+git20160502:";;
esac
cat <<\_ACEOF
@@ -1700,6 +1704,8 @@ Optional Features:
--enable-lpr lpr device; on ix86-at enabled by default
--enable-pae PAE support (ix86-only); on ix86-at disabled by
default, on ix86-xen enabled by default
+ --enable-kernsample enable sampling kernel
+ --disable-assert turn off assertions
--enable-kdb enable use of in-kernel debugger
--disable-kmsg disable use of kmsg device
--enable-floppy Linux device driver for PC floppy; on ix86-at
@@ -1935,6 +1941,12 @@ Optional Features:
Wireless adapters (Orinoco); on ix86-at enabled by
default
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-_START_MAP=0x1000000
+ specify kernel mapping start address
+
Some influential environment variables:
CC C compiler command
CFLAGS C compiler flags
@@ -2014,7 +2026,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-GNU Mach configure 1.6+git20160311
+GNU Mach configure 1.6+git20160502
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2106,7 +2118,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by GNU Mach $as_me 1.6+git20160311, which was
+It was created by GNU Mach $as_me 1.6+git20160502, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2972,7 +2984,7 @@ fi
# Define the identity of the package.
PACKAGE='gnumach'
- VERSION='1.6+git20160311'
+ VERSION='1.6+git20160502'
# Some tools Automake needs.
@@ -6339,6 +6351,16 @@ fi
fi
+# Check whether --with-_START_MAP was given.
+if test "${with__START_MAP+set}" = set; then :
+ withval=$with__START_MAP; _START_MAP="$withval"
+else
+ _START_MAP=0x1000000
+fi
+
+
+
+
# General options.
@@ -6461,6 +6483,22 @@ $as_echo "#define MACH_PAGEMAP 1" >>confdefs.h
$as_echo "#define MACH_PCSAMPLE 1" >>confdefs.h
+# Sample kernel too.
+# Check whether --enable-kernsample was given.
+if test "${enable_kernsample+set}" = set; then :
+ enableval=$enable_kernsample;
+fi
+
+if [ x"$enable_kernsample" = xyes ]; then
+
+$as_echo "#define MACH_KERNSAMPLE 1" >>confdefs.h
+
+else
+
+$as_echo "#define MACH_KERNSAMPLE 0" >>confdefs.h
+
+fi
+
# TTD Remote Kernel Debugging.
$as_echo "#define MACH_TTD 0" >>confdefs.h
@@ -6505,6 +6543,29 @@ $as_echo "#define SLAB_USE_CPU_POOLS 0" >>confdefs.h
# Options.
#
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable
assertions" >&5
+$as_echo_n "checking whether to enable assertions... " >&6; }
+ # Check whether --enable-assert was given.
+if test "${enable_assert+set}" = set; then :
+ enableval=$enable_assert; ac_enable_assert=$enableval
+ if test "x$enableval" = xno; then :
+
+$as_echo "#define NDEBUG 1" >>confdefs.h
+
+elif test "x$enableval" != xyes; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: invalid argument supplied
to --enable-assert" >&5
+$as_echo "$as_me: WARNING: invalid argument supplied to --enable-assert" >&2;}
+ ac_enable_assert=yes
+fi
+else
+ ac_enable_assert=yes
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_enable_assert" >&5
+$as_echo "$ac_enable_assert" >&6; }
+
+
# Check whether --enable-kdb was given.
if test "${enable_kdb+set}" = set; then :
enableval=$enable_kdb;
@@ -12128,7 +12189,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by GNU Mach $as_me 1.6+git20160311, which was
+This file was extended by GNU Mach $as_me 1.6+git20160502, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -12199,7 +12260,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //;
s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-GNU Mach config.status 1.6+git20160311
+GNU Mach config.status 1.6+git20160502
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/ddb/db_elf.c b/ddb/db_elf.c
index 10e7162..f654ad7 100644
--- a/ddb/db_elf.c
+++ b/ddb/db_elf.c
@@ -165,23 +165,23 @@ elf_db_search_symbol (db_symtab_t *stab,
if (s->st_name == 0)
continue;
- if (strategy == DB_STGY_XTRN && (s->st_info & STB_GLOBAL) == 0)
+ if (strategy == DB_STGY_XTRN && (ELF32_ST_BIND(s->st_info) != STB_GLOBAL))
continue;
if (off >= s->st_value) {
- if (s->st_info == STT_FUNC)
+ if (ELF32_ST_TYPE(s->st_info) == STT_FUNC)
continue;
if (off - s->st_value < diff) {
diff = off - s->st_value;
symp = s;
- if (diff == 0 && (s->st_info & STB_GLOBAL))
+ if (diff == 0 && (ELF32_ST_BIND(s->st_info) == STB_GLOBAL))
break;
} else if (off - s->st_value == diff) {
if (symp == NULL)
symp = s;
- else if ((symp->st_info & STB_GLOBAL) == 0
- && (s->st_info & STB_GLOBAL) != 0)
+ else if ((ELF32_ST_BIND(symp->st_info) != STB_GLOBAL)
+ && (ELF32_ST_BIND(s->st_info) == STB_GLOBAL))
symp = s; /* pick the external symbol */
}
}
diff --git a/doc/mach.info b/doc/mach.info
index 463a76b..51f4f5a 100644
--- a/doc/mach.info
+++ b/doc/mach.info
@@ -2,8 +2,8 @@ This is mach.info, produced by makeinfo version 6.1 from
mach.texi.
This file documents the GNU Mach microkernel.
- This is edition 0.4, last updated on 10 March 2016, of 'The GNU Mach
-Reference Manual', for version 1.6+git20160311.
+ This is edition 0.4, last updated on 20 April 2016, of 'The GNU Mach
+Reference Manual', for version 1.6+git20160502.
Copyright (C) 2001, 2002, 2006, 2007, 2008 Free Software Foundation,
Inc.
diff --git a/doc/mach.info-1 b/doc/mach.info-1
index 41ec161..da9fbc0 100644
--- a/doc/mach.info-1
+++ b/doc/mach.info-1
@@ -2,8 +2,8 @@ This is mach.info, produced by makeinfo version 6.1 from
mach.texi.
This file documents the GNU Mach microkernel.
- This is edition 0.4, last updated on 10 March 2016, of 'The GNU Mach
-Reference Manual', for version 1.6+git20160311.
+ This is edition 0.4, last updated on 20 April 2016, of 'The GNU Mach
+Reference Manual', for version 1.6+git20160502.
Copyright (C) 2001, 2002, 2006, 2007, 2008 Free Software Foundation,
Inc.
@@ -45,8 +45,8 @@ Main Menu
This file documents the GNU Mach microkernel.
- This is edition 0.4, last updated on 10 March 2016, of 'The GNU Mach
-Reference Manual', for version 1.6+git20160311.
+ This is edition 0.4, last updated on 20 April 2016, of 'The GNU Mach
+Reference Manual', for version 1.6+git20160502.
Copyright (C) 2001, 2002, 2006, 2007, 2008 Free Software Foundation,
Inc.
diff --git a/doc/mach.info-2 b/doc/mach.info-2
index 39fe14a..e91cf0e 100644
--- a/doc/mach.info-2
+++ b/doc/mach.info-2
@@ -2,8 +2,8 @@ This is mach.info, produced by makeinfo version 6.1 from
mach.texi.
This file documents the GNU Mach microkernel.
- This is edition 0.4, last updated on 10 March 2016, of 'The GNU Mach
-Reference Manual', for version 1.6+git20160311.
+ This is edition 0.4, last updated on 20 April 2016, of 'The GNU Mach
+Reference Manual', for version 1.6+git20160502.
Copyright (C) 2001, 2002, 2006, 2007, 2008 Free Software Foundation,
Inc.
diff --git a/doc/stamp-vti b/doc/stamp-vti
index fd5f466..13c069d 100644
--- a/doc/stamp-vti
+++ b/doc/stamp-vti
@@ -1,4 +1,4 @@
address@hidden UPDATED 10 March 2016
address@hidden UPDATED-MONTH March 2016
address@hidden EDITION 1.6+git20160311
address@hidden VERSION 1.6+git20160311
address@hidden UPDATED 20 April 2016
address@hidden UPDATED-MONTH April 2016
address@hidden EDITION 1.6+git20160502
address@hidden VERSION 1.6+git20160502
diff --git a/doc/version.texi b/doc/version.texi
index fd5f466..13c069d 100644
--- a/doc/version.texi
+++ b/doc/version.texi
@@ -1,4 +1,4 @@
address@hidden UPDATED 10 March 2016
address@hidden UPDATED-MONTH March 2016
address@hidden EDITION 1.6+git20160311
address@hidden VERSION 1.6+git20160311
address@hidden UPDATED 20 April 2016
address@hidden UPDATED-MONTH April 2016
address@hidden EDITION 1.6+git20160502
address@hidden VERSION 1.6+git20160502
diff --git a/i386/Makefrag.am b/i386/Makefrag.am
index 8b0ef7f..c61a3f6 100644
--- a/i386/Makefrag.am
+++ b/i386/Makefrag.am
@@ -225,8 +225,8 @@ EXTRA_DIST += \
i386/ldscript
if PLATFORM_at
gnumach_LINKFLAGS += \
- --defsym _START=0xC0100000 \
- --defsym _START_MAP=0x100000 \
+ --defsym _START_MAP=$(_START_MAP) \
+ --defsym _START=_START_MAP+0xC0000000 \
-T '$(srcdir)'/i386/ldscript
endif
diff --git a/i386/configfrag.ac b/i386/configfrag.ac
index 48744b1..3c29bdf 100644
--- a/i386/configfrag.ac
+++ b/i386/configfrag.ac
@@ -119,6 +119,11 @@ if [ x"$enable_pae" = xyes ]; then]
[else]
AM_CONDITIONAL([enable_pae], [false])
[fi]
+
+AC_ARG_WITH([_START_MAP],
+ AS_HELP_STRING([--with-_START_MAP=0x1000000], [specify kernel mapping start
address]),
+ [_START_MAP="$withval"], [_START_MAP=0x1000000])
+AC_SUBST(_START_MAP)
dnl Local Variables:
dnl mode: autoconf
diff --git a/i386/i386/hardclock.c b/i386/i386/hardclock.c
index 49ea82c..82761ec 100644
--- a/i386/i386/hardclock.c
+++ b/i386/i386/hardclock.c
@@ -62,18 +62,19 @@ hardclock(iunit, old_ipl, irq, ret_addr, regs)
(regs->efl & EFL_VM) || /* user mode */
((regs->cs & 0x03) != 0), /* user mode */
#if defined(LINUX_DEV)
- FALSE /* ignore SPL0 */
+ FALSE, /* ignore SPL0 */
#else /* LINUX_DEV */
- old_ipl == SPL0 /* base priority */
+ old_ipl == SPL0, /* base priority */
#endif /* LINUX_DEV */
- );
+ regs->eip); /* interrupted eip */
else
/*
* Interrupt from interrupt stack.
*/
clock_interrupt(tick, /* usec per tick */
FALSE, /* kernel mode */
- FALSE); /* not SPL0 */
+ FALSE, /* not SPL0 */
+ 0); /* interrupted eip */
#ifdef LINUX_DEV
linux_timer_intr();
diff --git a/i386/i386/pcb.c b/i386/i386/pcb.c
index dd2042d..743108d 100644
--- a/i386/i386/pcb.c
+++ b/i386/i386/pcb.c
@@ -409,7 +409,7 @@ void pcb_init(task_t parent_task, thread_t thread)
/* This is a new thread for the current task, make it inherit our FPU
state. */
- if (parent_task == current_task())
+ if (current_thread() && parent_task == current_task())
fpinherit(current_thread(), thread);
}
diff --git a/i386/i386/spl.S b/i386/i386/spl.S
index 1dce991..307739f 100644
--- a/i386/i386/spl.S
+++ b/i386/i386/spl.S
@@ -23,6 +23,12 @@
#include <i386/i386asm.h>
#include <i386/xen.h>
+#if NCPUS > 1
+#define mb lock; addl $0,(%esp)
+#else
+#define mb
+#endif
+
/*
* Set IPL to the specified value.
*
@@ -34,6 +40,7 @@
* potentially, return with interrupts disabled.
*/
#define SETIPL(level) \
+ mb; \
movl $(level),%edx; \
cmpl EXT(curr_ipl),%edx; \
jne spl; \
@@ -70,6 +77,7 @@ lock orl $1,hyp_shared_info+CPU_PENDING_SEL; /* Yes,
activate it */ \
#endif /* MACH_XEN */
ENTRY(spl0)
+ mb;
movl EXT(curr_ipl),%eax /* save current ipl */
pushl %eax
cli /* disable interrupts */
@@ -140,6 +148,7 @@ Entry(splsched)
Entry(splhigh)
Entry(splhi)
ENTRY(spl7)
+ mb;
/* ipl7 just clears IF */
movl $SPL7,%eax
xchgl EXT(curr_ipl),%eax
diff --git a/i386/i386/xen.h b/i386/i386/xen.h
index c681187..49b0d52 100644
--- a/i386/i386/xen.h
+++ b/i386/i386/xen.h
@@ -356,8 +356,8 @@ _hypcall2(int, set_debugreg, int, reg, unsigned long,
value);
_hypcall1(unsigned long, get_debugreg, int, reg);
/* x86-specific */
-MACH_INLINE unsigned64_t hyp_cpu_clock(void) {
- unsigned64_t tsc;
+MACH_INLINE uint64_t hyp_cpu_clock(void) {
+ uint64_t tsc;
asm volatile("rdtsc":"=A"(tsc));
return tsc;
}
diff --git a/i386/i386at/model_dep.c b/i386/i386at/model_dep.c
index 62763ae..679d524 100644
--- a/i386/i386at/model_dep.c
+++ b/i386/i386at/model_dep.c
@@ -301,7 +301,8 @@ i386at_init(void)
* is too far in physical memory. */
if (boot_info.flags & MULTIBOOT_CMDLINE) {
int len = strlen ((char*)phystokv(boot_info.cmdline)) + 1;
- assert(init_alloc_aligned(round_page(len), &addr));
+ if (! init_alloc_aligned(round_page(len), &addr))
+ panic("could not allocate memory for multiboot command line");
kernel_cmdline = (char*) phystokv(addr);
memcpy(kernel_cmdline, (void *)phystokv(boot_info.cmdline),
len);
boot_info.cmdline = addr;
@@ -311,20 +312,26 @@ i386at_init(void)
struct multiboot_module *m;
int i;
- assert(init_alloc_aligned(round_page(boot_info.mods_count *
sizeof(*m)), &addr));
+ if (! init_alloc_aligned(
+ round_page(boot_info.mods_count * sizeof(*m)), &addr))
+ panic("could not allocate memory for multiboot modules");
m = (void*) phystokv(addr);
memcpy(m, (void*) phystokv(boot_info.mods_addr),
boot_info.mods_count * sizeof(*m));
boot_info.mods_addr = addr;
for (i = 0; i < boot_info.mods_count; i++) {
vm_size_t size = m[i].mod_end - m[i].mod_start;
- assert(init_alloc_aligned(round_page(size), &addr));
+ if (! init_alloc_aligned(round_page(size), &addr))
+ panic("could not allocate memory for multiboot "
+ "module %d", i);
memcpy((void*) phystokv(addr), (void*)
phystokv(m[i].mod_start), size);
m[i].mod_start = addr;
m[i].mod_end = addr + size;
size = strlen((char*) phystokv(m[i].string)) + 1;
- assert(init_alloc_aligned(round_page(size), &addr));
+ if (! init_alloc_aligned(round_page(size), &addr))
+ panic("could not allocate memory for multiboot "
+ "module command line %d", i);
memcpy((void*) phystokv(addr), (void*)
phystokv(m[i].string), size);
m[i].string = addr;
}
diff --git a/i386/include/mach/i386/machine_types.defs
b/i386/include/mach/i386/machine_types.defs
index 6ac17cf..6ff93db 100755
--- a/i386/include/mach/i386/machine_types.defs
+++ b/i386/include/mach/i386/machine_types.defs
@@ -47,7 +47,7 @@
* a port in user space as an integer and
* in kernel space as a pointer.
*/
-type natural_t = unsigned32;
+type natural_t = uint32_t;
/*
* An integer_t is the signed counterpart
@@ -56,6 +56,6 @@ type natural_t = unsigned32;
* other types in a machine-independent
* way.
*/
-type integer_t = int32;
+type integer_t = int32_t;
#endif /* _MACHINE_MACHINE_TYPES_DEFS_ */
diff --git a/i386/include/mach/i386/vm_types.h
b/i386/include/mach/i386/vm_types.h
index 4a58b1c..4e259f9 100644
--- a/i386/include/mach/i386/vm_types.h
+++ b/i386/include/mach/i386/vm_types.h
@@ -59,16 +59,6 @@ typedef unsigned int natural_t;
*/
typedef int integer_t;
-#ifndef _POSIX_SOURCE
-
-/*
- * An int32 is an integer that is at least 32 bits wide
- */
-typedef int int32;
-typedef unsigned int uint32;
-
-#endif /* _POSIX_SOURCE */
-
/*
* A vm_offset_t is a type-neutral pointer,
* e.g. an offset into a virtual memory space.
@@ -92,20 +82,6 @@ typedef unsigned long phys_addr_t;
*/
typedef natural_t vm_size_t;
-/*
- * These types are _exactly_ as wide as indicated in their names.
- */
-typedef signed char signed8_t;
-typedef signed short signed16_t;
-typedef signed int signed32_t;
-typedef signed long long signed64_t;
-typedef unsigned char unsigned8_t;
-typedef unsigned short unsigned16_t;
-typedef unsigned int unsigned32_t;
-typedef unsigned long long unsigned64_t;
-typedef float float32_t;
-typedef double float64_t;
-
#endif /* __ASSEMBLER__ */
/*
diff --git a/i386/xen/xen.c b/i386/xen/xen.c
index a46ee2c..8b015c4 100644
--- a/i386/xen/xen.c
+++ b/i386/xen/xen.c
@@ -46,14 +46,15 @@ void hyp_failsafe_c_callback(struct failsafe_callback_regs
*regs) {
extern void return_to_iret;
-void hypclock_machine_intr(int old_ipl, void *ret_addr, struct
i386_interrupt_state *regs, unsigned64_t delta) {
+void hypclock_machine_intr(int old_ipl, void *ret_addr, struct
i386_interrupt_state *regs, uint64_t delta) {
if (ret_addr == &return_to_iret) {
clock_interrupt(delta/1000, /* usec per tick */
(regs->efl & EFL_VM) || /* user mode */
((regs->cs & 0x02) != 0), /* user mode */
- old_ipl == SPL0); /* base priority */
+ old_ipl == SPL0, /* base priority */
+ regs->eip); /* interrupted eip */
} else
- clock_interrupt(delta/1000, FALSE, FALSE);
+ clock_interrupt(delta/1000, FALSE, FALSE, 0);
}
void hyp_p2m_init(void) {
diff --git a/include/device/device_types.defs b/include/device/device_types.defs
index 49cc271..e97d89c 100644
--- a/include/device/device_types.defs
+++ b/include/device/device_types.defs
@@ -43,9 +43,9 @@
DEVICE_IMPORTS
#endif
-type recnum_t = unsigned32;
-type dev_mode_t = unsigned32;
-type dev_flavor_t = unsigned32;
+type recnum_t = uint32_t;
+type dev_mode_t = uint32_t;
+type dev_flavor_t = uint32_t;
type dev_name_t = (MACH_MSG_TYPE_STRING_C, 8*128);
type dev_status_t = array[*:1024] of int;
type io_buf_ptr_t = ^array[] of MACH_MSG_TYPE_INTEGER_8;
diff --git a/include/mach/gnumach.defs b/include/mach/gnumach.defs
index dd4da87..5235df6 100644
--- a/include/mach/gnumach.defs
+++ b/include/mach/gnumach.defs
@@ -84,3 +84,55 @@ simpleroutine task_set_name(
routine register_new_task_notification(
host_priv : host_priv_t;
notification : mach_port_send_t);
+
+/* Test that the contents of ADDR are equal to the 32-bit integer VAL1.
+ * If they are not, return immediately, otherwise, block until a
+ * matching 'gsync_wake' is done on the same address. FLAGS is used
+ * to control how the thread waits, and may be composed of:
+ * - GSYNC_SHARED: The address may be shared among tasks. If this
+ bit is not set, the address is assumed to be task-local.
+ * - GSYNC_QUAD: Additionally check that the adjacent 32-bit word
+ following ADDR matches the value VAL2.
+ * - GSYNC_TIMED: The call only blocks for MSEC milliseconds. */
+routine gsync_wait(
+ task : task_t;
+ addr : vm_offset_t;
+ val1 : unsigned;
+ val2 : unsigned;
+ msec : natural_t;
+ flags : int);
+
+/* Wake up threads waiting on the address ADDR. Much like with
+ * 'gsync_wait', the parameter FLAGS controls how it is done. In this
+ * case, it may be composed of the following:
+ * - GSYNC_SHARED: Same as with 'gsync_wait'.
+ * - GSYNC_BROADCAST: Wake up every thread waiting on the address. If
+ * this flag is not set, the call wakes (at most) 1 thread.
+ * - GSYNC_MUTATE: Before waking any potential waiting threads, set the
+ * contents of ADDR to VAL.
+ *
+ * This RPC is implemented as a simple routine for efficiency reasons,
+ * and because the return value rarely matters. */
+simpleroutine gsync_wake(
+ task : task_t;
+ addr : vm_offset_t;
+ val : unsigned;
+ flags : int);
+
+/* Arrange for threads waiting on address SRC_ADDR to instead
+ * wait on address DST_ADDR. If WAKE_ONE is true, additionally
+ * wake one of the threads waiting on SRC_ADDR. For this function,
+ * the parameter flags may be a combination of:
+ * - GSYNC_SHARED: Just like with 'gsync_wait' and 'gsync_wake'.
+ * - GSYNC_BROADCAST: Move all the threads waiting on SRC_ADDR. If
+ this flag is not set, the call moves (at most) 1 thread.
+ *
+ * This RPC is also a simple routine, and for the same reasons as
+ * with 'gsync_wake'. */
+simpleroutine gsync_requeue(
+ task : task_t;
+ src_addr : vm_offset_t;
+ dst_addr : vm_offset_t;
+ wake_one : boolean_t;
+ flags : int);
+
diff --git a/include/mach/kern_return.h b/include/mach/kern_return.h
index 2274328..a9d16e9 100644
--- a/include/mach/kern_return.h
+++ b/include/mach/kern_return.h
@@ -157,4 +157,10 @@
/* Object has been terminated and is no longer available.
*/
+#define KERN_TIMEDOUT 27
+ /* Kernel operation timed out. */
+
+#define KERN_INTERRUPTED 28
+ /* Kernel operation was interrupted. */
+
#endif /* _MACH_KERN_RETURN_H_ */
diff --git a/include/mach/std_types.defs b/include/mach/std_types.defs
index a1f156d..5d95ab4 100644
--- a/include/mach/std_types.defs
+++ b/include/mach/std_types.defs
@@ -33,12 +33,12 @@
type char = MACH_MSG_TYPE_CHAR;
type short = MACH_MSG_TYPE_INTEGER_16;
type int = MACH_MSG_TYPE_INTEGER_32;
-type int32 = MACH_MSG_TYPE_INTEGER_32;
-type int64 = MACH_MSG_TYPE_INTEGER_64;
+type int32_t = MACH_MSG_TYPE_INTEGER_32;
+type int64_t = MACH_MSG_TYPE_INTEGER_64;
type boolean_t = MACH_MSG_TYPE_BOOLEAN;
type unsigned = MACH_MSG_TYPE_INTEGER_32;
-type unsigned32 = MACH_MSG_TYPE_INTEGER_32;
-type unsigned64 = MACH_MSG_TYPE_INTEGER_64;
+type uint32_t = MACH_MSG_TYPE_INTEGER_32;
+type uint64_t = MACH_MSG_TYPE_INTEGER_64;
/* Get the definitions for natural_t and integer_t */
#include <mach/machine/machine_types.defs>
diff --git a/include/stdint.h b/include/stdint.h
new file mode 100644
index 0000000..bea277e
--- /dev/null
+++ b/include/stdint.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 Free Software Foundation, Inc.
+ *
+ * This file is part of GNU Mach.
+ *
+ * GNU Mach 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, 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 _STDINT_H_
+#define _STDINT_H_
+
+/*
+ * These types are _exactly_ as wide as indicated in their names.
+ */
+
+typedef char int8_t;
+typedef short int16_t;
+typedef int int32_t;
+#if __x86_64__
+typedef long int int64_t;
+#else
+typedef long long int int64_t;
+#endif /* __x86_64__ */
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+#if __x86_64__
+typedef unsigned long int uint64_t;
+#else
+typedef unsigned long long int uint64_t;
+#endif /* __x86_64__ */
+
+/* Types for `void *' pointers. */
+#if __x86_64__
+typedef long int intptr_t;
+typedef unsigned long int uintptr_t;
+#else
+typedef int intptr_t;
+typedef unsigned int uintptr_t;
+#endif /* __x86_64__ */
+
+#endif /* _STDINT_H_ */
diff --git a/include/sys/types.h b/include/sys/types.h
index 19e7b24..d576cc2 100644
--- a/include/sys/types.h
+++ b/include/sys/types.h
@@ -27,6 +27,7 @@
#define _MACH_SA_SYS_TYPES_H_
#include <mach/machine/vm_types.h>
+#include <stdint.h>
#ifndef _SIZE_T
#define _SIZE_T
@@ -58,20 +59,6 @@ typedef unsigned int time_t;
#define RAND_MAX 0x7fffffff
-/* Posix types */
-typedef signed8_t int8_t;
-typedef unsigned8_t uint8_t;
-typedef unsigned8_t u_int8_t;
-typedef signed16_t int16_t;
-typedef unsigned16_t uint16_t;
-typedef unsigned16_t u_int16_t;
-typedef signed32_t int32_t;
-typedef unsigned32_t uint32_t;
-typedef unsigned32_t u_int32_t;
-typedef signed64_t int64_t;
-typedef unsigned64_t uint64_t;
-typedef unsigned64_t u_int64_t;
-
/* Symbols not allowed by POSIX */
#ifndef _POSIX_SOURCE
diff --git a/ipc/ipc_kmsg.c b/ipc/ipc_kmsg.c
index 5076809..21667ca 100644
--- a/ipc/ipc_kmsg.c
+++ b/ipc/ipc_kmsg.c
@@ -1307,7 +1307,7 @@ ipc_kmsg_copyin_body(
mach_msg_type_number_t number;
boolean_t is_inline, longform, dealloc, is_port;
vm_offset_t data;
- unsigned64_t length;
+ uint64_t length;
kern_return_t kr;
type = (mach_msg_type_long_t *) saddr;
@@ -1358,7 +1358,7 @@ ipc_kmsg_copyin_body(
/* calculate length of data in bytes, rounding up */
- length = (((unsigned64_t) number * size) + 7) >> 3;
+ length = (((uint64_t) number * size) + 7) >> 3;
if (is_inline) {
vm_size_t amount;
@@ -2351,7 +2351,7 @@ ipc_kmsg_copyout_body(
mach_msg_type_size_t size;
mach_msg_type_number_t number;
boolean_t is_inline, longform, is_port;
- unsigned64_t length;
+ uint64_t length;
vm_offset_t addr;
type = (mach_msg_type_long_t *) saddr;
@@ -2382,7 +2382,7 @@ ipc_kmsg_copyout_body(
/* calculate length of data in bytes, rounding up */
- length = (((unsigned64_t) number * size) + 7) >> 3;
+ length = (((uint64_t) number * size) + 7) >> 3;
is_port = MACH_MSG_TYPE_PORT_ANY(name);
diff --git a/kern/exception.c b/kern/exception.c
index 63a63d6..246c141 100644
--- a/kern/exception.c
+++ b/kern/exception.c
@@ -757,7 +757,7 @@ exception_raise(
/* 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;\
+ union { mach_msg_type_t t; uint32_t w; } _t, _c;\
_t.t = *(type); _c.t = *(check);_t.w != _c.w; }))
/* Type descriptor for the return code. */
diff --git a/kern/gsync.c b/kern/gsync.c
new file mode 100644
index 0000000..68b3d0b
--- /dev/null
+++ b/kern/gsync.c
@@ -0,0 +1,413 @@
+/* Copyright (C) 2016 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <address@hidden>, 2016.
+
+ 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/>.
+*/
+
+#include <kern/gsync.h>
+#include <kern/sched_prim.h>
+#include <kern/thread.h>
+#include <kern/lock.h>
+#include <kern/list.h>
+#include <vm/vm_map.h>
+
+/* An entry in the global hash table. */
+struct gsync_hbucket
+{
+ struct list entries;
+ decl_simple_lock_data (, lock)
+};
+
+/* A key used to uniquely identify an address that a thread is
+ * waiting on. Its members' values depend on whether said
+ * address is shared or task-local. */
+struct gsync_key
+{
+ unsigned long u;
+ unsigned long v;
+};
+
+/* A thread that is blocked on an address with 'gsync_wait'. */
+struct gsync_waiter
+{
+ struct list link;
+ struct gsync_key key;
+ thread_t waiter;
+};
+
+#define GSYNC_NBUCKETS 512
+static struct gsync_hbucket gsync_buckets[GSYNC_NBUCKETS];
+
+void gsync_setup (void)
+{
+ int i;
+ for (i = 0; i < GSYNC_NBUCKETS; ++i)
+ {
+ list_init (&gsync_buckets[i].entries);
+ simple_lock_init (&gsync_buckets[i].lock);
+ }
+}
+
+/* Convenience comparison functions for gsync_key's. */
+
+static inline int
+gsync_key_eq (const struct gsync_key *lp,
+ const struct gsync_key *rp)
+{
+ return (lp->u == rp->u && lp->v == rp->v);
+}
+
+static inline int
+gsync_key_lt (const struct gsync_key *lp,
+ const struct gsync_key *rp)
+{
+ return (lp->u < rp->u || (lp->u == rp->u && lp->v < rp->v));
+}
+
+#define MIX2_LL(x, y) ((((x) << 5) | ((x) >> 27)) ^ (y))
+
+static inline unsigned int
+gsync_key_hash (const struct gsync_key *keyp)
+{
+ unsigned int ret = sizeof (void *);
+#ifndef __LP64__
+ ret = MIX2_LL (ret, keyp->u);
+ ret = MIX2_LL (ret, keyp->v);
+#else
+ ret = MIX2_LL (ret, keyp->u & ~0U);
+ ret = MIX2_LL (ret, keyp->u >> 32);
+ ret = MIX2_LL (ret, keyp->v & ~0U);
+ ret = MIX2_LL (ret, keyp->v >> 32);
+#endif
+ return (ret);
+}
+
+/* Test if the passed VM Map can access the address ADDR. The
+ * parameter FLAGS is used to specify the width and protection
+ * of the address. */
+static int
+valid_access_p (vm_map_t map, vm_offset_t addr, int flags)
+{
+ vm_prot_t prot = VM_PROT_READ |
+ ((flags & GSYNC_MUTATE) ? VM_PROT_WRITE : 0);
+ vm_offset_t size = sizeof (unsigned int) *
+ ((flags & GSYNC_QUAD) ? 2 : 1);
+
+ vm_map_entry_t entry;
+ return (vm_map_lookup_entry (map, addr, &entry) &&
+ entry->vme_end >= addr + size &&
+ (prot & entry->protection) == prot);
+}
+
+/* Given a task and an address, initialize the key at *KEYP and
+ * return the corresponding bucket in the global hash table. */
+static int
+gsync_fill_key (task_t task, vm_offset_t addr,
+ int flags, struct gsync_key *keyp)
+{
+ if (flags & GSYNC_SHARED)
+ {
+ /* For a shared address, we need the VM object
+ * and offset as the keys. */
+ vm_map_t map = task->map;
+ vm_prot_t prot = VM_PROT_READ |
+ ((flags & GSYNC_MUTATE) ? VM_PROT_WRITE : 0);
+ vm_map_version_t ver;
+ vm_prot_t rpr;
+ vm_object_t obj;
+ vm_offset_t off;
+ boolean_t wired_p;
+
+ if (unlikely (vm_map_lookup (&map, addr, prot, &ver,
+ &obj, &off, &rpr, &wired_p) != KERN_SUCCESS))
+ return (-1);
+
+ /* The VM object is returned locked. However, we check the
+ * address' accessibility later, so we can release it. */
+ vm_object_unlock (obj);
+
+ keyp->u = (unsigned long)obj;
+ keyp->v = (unsigned long)off;
+ }
+ else
+ {
+ /* Task-local address. The keys are the task's map and
+ * the virtual address itself. */
+ keyp->u = (unsigned long)task->map;
+ keyp->v = (unsigned long)addr;
+ }
+
+ return ((int)(gsync_key_hash (keyp) % GSYNC_NBUCKETS));
+}
+
+static inline struct gsync_waiter*
+node_to_waiter (struct list *nodep)
+{
+ return (list_entry (nodep, struct gsync_waiter, link));
+}
+
+static inline struct list*
+gsync_find_key (const struct list *entries,
+ const struct gsync_key *keyp, int *exactp)
+{
+ /* Look for a key that matches. We take advantage of the fact
+ * that the entries are sorted to break out of the loop as
+ * early as possible. */
+ struct list *runp;
+ list_for_each (entries, runp)
+ {
+ struct gsync_waiter *p = node_to_waiter (runp);
+ if (gsync_key_lt (keyp, &p->key))
+ break;
+ else if (gsync_key_eq (keyp, &p->key))
+ {
+ if (exactp != 0)
+ *exactp = 1;
+ break;
+ }
+ }
+
+ return (runp);
+}
+
+kern_return_t gsync_wait (task_t task, vm_offset_t addr,
+ unsigned int lo, unsigned int hi, natural_t msec, int flags)
+{
+ struct gsync_waiter w;
+ int bucket = gsync_fill_key (task, addr, flags, &w.key);
+
+ if (unlikely (bucket < 0))
+ return (KERN_INVALID_ADDRESS);
+
+ struct gsync_hbucket *hbp = gsync_buckets + bucket;
+ simple_lock (&hbp->lock);
+
+ /* Now test that the address is actually valid for the
+ * given task. Do so with the read-lock held in order
+ * to prevent memory deallocations. */
+ vm_map_lock_read (task->map);
+
+ if (unlikely (!valid_access_p (task->map, addr, flags)))
+ {
+ simple_unlock (&hbp->lock);
+ vm_map_unlock_read (task->map);
+ return (KERN_INVALID_ADDRESS);
+ }
+
+ /* Before doing any work, check that the expected value(s)
+ * match the contents of the address. Otherwise, the waiting
+ * thread could potentially miss a wakeup. */
+ if (((unsigned int *)addr)[0] != lo ||
+ ((flags & GSYNC_QUAD) &&
+ ((unsigned int *)addr)[1] != hi))
+ {
+ simple_unlock (&hbp->lock);
+ vm_map_unlock_read (task->map);
+ return (KERN_INVALID_ARGUMENT);
+ }
+
+ vm_map_unlock_read (task->map);
+
+ /* Look for the first entry in the hash bucket that
+ * compares strictly greater than this waiter. */
+ struct list *runp;
+ list_for_each (&hbp->entries, runp)
+ {
+ struct gsync_waiter *p = node_to_waiter (runp);
+ if (gsync_key_lt (&w.key, &p->key))
+ break;
+ }
+
+ /* Finally, add ourselves to the list and go to sleep. */
+ list_add (runp->prev, runp, &w.link);
+ w.waiter = current_thread ();
+
+ if (flags & GSYNC_TIMED)
+ thread_will_wait_with_timeout (w.waiter, msec);
+ else
+ thread_will_wait (w.waiter);
+
+ thread_sleep (0, (simple_lock_t)&hbp->lock, TRUE);
+
+ /* We're back. */
+ kern_return_t ret = current_thread()->wait_result;
+ if (ret != THREAD_AWAKENED)
+ {
+ /* We were interrupted or timed out. */
+ simple_lock (&hbp->lock);
+ if (w.link.next != 0)
+ list_remove (&w.link);
+ simple_unlock (&hbp->lock);
+
+ /* Map the error code. */
+ ret = ret == THREAD_INTERRUPTED ?
+ KERN_INTERRUPTED : KERN_TIMEDOUT;
+ }
+ else
+ ret = KERN_SUCCESS;
+
+ return (ret);
+}
+
+/* Remove a waiter from the queue, wake it up, and
+ * return the next node. */
+static inline struct list*
+dequeue_waiter (struct list *nodep)
+{
+ struct list *nextp = list_next (nodep);
+ list_remove (nodep);
+ list_node_init (nodep);
+ clear_wait (node_to_waiter(nodep)->waiter,
+ THREAD_AWAKENED, FALSE);
+ return (nextp);
+}
+
+kern_return_t gsync_wake (task_t task,
+ vm_offset_t addr, unsigned int val, int flags)
+{
+ struct gsync_key key;
+ int bucket = gsync_fill_key (task, addr, flags, &key);
+
+ if (unlikely (bucket < 0))
+ return (KERN_INVALID_ADDRESS);
+
+ kern_return_t ret = KERN_INVALID_ARGUMENT;
+
+ struct gsync_hbucket *hbp = gsync_buckets + bucket;
+ simple_lock (&hbp->lock);
+ vm_map_lock_read (task->map);
+
+ if (unlikely (!valid_access_p (task->map, addr, flags)))
+ {
+ simple_unlock (&hbp->lock);
+ vm_map_unlock_read (task->map);
+ return (KERN_INVALID_ADDRESS);
+ }
+
+ if (flags & GSYNC_MUTATE)
+ /* Set the contents of the address to the specified value,
+ * even if we don't end up waking any threads. Note that
+ * the buckets' simple locks give us atomicity. */
+ *(unsigned int *)addr = val;
+
+ vm_map_unlock_read (task->map);
+
+ int found = 0;
+ struct list *runp = gsync_find_key (&hbp->entries, &key, &found);
+ if (found)
+ {
+ do
+ runp = dequeue_waiter (runp);
+ while ((flags & GSYNC_BROADCAST) &&
+ !list_end (&hbp->entries, runp) &&
+ gsync_key_eq (&node_to_waiter(runp)->key, &key));
+
+ ret = KERN_SUCCESS;
+ }
+
+ simple_unlock (&hbp->lock);
+ return (ret);
+}
+
+kern_return_t gsync_requeue (task_t task, vm_offset_t src,
+ vm_offset_t dst, boolean_t wake_one, int flags)
+{
+ struct gsync_key src_k, dst_k;
+ int src_bkt = gsync_fill_key (task, src, flags, &src_k);
+ int dst_bkt = gsync_fill_key (task, dst, flags, &dst_k);
+
+ if ((src_bkt | dst_bkt) < 0)
+ return (KERN_INVALID_ADDRESS);
+
+ vm_map_lock_read (task->map);
+
+ /* We don't actually dereference or modify the contents
+ * of the addresses, but we still check that they can
+ * be accessed by the task. */
+ if (unlikely (!valid_access_p (task->map, src, flags) ||
+ !valid_access_p (task->map, dst, flags)))
+ {
+ vm_map_unlock_read (task->map);
+ return (KERN_INVALID_ADDRESS);
+ }
+
+ vm_map_unlock_read (task->map);
+
+ /* If we're asked to unconditionally wake up a waiter, then
+ * we need to remove a maximum of two threads from the queue. */
+ unsigned int nw = 1 + wake_one;
+ struct gsync_hbucket *bp1 = gsync_buckets + src_bkt;
+ struct gsync_hbucket *bp2 = gsync_buckets + dst_bkt;
+
+ /* Acquire the locks in order, to prevent any potential deadlock. */
+ if (bp1 == bp2)
+ simple_lock (&bp1->lock);
+ else if ((unsigned long)bp1 < (unsigned long)bp2)
+ {
+ simple_lock (&bp1->lock);
+ simple_lock (&bp2->lock);
+ }
+ else
+ {
+ simple_lock (&bp2->lock);
+ simple_lock (&bp1->lock);
+ }
+
+ kern_return_t ret = KERN_SUCCESS;
+ int exact;
+ struct list *inp = gsync_find_key (&bp1->entries, &src_k, &exact);
+
+ if (!exact)
+ /* There are no waiters in the source queue. */
+ ret = KERN_INVALID_ARGUMENT;
+ else
+ {
+ struct list *outp = gsync_find_key (&bp2->entries, &dst_k, 0);
+
+ /* We're going to need a node that points one past the
+ * end of the waiters in the source queue. */
+ struct list *endp = inp;
+
+ do
+ {
+ /* Modify the keys while iterating. */
+ node_to_waiter(endp)->key = dst_k;
+ endp = list_next (endp);
+ }
+ while (((flags & GSYNC_BROADCAST) || --nw != 0) &&
+ !list_end (&bp1->entries, endp) &&
+ gsync_key_eq (&node_to_waiter(endp)->key, &src_k));
+
+ /* Splice the list by removing waiters from the source queue
+ * and inserting them into the destination queue. */
+ inp->prev->next = endp;
+ endp->prev->next = outp->next;
+ endp->prev = inp->prev;
+
+ outp->next = inp;
+ inp->prev = outp;
+
+ if (wake_one)
+ (void)dequeue_waiter (inp);
+ }
+
+ /* Release the locks and we're done.*/
+ simple_unlock (&bp1->lock);
+ if (bp1 != bp2)
+ simple_unlock (&bp2->lock);
+
+ return (ret);
+}
+
diff --git a/kern/gsync.h b/kern/gsync.h
new file mode 100644
index 0000000..aafb649
--- /dev/null
+++ b/kern/gsync.h
@@ -0,0 +1,41 @@
+/* Copyright (C) 2016 Free Software Foundation, Inc.
+ Contributed by Agustina Arzille <address@hidden>, 2016.
+
+ 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/>.
+*/
+
+#ifndef _KERN_GSYNC_H_
+#define _KERN_GSYNC_H_ 1
+
+#define GSYNC_SHARED 0x01
+#define GSYNC_QUAD 0x02
+#define GSYNC_TIMED 0x04
+#define GSYNC_BROADCAST 0x08
+#define GSYNC_MUTATE 0x10
+
+#include <mach/mach_types.h>
+
+void gsync_setup (void);
+
+kern_return_t gsync_wait (task_t task, vm_offset_t addr,
+ unsigned int lo, unsigned int hi, natural_t msec, int flags);
+
+kern_return_t gsync_wake (task_t task,
+ vm_offset_t addr, unsigned int val, int flags);
+
+kern_return_t gsync_requeue (task_t task, vm_offset_t src_addr,
+ vm_offset_t dst_addr, boolean_t wake_one, int flags);
+
+#endif
diff --git a/kern/mach_clock.c b/kern/mach_clock.c
index 1817ce2..d6ebf23 100644
--- a/kern/mach_clock.c
+++ b/kern/mach_clock.c
@@ -133,7 +133,8 @@ timer_elt_data_t timer_head; /* ordered list of
timeouts */
void clock_interrupt(
int usec, /* microseconds per tick */
boolean_t usermode, /* executing user code */
- boolean_t basepri) /* at base priority */
+ boolean_t basepri, /* at base priority */
+ vm_offset_t pc) /* address of interrupted instruction */
{
int my_cpu = cpu_number();
thread_t thread = current_thread();
@@ -184,8 +185,11 @@ void clock_interrupt(
* This had better be MP safe. It might be interesting
* to keep track of cpu in the sample.
*/
- if (usermode) {
- take_pc_sample_macro(thread, SAMPLED_PC_PERIODIC);
+#ifndef MACH_KERNSAMPLE
+ if (usermode)
+#endif
+ {
+ take_pc_sample_macro(thread, SAMPLED_PC_PERIODIC, usermode, pc);
}
#endif /* MACH_PCSAMPLE */
diff --git a/kern/mach_clock.h b/kern/mach_clock.h
index 1af0cda..977b43b 100644
--- a/kern/mach_clock.h
+++ b/kern/mach_clock.h
@@ -62,7 +62,8 @@ typedef struct timer_elt *timer_elt_t;
extern void clock_interrupt(
int usec,
boolean_t usermode,
- boolean_t basepri);
+ boolean_t basepri,
+ vm_offset_t pc);
extern void softclock (void);
diff --git a/kern/pc_sample.c b/kern/pc_sample.c
index fcb9d71..e9f0b16 100644
--- a/kern/pc_sample.c
+++ b/kern/pc_sample.c
@@ -46,12 +46,18 @@ typedef sampled_pc_t sampled_pcs[MAX_PC_SAMPLES];
void take_pc_sample(
const thread_t t,
sample_control_t *cp,
- sampled_pc_flavor_t flavor)
+ sampled_pc_flavor_t flavor,
+ boolean_t usermode,
+ vm_offset_t kern_pc)
{
vm_offset_t pc;
struct sampled_pc *sample;
- pc = interrupted_pc(t);
+ if (usermode)
+ pc = interrupted_pc(t);
+ else
+ pc = kern_pc;
+
cp->seqno++;
sample = &((sampled_pc_t *)cp->buffer)[cp->seqno % MAX_PC_SAMPLES];
sample->id = (vm_offset_t)t;
diff --git a/kern/pc_sample.h b/kern/pc_sample.h
index 4832cb9..04ca667 100644
--- a/kern/pc_sample.h
+++ b/kern/pc_sample.h
@@ -71,22 +71,24 @@ typedef struct sample_control sample_control_t;
extern void take_pc_sample(
thread_t thread,
sample_control_t *cp,
- sampled_pc_flavor_t flavor);
+ sampled_pc_flavor_t flavor,
+ boolean_t usermode,
+ vm_offset_t pc);
/*
* Macro to do quick flavor check for sampling,
* on both threads and tasks.
*/
-#define take_pc_sample_macro(thread, flavor) \
+#define take_pc_sample_macro(thread, flavor, usermode, pc) \
MACRO_BEGIN \
task_t task; \
\
if ((thread)->pc_sample.sampletypes & (flavor)) \
- take_pc_sample((thread), &(thread)->pc_sample, (flavor)); \
+ take_pc_sample((thread), &(thread)->pc_sample, (flavor), usermode,
pc); \
\
task = (thread)->task; \
if (task->pc_sample.sampletypes & (flavor)) \
- take_pc_sample((thread), &task->pc_sample, (flavor)); \
+ take_pc_sample((thread), &task->pc_sample, (flavor), usermode, pc);
\
MACRO_END
#endif /* _KERN_PC_SAMPLE_H_ */
diff --git a/kern/rdxtree.h b/kern/rdxtree.h
index 1f8456e..9892d56 100644
--- a/kern/rdxtree.h
+++ b/kern/rdxtree.h
@@ -36,7 +36,7 @@
#define _RDXTREE_H
#include <stddef.h>
-#include <sys/types.h>
+#include <stdint.h>
/*
* Initialize the node cache.
diff --git a/kern/startup.c b/kern/startup.c
index bd29694..c87cbb1 100644
--- a/kern/startup.c
+++ b/kern/startup.c
@@ -36,6 +36,7 @@
#include <ipc/ipc_init.h>
#include <kern/cpu_number.h>
#include <kern/debug.h>
+#include <kern/gsync.h>
#include <kern/machine.h>
#include <kern/mach_factor.h>
#include <kern/mach_clock.h>
@@ -158,6 +159,8 @@ void setup_main(void)
recompute_priorities(NULL);
compute_mach_factor();
+ gsync_setup ();
+
/*
* Create a kernel thread to start the other kernel
* threads. Thread_resume (from kernel_thread) calls
diff --git a/linux/dev/include/linux/types.h b/linux/dev/include/linux/types.h
index b697d9e..eb086c2 100644
--- a/linux/dev/include/linux/types.h
+++ b/linux/dev/include/linux/types.h
@@ -109,16 +109,6 @@ struct ustat {
char f_fpack[6];
};
-/* stdint.h */
-typedef s8 int8_t;
-typedef u8 uint8_t;
-typedef s16 int16_t;
-typedef u16 uint16_t;
-typedef s32 int32_t;
-typedef u32 uint32_t;
-typedef s64 int64_t;
-typedef u64 uint64_t;
-
/* Yes, this is ugly. But that's why it is called glue code. */
#define _MACH_SA_SYS_TYPES_H_
diff --git a/version.m4 b/version.m4
index 029631f..c76a401 100644
--- a/version.m4
+++ b/version.m4
@@ -1,4 +1,4 @@
m4_define([AC_PACKAGE_NAME],[GNU Mach])
-m4_define([AC_PACKAGE_VERSION],[1.6+git20160311])
+m4_define([AC_PACKAGE_VERSION],[1.6+git20160502])
m4_define([AC_PACKAGE_BUGREPORT],address@hidden)
m4_define([AC_PACKAGE_TARNAME],[gnumach])
diff --git a/vm/vm_fault.c b/vm/vm_fault.c
index 09e2c54..68afc59 100644
--- a/vm/vm_fault.c
+++ b/vm/vm_fault.c
@@ -154,7 +154,7 @@ vm_fault_cleanup(
thread_t _thread_ = current_thread(); \
\
if (_thread_ != THREAD_NULL) \
- take_pc_sample_macro(_thread_, (flavor)); \
+ take_pc_sample_macro(_thread_, (flavor), 1, 0); \
MACRO_END
#else
diff --git a/vm/vm_resident.c b/vm/vm_resident.c
index fa7a337..79481a7 100644
--- a/vm/vm_resident.c
+++ b/vm/vm_resident.c
@@ -905,8 +905,10 @@ vm_page_t vm_page_grab_contig(
/* TODO Allow caller to pass type */
mem = vm_page_alloc_pa(order, selector, VM_PT_KERNEL);
- if (mem == NULL)
- panic("vm_page_grab_contig");
+ if (mem == NULL) {
+ simple_unlock(&vm_page_queue_free_lock);
+ return NULL;
+ }
for (i = 0; i < nr_pages; i++) {
mem[i].free = FALSE;
diff --git a/xen/block.c b/xen/block.c
index d98b31e..46df358 100644
--- a/xen/block.c
+++ b/xen/block.c
@@ -489,7 +489,7 @@ device_read (void *d, ipc_port_t reply_port,
req->operation = BLKIF_OP_READ;
req->nr_segments = nbpages;
req->handle = bd->handle;
- req->id = (unsigned64_t) (unsigned long) &err; /* pointer on the stack */
+ req->id = (uint64_t) (unsigned long) &err; /* pointer on the stack */
req->sector_number = bn + offset / 512;
for (i = 0; i < nbpages; i++) {
req->seg[i].gref = gref[i] = hyp_grant_give(bd->domid,
atop(pages[i]->phys_addr), 0);
@@ -641,7 +641,7 @@ device_write(void *d, ipc_port_t reply_port,
req->operation = BLKIF_OP_WRITE;
req->nr_segments = nbpages;
req->handle = bd->handle;
- req->id = (unsigned64_t) (unsigned long) &err; /* pointer on the stack */
+ req->id = (uint64_t) (unsigned long) &err; /* pointer on the stack */
req->sector_number = bn + i*PAGE_SIZE / 512;
for (j = 0; j < nbpages; j++) {
diff --git a/xen/net.c b/xen/net.c
index 5564365..7181d78 100644
--- a/xen/net.c
+++ b/xen/net.c
@@ -119,10 +119,10 @@ static void enqueue_rx_buf(struct net_data *nd, int
number) {
}
static int recompute_checksum(void *data, int len) {
- unsigned16_t *header16 = data;
- unsigned8_t *header8 = data;
+ uint16_t *header16 = data;
+ uint8_t *header8 = data;
unsigned length, i;
- unsigned32_t checksum = 0;
+ uint32_t checksum = 0;
/* IPv4 header length */
length = (header8[0] & 0xf) * 4;
@@ -145,8 +145,8 @@ static int recompute_checksum(void *data, int len) {
if (header8[9] == 6) {
/* Need to fix TCP checksum as well */
- unsigned16_t *tcp_header16 = header16 + length/2;
- unsigned8_t *tcp_header8 = header8 + length;
+ uint16_t *tcp_header16 = header16 + length/2;
+ uint8_t *tcp_header8 = header8 + length;
unsigned tcp_length = ntohs(header16[1]) - length;
/* Pseudo IP header */
@@ -166,7 +166,7 @@ static int recompute_checksum(void *data, int len) {
tcp_header16[8] = htons(~checksum);
} else if (header8[9] == 17) {
/* Drop any bogus checksum */
- unsigned16_t *udp_header16 = header16 + length/2;
+ uint16_t *udp_header16 = header16 + length/2;
udp_header16[3] = 0;
}
diff --git a/xen/public/elfstructs.h b/xen/public/elfstructs.h
index 77362f3..65d5345 100644
--- a/xen/public/elfstructs.h
+++ b/xen/public/elfstructs.h
@@ -353,7 +353,7 @@ typedef struct {
#define ELF64_R_SYM(info) ((info) >> 32)
#define ELF64_R_TYPE(info) ((info) & 0xFFFFFFFF)
-#define ELF64_R_INFO(s,t) (((s) << 32) + (u_int32_t)(t))
+#define ELF64_R_INFO(s,t) (((s) << 32) + (uint32_t)(t))
/* Program Header */
typedef struct {
diff --git a/xen/ring.h b/xen/ring.h
index c5c2fe3..1ac8b37 100644
--- a/xen/ring.h
+++ b/xen/ring.h
@@ -19,7 +19,7 @@
#ifndef XEN_RING_H
#define XEN_RING_H
-typedef unsigned32_t hyp_ring_pos_t;
+typedef uint32_t hyp_ring_pos_t;
#define hyp_ring_idx(ring, pos) (((unsigned)(pos)) & (sizeof(ring)-1))
#define hyp_ring_cell(ring, pos) (ring)[hyp_ring_idx((ring), (pos))]
diff --git a/xen/store.c b/xen/store.c
index 739dc36..659a70c 100644
--- a/xen/store.c
+++ b/xen/store.c
@@ -46,7 +46,7 @@ struct store_req {
};
/* Send a request */
-static void store_put(hyp_store_transaction_t t, unsigned32_t type, struct
store_req *req, unsigned nr_reqs) {
+static void store_put(hyp_store_transaction_t t, uint32_t type, struct
store_req *req, unsigned nr_reqs) {
struct xsd_sockmsg head = {
.type = type,
.req_id = 0,
@@ -105,7 +105,7 @@ static const char *errors[] = {
static struct xsd_sockmsg head;
const char *hyp_store_error;
-static void *store_put_wait(hyp_store_transaction_t t, unsigned32_t type,
struct store_req *req, unsigned nr_reqs) {
+static void *store_put_wait(hyp_store_transaction_t t, uint32_t type, struct
store_req *req, unsigned nr_reqs) {
unsigned len;
const char **error;
void *data;
diff --git a/xen/store.h b/xen/store.h
index ae236eb..6bb78ea 100644
--- a/xen/store.h
+++ b/xen/store.h
@@ -21,7 +21,7 @@
#include <machine/xen.h>
#include <xen/public/io/xenbus.h>
-typedef unsigned32_t hyp_store_transaction_t;
+typedef uint32_t hyp_store_transaction_t;
#define hyp_store_state_unknown "0"
#define hyp_store_state_initializing "1"
diff --git a/xen/time.c b/xen/time.c
index 4ebe91f..d483405 100644
--- a/xen/time.c
+++ b/xen/time.c
@@ -28,15 +28,15 @@
#include "time.h"
#include "store.h"
-static unsigned64_t lastnsec;
+static uint64_t lastnsec;
/* 2^64 nanoseconds ~= 500 years */
-static unsigned64_t hyp_get_stime(void) {
- unsigned32_t version;
- unsigned64_t cpu_clock, last_cpu_clock, delta, system_time;
- unsigned64_t delta_high, delta_low;
- unsigned32_t mul;
- signed8_t shift;
+static uint64_t hyp_get_stime(void) {
+ uint32_t version;
+ uint64_t cpu_clock, last_cpu_clock, delta, system_time;
+ uint64_t delta_high, delta_low;
+ uint32_t mul;
+ int8_t shift;
volatile struct vcpu_time_info *time =
&hyp_shared_info.vcpu_info[0].time;
do {
@@ -56,14 +56,14 @@ static unsigned64_t hyp_get_stime(void) {
else
delta <<= shift;
delta_high = delta >> 32;
- delta_low = (unsigned32_t) delta;
- return system_time + ((delta_low * (unsigned64_t) mul) >> 32)
- + (delta_high * (unsigned64_t) mul);
+ delta_low = (uint32_t) delta;
+ return system_time + ((delta_low * (uint64_t) mul) >> 32)
+ + (delta_high * (uint64_t) mul);
}
-unsigned64_t hyp_get_time(void) {
- unsigned32_t version;
- unsigned32_t sec, nsec;
+uint64_t hyp_get_time(void) {
+ uint32_t version;
+ uint32_t sec, nsec;
do {
version = hyp_shared_info.wc_version;
@@ -77,7 +77,7 @@ unsigned64_t hyp_get_time(void) {
}
static void hypclock_intr(int unit, int old_ipl, void *ret_addr, struct
i386_interrupt_state *regs) {
- unsigned64_t nsec, delta;
+ uint64_t nsec, delta;
if (!lastnsec)
return;
@@ -116,7 +116,7 @@ int
readtodc(tp)
u_int *tp;
{
- unsigned64_t t = hyp_get_time();
+ uint64_t t = hyp_get_time();
u_int n = t / 1000000000;
*tp = n;
@@ -138,7 +138,7 @@ clkstart()
hyp_evt_handler(port, hypclock_intr, 0, SPLHI);
/* first clock tick */
- clock_interrupt(0, 0, 0);
+ clock_interrupt(0, 0, 0, 0);
lastnsec = hyp_get_stime();
/* 10ms tick rest */
diff --git a/xen/time.h b/xen/time.h
index 8c8bc53..cf28720 100644
--- a/xen/time.h
+++ b/xen/time.h
@@ -20,6 +20,6 @@
#define XEN_TIME_H
#include <mach/mach_types.h>
-unsigned64_t hyp_get_time(void);
+uint64_t hyp_get_time(void);
#endif /* XEN_TIME_H */
--
Alioth's /usr/local/bin/git-commit-notice on
/srv/git.debian.org/git/pkg-hurd/gnumach.git