commit-hurd
[Top][All Lists]
Advanced

[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 master
in repository gnumach.

commit dd977fd2a7f59679b65434ff00b7b4c7c5864dd2
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 +-
 debian/changelog                          |   5 +-
 debian/patches/60_bigmem.patch            |  32 +--
 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 +-
 54 files changed, 1022 insertions(+), 224 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/debian/changelog b/debian/changelog
index 508adff..0a99e85 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,7 @@
-gnumach (2:1.6+git20160311-2) UNRELEASED; urgency=medium
+gnumach (2:1.6+git20160502-1) unstable; urgency=medium
 
   [ Samuel Thibault ]
+  * New upstream snapshot.
   * control.in: Really bump dpkg-dev and debhelper versions.
   * patches/20_FP_NO.patch: Avoid defining FP_NO.
   * patches/70_dde.patch: Fix crash when delivering the interrupt makes the
@@ -12,7 +13,7 @@ gnumach (2:1.6+git20160311-2) UNRELEASED; urgency=medium
   [ Svante Signell ]
   * rules: Add custom version in uname -v and custom packages names.
 
- -- Samuel Thibault <address@hidden>  Fri, 11 Mar 2016 23:21:56 +0000
+ -- Samuel Thibault <address@hidden>  Tue, 03 May 2016 00:16:34 +0000
 
 gnumach (2:1.6+git20160311-1) unstable; urgency=medium
 
diff --git a/debian/patches/60_bigmem.patch b/debian/patches/60_bigmem.patch
index 737a178..8d1b0cf 100644
--- a/debian/patches/60_bigmem.patch
+++ b/debian/patches/60_bigmem.patch
@@ -3,8 +3,8 @@ This makes glibc's local-bigmem.diff patch mandatory.
 
 Index: gnumach/i386/include/mach/i386/vm_param.h
 ===================================================================
---- gnumach.orig/i386/include/mach/i386/vm_param.h     2012-06-10 
23:45:02.000000000 +0200
-+++ gnumach/i386/include/mach/i386/vm_param.h  2012-07-14 15:57:26.423861314 
+0200
+--- gnumach.orig/i386/include/mach/i386/vm_param.h
++++ gnumach/i386/include/mach/i386/vm_param.h
 @@ -73,6 +73,6 @@
     with that.
     */
@@ -15,22 +15,22 @@ Index: gnumach/i386/include/mach/i386/vm_param.h
  #endif        /* _MACH_I386_VM_PARAM_H_ */
 Index: gnumach/i386/Makefrag.am
 ===================================================================
---- gnumach.orig/i386/Makefrag.am      2012-06-10 23:45:02.000000000 +0200
-+++ gnumach/i386/Makefrag.am   2012-07-14 15:57:26.427861233 +0200
-@@ -199,7 +199,7 @@ EXTRA_DIST += \
-       i386/ldscript
+--- gnumach.orig/i386/Makefrag.am
++++ gnumach/i386/Makefrag.am
+@@ -226,7 +226,7 @@ EXTRA_DIST += \
  if PLATFORM_at
  gnumach_LINKFLAGS += \
--      --defsym _START=0xC0100000 \
-+      --defsym _START=0x80100000 \
-       --defsym _START_MAP=0x100000 \
+       --defsym _START_MAP=$(_START_MAP) \
+-      --defsym _START=_START_MAP+0xC0000000 \
++      --defsym _START=_START_MAP+0x80000000 \
        -T '$(srcdir)'/i386/ldscript
  endif
+ 
 Index: gnumach/i386/i386/vm_param.h
 ===================================================================
---- gnumach.orig/i386/i386/vm_param.h  2012-06-10 23:45:02.000000000 +0200
-+++ gnumach/i386/i386/vm_param.h       2012-07-14 15:57:44.559495669 +0200
-@@ -31,7 +31,7 @@
+--- gnumach.orig/i386/i386/vm_param.h
++++ gnumach/i386/i386/vm_param.h
+@@ -35,7 +35,7 @@
  /* This can be changed freely to separate kernel addresses from user addresses
   * for better trace support in kdb; the _START symbol has to be offset by the
   * same amount. */
@@ -41,8 +41,8 @@ Index: gnumach/i386/i386/vm_param.h
  /* PV kernels can be loaded directly to the target virtual address */
 Index: gnumach/i386/xen/Makefrag.am
 ===================================================================
---- gnumach.orig/i386/xen/Makefrag.am  2012-07-14 15:58:19.998781083 +0200
-+++ gnumach/i386/xen/Makefrag.am       2012-07-14 15:58:30.254574271 +0200
+--- gnumach.orig/i386/xen/Makefrag.am
++++ gnumach/i386/xen/Makefrag.am
 @@ -28,7 +28,7 @@ libkernel_a_SOURCES += \
  
  if PLATFORM_xen
@@ -55,8 +55,8 @@ Index: gnumach/i386/xen/Makefrag.am
  endif
 Index: gnumach/i386/xen/xen_boothdr.S
 ===================================================================
---- gnumach.orig/i386/xen/xen_boothdr.S        2012-07-14 15:58:13.358914976 
+0200
-+++ gnumach/i386/xen/xen_boothdr.S     2012-07-14 15:58:39.790381972 +0200
+--- gnumach.orig/i386/xen/xen_boothdr.S
++++ gnumach/i386/xen/xen_boothdr.S
 @@ -22,8 +22,8 @@
        .ascii  "GUEST_OS=GNU Mach"
        .ascii  ",GUEST_VERSION=1.3"
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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]