commit-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnumach] 01/01: New upstream version 1.8+git20170609


From: Samuel Thibault
Subject: [gnumach] 01/01: New upstream version 1.8+git20170609
Date: Sat, 10 Jun 2017 00:38:35 +0000

This is an automated email from the git hooks/post-receive script.

sthibault pushed a commit to branch upstream
in repository gnumach.

commit 5d9383d87c39e5533e07108b8db35dfe22187869
Author: Samuel Thibault <address@hidden>
Date:   Fri Jun 9 23:39:58 2017 +0000

    New upstream version 1.8+git20170609
---
 ChangeLog                               |  48 +++++
 Makefile.am                             |   2 +-
 Makefile.in                             |  82 +++----
 Makefrag.am                             |   3 +
 configure                               |  20 +-
 doc/mach.info                           |   2 +-
 doc/mach.info-1                         |   4 +-
 doc/mach.info-2                         |   2 +-
 doc/stamp-vti                           |   4 +-
 doc/version.texi                        |   4 +-
 i386/i386at/rtc.c                       |  31 ++-
 kern/atomic.h                           |  54 +++++
 kern/bootstrap.c                        |   6 +
 kern/gsync.c                            | 368 ++++++++++++++++++++------------
 kern/kmutex.c                           |  76 +++++++
 kern/kmutex.h                           |  52 +++++
 kern/sched_prim.c                       |   5 +-
 kern/sched_prim.h                       |   2 +-
 linux/src/include/linux/compiler-gcc7.h |  67 ++++++
 version.m4                              |   2 +-
 vm/vm_object.h                          |  14 ++
 21 files changed, 647 insertions(+), 201 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ebe0116..f367650 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,51 @@
+2017-06-10  Samuel Thibault  <address@hidden>
+
+       Fix year computation
+       * i386/i386at/rtc.c (readtodc): Do not spuriously add 70 to the year.
+
+       Fix Epoch computation
+       * i386/i386at/rtc.c (CENTURY_START): New macro.
+       (readtodc): Use CENTURY_START instead of assuming it is equal to 1970,
+       and set yr to an absolute date before calling yeartoday.
+
+2017-05-07  David Michael  <address@hidden>
+
+       Support GCC 7
+       * Makefile.am (clib_routines): Add __udivmoddi4.
+       * linux/src/include/linux/compiler-gcc7.h: New file.
+
+2017-05-07  Samuel Thibault  <address@hidden>
+
+       Merge branch 'master' of git.savannah.gnu.org:/srv/git/hurd/gnumach
+
+2017-03-18  Justus Winter  <address@hidden>
+
+       kern: Make kernel task available to bootscript.
+       * kern/bootstrap.c (bootstrap_create): Insert the variable
+       'kernel-task' into the bootscript environment.  Userspace can use this
+       instead of guessing based on the order of the first tasks.
+
+2017-03-04  Agustina Arzille  <address@hidden>
+
+       Rewrite gsync so that it works with remote tasks v2
+
+       Implement basic sleeping locks for gnumach
+       * kern/atomic.h: New file.
+       * kern/kmutex.h: New file.
+       * kern/kmutex.c: New file.
+       * Makefrag.am (libkernel_a_SOURCES): Add atomic.h, kmutex.h, kmutex.c.
+       * kern/sched_prim.h (thread_wakeup_prim): Make it return boolean_t.
+       * kern/sched_prim.c (thread_wakeup_prim): Return TRUE if we woke a
+       thread, and FALSE otherwise.
+
+2017-01-24  Samuel Thibault  <address@hidden>
+
+       Fix bissextile years computation
+       In practice, fixes 2100, 2200, 2300, 2500, 2600, 2700, etc.
+
+       * i386/i386at/rtc.c (yeartoday): Make years divisible by 100 but not
+       divisible by 400 non-bisextile.
+
 2016-12-27  Richard Braun  <address@hidden>
 
        VM: really fix pageout of external objects backed by the default pager
diff --git a/Makefile.am b/Makefile.am
index 67252db..e7527ab 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -162,7 +162,7 @@ noinst_PROGRAMS += \
 
 # This is the list of routines we decide is OK to steal from the C library.
 clib_routines := htonl htons ntohl ntohs                       \
-                udivdi3 __udivdi3 __umoddi3                    \
+                udivdi3 __udivdi3 __udivmoddi4 __umoddi3       \
                 __rel_iplt_start __rel_iplt_end                \
                 __ffsdi2                                       \
                 _START _start etext _edata end _end # actually ld magic, not 
libc.
diff --git a/Makefile.in b/Makefile.in
index f12bdab..165515e 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1230,7 +1230,7 @@ am__libkernel_a_SOURCES_DIST = ddb/db_access.c 
ddb/db_access.h \
        ipc/ipc_thread.c ipc/ipc_thread.h ipc/ipc_types.h \
        ipc/mach_msg.c ipc/mach_msg.h ipc/mach_port.c ipc/mach_port.h \
        ipc/mach_rpc.c ipc/mach_debug.c ipc/port.h kern/act.c \
-       kern/act.h kern/assert.h kern/ast.c kern/ast.h \
+       kern/act.h kern/assert.h kern/ast.c kern/ast.h kern/atomic.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 \
@@ -1238,16 +1238,17 @@ am__libkernel_a_SOURCES_DIST = ddb/db_access.c 
ddb/db_access.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/ipc_tt.h kern/kalloc.h kern/kern_types.h kern/kmutex.c \
+       kern/kmutex.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 \
@@ -1443,21 +1444,22 @@ am_libkernel_a_OBJECTS = $(am__objects_2) 
ipc/ipc_entry.$(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/kmutex.$(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) \
@@ -2555,7 +2557,7 @@ libkernel_a_SOURCES = $(am__append_2) ipc/ipc_entry.c 
ipc/ipc_entry.h \
        ipc/ipc_thread.c ipc/ipc_thread.h ipc/ipc_types.h \
        ipc/mach_msg.c ipc/mach_msg.h ipc/mach_port.c ipc/mach_port.h \
        ipc/mach_rpc.c ipc/mach_debug.c ipc/port.h kern/act.c \
-       kern/act.h kern/assert.h kern/ast.c kern/ast.h \
+       kern/act.h kern/assert.h kern/ast.c kern/ast.h kern/atomic.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 \
@@ -2563,16 +2565,17 @@ libkernel_a_SOURCES = $(am__append_2) ipc/ipc_entry.c 
ipc/ipc_entry.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/ipc_tt.h kern/kalloc.h kern/kern_types.h kern/kmutex.c \
+       kern/kmutex.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 \
@@ -2921,7 +2924,7 @@ gnumach_o_LINK = $(LD) $(LDFLAGS) -u _start -r -o $@
 
 # This is the list of routines we decide is OK to steal from the C library.
 clib_routines := htonl htons ntohl ntohs                       \
-                udivdi3 __udivdi3 __umoddi3                    \
+                udivdi3 __udivdi3 __udivmoddi4 __umoddi3       \
                 __rel_iplt_start __rel_iplt_end                \
                 __ffsdi2                                       \
                 _START _start etext _edata end _end # actually ld magic, not 
libc.
@@ -3178,6 +3181,8 @@ kern/ipc_sched.$(OBJEXT): kern/$(am__dirstamp) \
        kern/$(DEPDIR)/$(am__dirstamp)
 kern/ipc_tt.$(OBJEXT): kern/$(am__dirstamp) \
        kern/$(DEPDIR)/$(am__dirstamp)
+kern/kmutex.$(OBJEXT): kern/$(am__dirstamp) \
+       kern/$(DEPDIR)/$(am__dirstamp)
 kern/lock.$(OBJEXT): kern/$(am__dirstamp) \
        kern/$(DEPDIR)/$(am__dirstamp)
 kern/lock_mon.$(OBJEXT): kern/$(am__dirstamp) \
@@ -4280,6 +4285,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 c16f1c7..4625b48 100644
--- a/Makefrag.am
+++ b/Makefrag.am
@@ -132,6 +132,7 @@ libkernel_a_SOURCES += \
        kern/assert.h \
        kern/ast.c \
        kern/ast.h \
+       kern/atomic.h \
        kern/boot_script.h \
        kern/bootstrap.c \
        kern/bootstrap.h \
@@ -160,6 +161,8 @@ libkernel_a_SOURCES += \
        kern/ipc_tt.h \
        kern/kalloc.h \
        kern/kern_types.h \
+       kern/kmutex.c \
+       kern/kmutex.h \
        kern/list.h \
        kern/lock.c \
        kern/lock.h \
diff --git a/configure b/configure
index 7d869e4..7ff9489 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.8+git20170102.
+# Generated by GNU Autoconf 2.69 for GNU Mach 1.8+git20170609.
 #
 # Report bugs to <address@hidden>.
 #
@@ -579,8 +579,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='GNU Mach'
 PACKAGE_TARNAME='gnumach'
-PACKAGE_VERSION='1.8+git20170102'
-PACKAGE_STRING='GNU Mach 1.8+git20170102'
+PACKAGE_VERSION='1.8+git20170609'
+PACKAGE_STRING='GNU Mach 1.8+git20170609'
 PACKAGE_BUGREPORT='address@hidden'
 PACKAGE_URL=''
 
@@ -1599,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.8+git20170102 to adapt to many kinds of 
systems.
+\`configure' configures GNU Mach 1.8+git20170609 to adapt to many kinds of 
systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1670,7 +1670,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of GNU Mach 1.8+git20170102:";;
+     short | recursive ) echo "Configuration of GNU Mach 1.8+git20170609:";;
    esac
   cat <<\_ACEOF
 
@@ -2026,7 +2026,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-GNU Mach configure 1.8+git20170102
+GNU Mach configure 1.8+git20170609
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2118,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.8+git20170102, which was
+It was created by GNU Mach $as_me 1.8+git20170609, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2984,7 +2984,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='gnumach'
- VERSION='1.8+git20170102'
+ VERSION='1.8+git20170609'
 
 
 # Some tools Automake needs.
@@ -12189,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.8+git20170102, which was
+This file was extended by GNU Mach $as_me 1.8+git20170609, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -12260,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.8+git20170102
+GNU Mach config.status 1.8+git20170609
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff --git a/doc/mach.info b/doc/mach.info
index 0428c7e..071e74a 100644
--- a/doc/mach.info
+++ b/doc/mach.info
@@ -3,7 +3,7 @@ This is mach.info, produced by makeinfo version 6.3 from 
mach.texi.
 This file documents the GNU Mach microkernel.
 
    This is edition 0.4, last updated on 2 January 2017, of 'The GNU Mach
-Reference Manual', for version 1.8+git20170102.
+Reference Manual', for version 1.8+git20170609.
 
    Copyright (C) 2001, 2002, 2006, 2007, 2008 Free Software Foundation,
 Inc.
diff --git a/doc/mach.info-1 b/doc/mach.info-1
index 449b1a1..15b960d 100644
--- a/doc/mach.info-1
+++ b/doc/mach.info-1
@@ -3,7 +3,7 @@ This is mach.info, produced by makeinfo version 6.3 from 
mach.texi.
 This file documents the GNU Mach microkernel.
 
    This is edition 0.4, last updated on 2 January 2017, of 'The GNU Mach
-Reference Manual', for version 1.8+git20170102.
+Reference Manual', for version 1.8+git20170609.
 
    Copyright (C) 2001, 2002, 2006, 2007, 2008 Free Software Foundation,
 Inc.
@@ -46,7 +46,7 @@ Main Menu
 This file documents the GNU Mach microkernel.
 
    This is edition 0.4, last updated on 2 January 2017, of 'The GNU Mach
-Reference Manual', for version 1.8+git20170102.
+Reference Manual', for version 1.8+git20170609.
 
    Copyright (C) 2001, 2002, 2006, 2007, 2008 Free Software Foundation,
 Inc.
diff --git a/doc/mach.info-2 b/doc/mach.info-2
index c253c14..8a3d0b9 100644
--- a/doc/mach.info-2
+++ b/doc/mach.info-2
@@ -3,7 +3,7 @@ This is mach.info, produced by makeinfo version 6.3 from 
mach.texi.
 This file documents the GNU Mach microkernel.
 
    This is edition 0.4, last updated on 2 January 2017, of 'The GNU Mach
-Reference Manual', for version 1.8+git20170102.
+Reference Manual', for version 1.8+git20170609.
 
    Copyright (C) 2001, 2002, 2006, 2007, 2008 Free Software Foundation,
 Inc.
diff --git a/doc/stamp-vti b/doc/stamp-vti
index 9278519..d693eed 100644
--- a/doc/stamp-vti
+++ b/doc/stamp-vti
@@ -1,4 +1,4 @@
 @set UPDATED 2 January 2017
 @set UPDATED-MONTH January 2017
address@hidden EDITION 1.8+git20170102
address@hidden VERSION 1.8+git20170102
address@hidden EDITION 1.8+git20170609
address@hidden VERSION 1.8+git20170609
diff --git a/doc/version.texi b/doc/version.texi
index 9278519..d693eed 100644
--- a/doc/version.texi
+++ b/doc/version.texi
@@ -1,4 +1,4 @@
 @set UPDATED 2 January 2017
 @set UPDATED-MONTH January 2017
address@hidden EDITION 1.8+git20170102
address@hidden VERSION 1.8+git20170102
address@hidden EDITION 1.8+git20170609
address@hidden VERSION 1.8+git20170609
diff --git a/i386/i386at/rtc.c b/i386/i386at/rtc.c
index 01e0977..6e5cdeb 100644
--- a/i386/i386at/rtc.c
+++ b/i386/i386at/rtc.c
@@ -53,6 +53,10 @@ WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <i386/pio.h>
 #include <i386at/rtc.h>
 
+/* time of day stored in RTC are currently between 1970 and 2070. Update that
+ * before 2070 please. */
+#define CENTURY_START  1970
+
 static boolean_t first_rtcopen_ever = TRUE;
 
 void
@@ -109,7 +113,24 @@ static int month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 
30, 31, 30, 31};
 int
 yeartoday(int year)
 {
-       return((year%4) ? 365 : 366);
+       if (year%4)
+               /* Not divisible by 4, not bissextile */
+               return 365;
+
+       /* Divisible by 4 */
+       if (year % 100)
+               /* Not divisible by 100, bissextile */
+               return 366;
+
+       /* Divisible by 100 */
+       if (year % 400)
+               /* Not divisible by 400, not bissextile */
+               return 365;
+
+       /* Divisible by 400 */
+       /* Rules for 2000 and further have not been officially decided yet.
+        * 2000 was made bissextile.  */
+       return 366;
 }
 
 int
@@ -146,7 +167,9 @@ readtodc(u_int *tp)
        dom = hexdectodec(rtclk.rtc_dom);
        mon = hexdectodec(rtclk.rtc_mon);
        yr = hexdectodec(rtclk.rtc_yr);
-       yr = (yr < 70) ? yr+100 : yr;
+       yr = (yr < CENTURY_START%100) ?
+               yr+CENTURY_START-CENTURY_START%100+100 :
+               yr+CENTURY_START-CENTURY_START%100;
 
        n = sec + 60 * min + 3600 * hr;
        n += (dom - 1) * 3600 * 24;
@@ -156,7 +179,8 @@ readtodc(u_int *tp)
        for (i = mon - 2; i >= 0; i--)
                days += month[i];
        month[1] = 28;
-       for (i = 70; i < yr; i++)
+       /* Epoch shall be 1970 January 1st */
+       for (i = 1970; i < yr; i++)
                days += yeartoday(i);
        n += days * 3600 * 24;
 
@@ -191,6 +215,7 @@ writetodc(void)
        n = (time.tv_sec - diff) / (3600 * 24); /* days */
        rtclk.rtc_dow = (n + 4) % 7;  /* 1/1/70 is Thursday */
 
+       /* Epoch shall be 1970 January 1st */
        for (j = 1970, i = yeartoday(j); n >= i; j++, i = yeartoday(j))
                n -= i;
 
diff --git a/kern/atomic.h b/kern/atomic.h
new file mode 100644
index 0000000..00da164
--- /dev/null
+++ b/kern/atomic.h
@@ -0,0 +1,54 @@
+/* Copyright (C) 2017 Free Software Foundation, Inc.
+   Contributed by Agustina Arzille <address@hidden>, 2017.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; either
+   version 2 of the license, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _KERN_ATOMIC_H_
+#define _KERN_ATOMIC_H_   1
+
+/* Atomically compare *PTR with EXP and set it to NVAL if they're equal.
+ * Evaluates to a boolean, indicating whether the comparison was successful.*/
+#define __atomic_cas_helper(ptr, exp, nval, mo)   \
+  ({   \
+     typeof(exp) __e = (exp);   \
+     __atomic_compare_exchange_n ((ptr), &__e, (nval), 0,   \
+       __ATOMIC_##mo, __ATOMIC_RELAXED);   \
+   })
+
+#define atomic_cas_acq(ptr, exp, nval)   \
+  __atomic_cas_helper (ptr, exp, nval, ACQUIRE)
+
+#define atomic_cas_rel(ptr, exp, nval)   \
+  __atomic_cas_helper (ptr, exp, nval, RELEASE)
+
+#define atomic_cas_seq(ptr, exp, nval)   \
+  __atomic_cas_helper (ptr, exp, nval, SEQ_CST)
+
+/* Atomically exchange the value of *PTR with VAL, evaluating to
+ * its previous value. */
+#define __atomic_swap_helper(ptr, val, mo)   \
+  __atomic_exchange_n ((ptr), (val), __ATOMIC_##mo)
+
+#define atomic_swap_acq(ptr, val)   \
+  __atomic_swap_helper (ptr, val, ACQUIRE)
+
+#define atomic_swap_rel(ptr, val)   \
+  __atomic_swap_helper (ptr, val, RELEASE)
+
+#define atomic_swap_seq(ptr, val)   \
+  __atomic_swap_helper (ptr, val, SEQ_CST)
+
+#endif
diff --git a/kern/bootstrap.c b/kern/bootstrap.c
index 7398ea4..c21d3b1 100644
--- a/kern/bootstrap.c
+++ b/kern/bootstrap.c
@@ -180,6 +180,12 @@ void bootstrap_create(void)
       if (losers)
        panic ("cannot set boot-script variable device-port: %s",
               boot_script_error_string (losers));
+      losers = boot_script_set_variable
+       ("kernel-task", VAL_PORT,
+        (long) kernel_task->itk_self);
+      if (losers)
+       panic ("cannot set boot-script variable kernel-task: %s",
+              boot_script_error_string (losers));
 
       losers = boot_script_set_variable ("kernel-command-line", VAL_STR,
                                         (long) kernel_cmdline);
diff --git a/kern/gsync.c b/kern/gsync.c
index e70e119..56d0438 100644
--- a/kern/gsync.c
+++ b/kern/gsync.c
@@ -17,36 +17,61 @@
 */
 
 #include <kern/gsync.h>
+#include <kern/kmutex.h>
 #include <kern/sched_prim.h>
 #include <kern/thread.h>
-#include <kern/lock.h>
 #include <kern/list.h>
 #include <vm/vm_map.h>
+#include <vm/vm_kern.h>
 
 /* An entry in the global hash table. */
 struct gsync_hbucket
 {
   struct list entries;
-  decl_simple_lock_data (, lock)
+  struct kmutex 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
+ * address is shared or task-local. Note that different types of keys
+ * should never compare equal, since a task map should never have
+ * the same address as a VM object. */
+union gsync_key
 {
-  unsigned long u;
-  unsigned long v;
+  struct
+    {
+      vm_map_t map;
+      vm_offset_t addr;
+    } local;
+
+  struct
+    {
+      vm_object_t obj;
+      vm_offset_t off;
+    } shared;
+
+  struct
+    {
+      unsigned long u;
+      unsigned long v;
+    } any;
 };
 
 /* A thread that is blocked on an address with 'gsync_wait'. */
 struct gsync_waiter
 {
   struct list link;
-  struct gsync_key key;
+  union gsync_key key;
   thread_t waiter;
 };
 
+/* Needed data for temporary mappings. */
+struct vm_args
+{
+  vm_object_t obj;
+  vm_offset_t off;
+};
+
 #define GSYNC_NBUCKETS   512
 static struct gsync_hbucket gsync_buckets[GSYNC_NBUCKETS];
 
@@ -56,97 +81,93 @@ void gsync_setup (void)
   for (i = 0; i < GSYNC_NBUCKETS; ++i)
     {
       list_init (&gsync_buckets[i].entries);
-      simple_lock_init (&gsync_buckets[i].lock);
+      kmutex_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)
+gsync_key_eq (const union gsync_key *lp,
+  const union gsync_key *rp)
 {
-  return (lp->u == rp->u && lp->v == rp->v);
+  return (lp->any.u == rp->any.u && lp->any.v == rp->any.v);
 }
 
 static inline int
-gsync_key_lt (const struct gsync_key *lp,
-  const struct gsync_key *rp)
+gsync_key_lt (const union gsync_key *lp,
+  const union gsync_key *rp)
 {
-  return (lp->u < rp->u || (lp->u == rp->u && lp->v < rp->v));
+  return (lp->any.u < rp->any.u ||
+    (lp->any.u == rp->any.u && lp->any.v < rp->any.v));
 }
 
 #define MIX2_LL(x, y)   ((((x) << 5) | ((x) >> 27)) ^ (y))
 
 static inline unsigned int
-gsync_key_hash (const struct gsync_key *keyp)
+gsync_key_hash (const union gsync_key *keyp)
 {
   unsigned int ret = sizeof (void *);
 #ifndef __LP64__
-  ret = MIX2_LL (ret, keyp->u);
-  ret = MIX2_LL (ret, keyp->v);
+  ret = MIX2_LL (ret, keyp->any.u);
+  ret = MIX2_LL (ret, keyp->any.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);
+  ret = MIX2_LL (ret, keyp->any.u & ~0U);
+  ret = MIX2_LL (ret, keyp->any.u >> 32);
+  ret = MIX2_LL (ret, keyp->any.v & ~0U);
+  ret = MIX2_LL (ret, keyp->any.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. */
+/* Perform a VM lookup for the address in the map. The FLAGS
+ * parameter is used to specify some attributes for the address,
+ * such as protection. Place the corresponding VM object/offset pair
+ * in VAP. Returns 0 if successful, -1 otherwise. */
 static int
-valid_access_p (vm_map_t map, vm_offset_t addr, int flags)
+probe_address (vm_map_t map, vm_offset_t addr,
+  int flags, struct vm_args *vap)
 {
   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_version_t ver;
+  vm_prot_t rprot;
+  boolean_t wired_p;
+
+  if (vm_map_lookup (&map, addr, prot, &ver,
+      &vap->obj, &vap->off, &rprot, &wired_p) != KERN_SUCCESS)
+    return (-1);
+  else if ((rprot & prot) != prot)
+    {
+      vm_object_unlock (vap->obj);
+      return (-1);
+    }
 
-  vm_map_entry_t entry;
-  return (vm_map_lookup_entry (map, addr, &entry) &&
-    entry->vme_end >= addr + size &&
-    (prot & entry->protection) == prot);
+  return (0);
 }
 
-/* Given a task and an address, initialize the key at *KEYP and
- * return the corresponding bucket in the global hash table. */
+/* Initialize the key with its needed members, depending on whether the
+ * address is local or shared. Also stores the VM object and offset inside
+ * the argument VAP for future use. */
 static int
-gsync_fill_key (task_t task, vm_offset_t addr,
-  int flags, struct gsync_key *keyp)
+gsync_prepare_key (task_t task, vm_offset_t addr, int flags,
+  union gsync_key *keyp, struct vm_args *vap)
 {
-  if (flags & GSYNC_SHARED)
+  if (probe_address (task->map, addr, flags, vap) < 0)
+    return (-1);
+  else 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;
+      keyp->shared.obj = vap->obj;
+      keyp->shared.off = vap->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;
+      keyp->local.map = task->map;
+      keyp->local.addr = addr;
     }
 
   return ((int)(gsync_key_hash (keyp) % GSYNC_NBUCKETS));
@@ -160,7 +181,7 @@ node_to_waiter (struct list *nodep)
 
 static inline struct list*
 gsync_find_key (const struct list *entries,
-  const struct gsync_key *keyp, int *exactp)
+  const union 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
@@ -182,57 +203,105 @@ gsync_find_key (const struct list *entries,
   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)
+/* Create a temporary mapping in the kernel.*/
+static inline vm_offset_t
+temp_mapping (struct vm_args *vap, vm_offset_t addr, vm_prot_t prot)
 {
-  if (unlikely (task != current_task()))
-    /* Not implemented yet.  */
-    return (KERN_FAILURE);
+  vm_offset_t paddr;
+  /* Adjust the offset for addresses that aren't page-aligned. */
+  vm_offset_t off = vap->off - (addr - trunc_page (addr));
 
-  struct gsync_waiter w;
-  int bucket = gsync_fill_key (task, addr, flags, &w.key);
+  if (vm_map_enter (kernel_map, &paddr, PAGE_SIZE,
+      0, TRUE, vap->obj, off, FALSE, prot, VM_PROT_ALL,
+      VM_INHERIT_DEFAULT) != KERN_SUCCESS)
+    paddr = 0;
+
+  return (paddr);
+}
 
-  if (unlikely (bucket < 0))
+kern_return_t gsync_wait (task_t task, vm_offset_t addr,
+  unsigned int lo, unsigned int hi, natural_t msec, int flags)
+{
+  if (task == 0)
+    return (KERN_INVALID_TASK);
+  else if (addr % sizeof (int) != 0)
     return (KERN_INVALID_ADDRESS);
 
-  /* 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);
 
-  struct gsync_hbucket *hbp = gsync_buckets + bucket;
-  simple_lock (&hbp->lock);
+  struct gsync_waiter w;
+  struct vm_args va;
+  boolean_t remote = task != current_task ();
+  int bucket = gsync_prepare_key (task, addr, flags, &w.key, &va);
 
-  if (unlikely (!valid_access_p (task->map, addr, flags)))
+  if (bucket < 0)
     {
-      simple_unlock (&hbp->lock);
       vm_map_unlock_read (task->map);
       return (KERN_INVALID_ADDRESS);
     }
+  else if (remote)
+    /* The VM object is returned locked. However, we are about to acquire
+     * a sleeping lock for a bucket, so we must not hold any simple
+     * locks. To prevent this object from going away, we add a reference
+     * to it when requested. */
+    vm_object_reference_locked (va.obj);
+
+  /* We no longer need the lock on the VM object. */
+  vm_object_unlock (va.obj);
+
+  struct gsync_hbucket *hbp = gsync_buckets + bucket;
+  kmutex_lock (&hbp->lock, FALSE);
 
   /* 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))
+
+  boolean_t equal;
+  if (! remote)
+    equal = ((unsigned int *)addr)[0] == lo &&
+      ((flags & GSYNC_QUAD) == 0 ||
+       ((unsigned int *)addr)[1] == hi);
+  else
     {
-      simple_unlock (&hbp->lock);
-      vm_map_unlock_read (task->map);
-      return (KERN_INVALID_ARGUMENT);
+      vm_offset_t paddr = temp_mapping (&va, addr, VM_PROT_READ);
+      if (unlikely (paddr == 0))
+        {
+          kmutex_unlock (&hbp->lock);
+          vm_map_unlock_read (task->map);
+          /* Make sure to remove the reference we added. */
+          vm_object_deallocate (va.obj);
+          return (KERN_MEMORY_FAILURE);
+        }
+
+      vm_offset_t off = addr & (PAGE_SIZE - 1);
+      paddr += off;
+
+      equal = ((unsigned int *)paddr)[0] == lo &&
+        ((flags & GSYNC_QUAD) == 0 ||
+         ((unsigned int *)paddr)[1] == hi);
+
+      paddr -= off;
+
+      /* Note that the call to 'vm_map_remove' will unreference
+       * the VM object, so we don't have to do it ourselves. */
+      vm_map_remove (kernel_map, paddr, paddr + PAGE_SIZE);
     }
 
+  /* Done with the task's map. */
   vm_map_unlock_read (task->map);
 
+  if (! equal)
+    {
+      kmutex_unlock (&hbp->lock);
+      return (KERN_INVALID_ARGUMENT);
+    }
+
   /* 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;
-    }
+    if (gsync_key_lt (&w.key, &node_to_waiter(runp)->key))
+      break;
 
   /* Finally, add ourselves to the list and go to sleep. */
   list_add (runp->prev, runp, &w.link);
@@ -243,24 +312,23 @@ kern_return_t gsync_wait (task_t task, vm_offset_t addr,
   else
     thread_will_wait (w.waiter);
 
-  thread_sleep (0, (simple_lock_t)&hbp->lock, TRUE);
+  kmutex_unlock (&hbp->lock);
+  thread_block (thread_no_continuation);
 
   /* We're back. */
-  kern_return_t ret = current_thread()->wait_result;
-  if (ret != THREAD_AWAKENED)
+  kern_return_t ret = KERN_SUCCESS;
+  if (current_thread()->wait_result != THREAD_AWAKENED)
     {
       /* We were interrupted or timed out. */
-      simple_lock (&hbp->lock);
-      if (w.link.next != 0)
+      kmutex_lock (&hbp->lock, FALSE);
+      if (!list_node_unlinked (&w.link))
         list_remove (&w.link);
-      simple_unlock (&hbp->lock);
+      kmutex_unlock (&hbp->lock);
 
       /* Map the error code. */
-      ret = ret == THREAD_INTERRUPTED ?
+      ret = current_thread()->wait_result == THREAD_INTERRUPTED ?
         KERN_INTERRUPTED : KERN_TIMEDOUT;
     }
-  else
-    ret = KERN_SUCCESS;
 
   return (ret);
 }
@@ -281,34 +349,60 @@ dequeue_waiter (struct list *nodep)
 kern_return_t gsync_wake (task_t task,
   vm_offset_t addr, unsigned int val, int flags)
 {
-  if (unlikely (task != current_task()))
-    /* Not implemented yet.  */
-    return (KERN_FAILURE);
-
-  struct gsync_key key;
-  int bucket = gsync_fill_key (task, addr, flags, &key);
-
-  if (unlikely (bucket < 0))
+  if (task == 0)
+    return (KERN_INVALID_TASK);
+  else if (addr % sizeof (int) != 0)
     return (KERN_INVALID_ADDRESS);
 
-  kern_return_t ret = KERN_INVALID_ARGUMENT;
-
   vm_map_lock_read (task->map);
-  struct gsync_hbucket *hbp = gsync_buckets + bucket;
-  simple_lock (&hbp->lock);
 
-  if (unlikely (!valid_access_p (task->map, addr, flags)))
+  union gsync_key key;
+  struct vm_args va;
+  int bucket = gsync_prepare_key (task, addr, flags, &key, &va);
+
+  if (bucket < 0)
     {
-      simple_unlock (&hbp->lock);
       vm_map_unlock_read (task->map);
       return (KERN_INVALID_ADDRESS);
     }
+  else if (current_task () != task && (flags & GSYNC_MUTATE) != 0)
+    /* See above on why we do this. */
+    vm_object_reference_locked (va.obj);
+
+  /* Done with the VM object lock. */
+  vm_object_unlock (va.obj);
+
+  kern_return_t ret = KERN_INVALID_ARGUMENT;
+  struct gsync_hbucket *hbp = gsync_buckets + bucket;
+
+  kmutex_lock (&hbp->lock, FALSE);
 
   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;
+    {
+      /* 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. */
+
+      if (task != current_task ())
+        {
+          vm_offset_t paddr = temp_mapping (&va, addr,
+            VM_PROT_READ | VM_PROT_WRITE);
+
+          if (paddr == 0)
+            {
+              kmutex_unlock (&hbp->lock);
+              vm_map_unlock_read (task->map);
+              vm_object_deallocate (va.obj);
+              return (KERN_MEMORY_FAILURE);
+            }
+
+          addr = paddr + (addr & (PAGE_SIZE - 1));
+        }
+
+      *(unsigned int *)addr = val;
+      if (task != current_task ())
+        vm_map_remove (kernel_map, addr, addr + sizeof (int));
+    }
 
   vm_map_unlock_read (task->map);
 
@@ -325,37 +419,35 @@ kern_return_t gsync_wake (task_t task,
       ret = KERN_SUCCESS;
     }
 
-  simple_unlock (&hbp->lock);
+  kmutex_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)
 {
-  if (unlikely (task != current_task()))
-    /* Not implemented yet.  */
-    return (KERN_FAILURE);
+  if (task == 0)
+    return (KERN_INVALID_TASK);
+  else if (src % sizeof (int) != 0 || dst % sizeof (int) != 0)
+    return (KERN_INVALID_ADDRESS);
 
-  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);
+  union gsync_key src_k, dst_k;
+  struct vm_args va;
 
-  if ((src_bkt | dst_bkt) < 0)
+  int src_bkt = gsync_prepare_key (task, src, flags, &src_k, &va);
+  if (src_bkt < 0)
     return (KERN_INVALID_ADDRESS);
 
-  vm_map_lock_read (task->map);
+  /* Unlock the VM object before the second lookup. */
+  vm_object_unlock (va.obj);
 
-  /* 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);
-    }
+  int dst_bkt = gsync_prepare_key (task, dst, flags, &dst_k, &va);
+  if (dst_bkt < 0)
+    return (KERN_INVALID_ADDRESS);
 
-  vm_map_unlock_read (task->map);
+  /* We never create any temporary mappings in 'requeue', so we
+   * can unlock the VM object right now. */
+  vm_object_unlock (va.obj);
 
   /* If we're asked to unconditionally wake up a waiter, then
    * we need to remove a maximum of two threads from the queue. */
@@ -365,23 +457,23 @@ kern_return_t gsync_requeue (task_t task, vm_offset_t src,
 
   /* Acquire the locks in order, to prevent any potential deadlock. */
   if (bp1 == bp2)
-    simple_lock (&bp1->lock);
+    kmutex_lock (&bp1->lock, FALSE);
   else if ((unsigned long)bp1 < (unsigned long)bp2)
     {
-      simple_lock (&bp1->lock);
-      simple_lock (&bp2->lock);
+      kmutex_lock (&bp1->lock, FALSE);
+      kmutex_lock (&bp2->lock, FALSE);
     }
   else
     {
-      simple_lock (&bp2->lock);
-      simple_lock (&bp1->lock);
+      kmutex_lock (&bp2->lock, FALSE);
+      kmutex_lock (&bp1->lock, FALSE);
     }
 
   kern_return_t ret = KERN_SUCCESS;
   int exact;
   struct list *inp = gsync_find_key (&bp1->entries, &src_k, &exact);
 
-  if (!exact)
+  if (! exact)
     /* There are no waiters in the source queue. */
     ret = KERN_INVALID_ARGUMENT;
   else
@@ -416,9 +508,9 @@ kern_return_t gsync_requeue (task_t task, vm_offset_t src,
     }
 
   /* Release the locks and we're done.*/
-  simple_unlock (&bp1->lock);
+  kmutex_unlock (&bp1->lock);
   if (bp1 != bp2)
-    simple_unlock (&bp2->lock);
+    kmutex_unlock (&bp2->lock);
 
   return (ret);
 }
diff --git a/kern/kmutex.c b/kern/kmutex.c
new file mode 100644
index 0000000..5926d1d
--- /dev/null
+++ b/kern/kmutex.c
@@ -0,0 +1,76 @@
+/* Copyright (C) 2017 Free Software Foundation, Inc.
+   Contributed by Agustina Arzille <address@hidden>, 2017.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; either
+   version 2 of the license, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <kern/kmutex.h>
+#include <kern/atomic.h>
+#include <kern/sched_prim.h>
+#include <kern/thread.h>
+
+void kmutex_init (struct kmutex *mtxp)
+{
+  mtxp->state = KMUTEX_AVAIL;
+  simple_lock_init (&mtxp->lock);
+}
+
+kern_return_t kmutex_lock (struct kmutex *mtxp, boolean_t interruptible)
+{
+  check_simple_locks ();
+
+  if (atomic_cas_acq (&mtxp->state, KMUTEX_AVAIL, KMUTEX_LOCKED))
+    /* Unowned mutex - We're done. */
+    return (KERN_SUCCESS);
+
+  /* The mutex is locked. We may have to sleep. */
+  simple_lock (&mtxp->lock);
+  if (atomic_swap_acq (&mtxp->state, KMUTEX_CONTENDED) == KMUTEX_AVAIL)
+    {
+      /* The mutex was released in-between. */
+      simple_unlock (&mtxp->lock);
+      return (KERN_SUCCESS);
+    }
+
+  /* Sleep and check the result value of the waiting, in order to
+   * inform our caller if we were interrupted or not. Note that
+   * we don't need to set again the mutex state. The owner will
+   * handle that in every case. */
+  thread_sleep ((event_t)mtxp, (simple_lock_t)&mtxp->lock, interruptible);
+  return (current_thread()->wait_result == THREAD_AWAKENED ?
+    KERN_SUCCESS : KERN_INTERRUPTED);
+}
+
+kern_return_t kmutex_trylock (struct kmutex *mtxp)
+{
+  return (atomic_cas_acq (&mtxp->state, KMUTEX_AVAIL, KMUTEX_LOCKED) ?
+    KERN_SUCCESS : KERN_FAILURE);
+}
+
+void kmutex_unlock (struct kmutex *mtxp)
+{
+  if (atomic_cas_rel (&mtxp->state, KMUTEX_LOCKED, KMUTEX_AVAIL))
+    /* No waiters - We're done. */
+    return;
+
+  simple_lock (&mtxp->lock);
+
+  if (!thread_wakeup_one ((event_t)mtxp))
+    /* Any threads that were waiting on this mutex were
+     * interrupted and left - Reset the mutex state. */
+    mtxp->state = KMUTEX_AVAIL;
+
+  simple_unlock (&mtxp->lock);
+}
diff --git a/kern/kmutex.h b/kern/kmutex.h
new file mode 100644
index 0000000..2981515
--- /dev/null
+++ b/kern/kmutex.h
@@ -0,0 +1,52 @@
+/* Copyright (C) 2017 Free Software Foundation, Inc.
+   Contributed by Agustina Arzille <address@hidden>, 2017.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License
+   as published by the Free Software Foundation; either
+   version 2 of the license, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _KERN_KMUTEX_H_
+#define _KERN_KMUTEX_H_   1
+
+#include <kern/lock.h>
+#include <mach/kern_return.h>
+
+struct kmutex
+{
+  unsigned int state;
+  decl_simple_lock_data (, lock)
+};
+
+/* Possible values for the mutex state. */
+#define KMUTEX_AVAIL       0
+#define KMUTEX_LOCKED      1
+#define KMUTEX_CONTENDED   2
+
+/* Initialize mutex in *MTXP. */
+extern void kmutex_init (struct kmutex *mtxp);
+
+/* Acquire lock MTXP. If INTERRUPTIBLE is true, the sleep may be
+ * prematurely terminated, in which case the function returns
+ * KERN_INTERRUPTED. Otherwise, KERN_SUCCESS is returned. */
+extern kern_return_t kmutex_lock (struct kmutex *mtxp,
+  boolean_t interruptible);
+
+/* Try to acquire the lock MTXP without sleeping.
+ * Returns KERN_SUCCESS if successful, KERN_FAILURE otherwise. */
+extern kern_return_t kmutex_trylock (struct kmutex *mtxp);
+
+/* Unlock the mutex MTXP. */
+extern void kmutex_unlock (struct kmutex *mtxp);
+
+#endif
diff --git a/kern/sched_prim.c b/kern/sched_prim.c
index bb76735..173f068 100644
--- a/kern/sched_prim.c
+++ b/kern/sched_prim.c
@@ -376,13 +376,14 @@ void clear_wait(
  *     and thread_wakeup_one.
  *
  */
-void thread_wakeup_prim(
+boolean_t thread_wakeup_prim(
        event_t         event,
        boolean_t       one_thread,
        int             result)
 {
        queue_t                 q;
        int                     index;
+       boolean_t woke = FALSE;
        thread_t                thread, next_th;
        decl_simple_lock_data( , *lock);
        spl_t                   s;
@@ -435,6 +436,7 @@ void thread_wakeup_prim(
                                break;
                        }
                        thread_unlock(thread);
+                       woke = TRUE;
                        if (one_thread)
                                break;
                }
@@ -442,6 +444,7 @@ void thread_wakeup_prim(
        }
        simple_unlock(lock);
        splx(s);
+       return (woke);
 }
 
 /*
diff --git a/kern/sched_prim.h b/kern/sched_prim.h
index dfb2f54..405e545 100644
--- a/kern/sched_prim.h
+++ b/kern/sched_prim.h
@@ -72,7 +72,7 @@ extern void   thread_sleep(
        simple_lock_t   lock,
        boolean_t       interruptible);
 extern void    thread_wakeup(void);            /* for function pointers */
-extern void    thread_wakeup_prim(
+extern boolean_t       thread_wakeup_prim(
        event_t         event,
        boolean_t       one_thread,
        int             result);
diff --git a/linux/src/include/linux/compiler-gcc7.h 
b/linux/src/include/linux/compiler-gcc7.h
new file mode 100644
index 0000000..02c5bea
--- /dev/null
+++ b/linux/src/include/linux/compiler-gcc7.h
@@ -0,0 +1,67 @@
+#ifndef __LINUX_COMPILER_H
+#error "Please don't include <linux/compiler-gcc7.h> directly, include 
<linux/compiler.h> instead."
+#endif
+
+#define __used                         __attribute__((__used__))
+#define __must_check                   __attribute__((warn_unused_result))
+#define __compiler_offsetof(a, b)      __builtin_offsetof(a, b)
+
+/* Mark functions as cold. gcc will assume any path leading to a call
+   to them will be unlikely.  This means a lot of manual unlikely()s
+   are unnecessary now for any paths leading to the usual suspects
+   like BUG(), printk(), panic() etc. [but let's keep them for now for
+   older compilers]
+
+   Early snapshots of gcc 4.3 don't support this and we can't detect this
+   in the preprocessor, but we can live with this because they're unreleased.
+   Maketime probing would be overkill here.
+
+   gcc also has a __attribute__((__hot__)) to move hot functions into
+   a special section, but I don't see any sense in this right now in
+   the kernel context */
+#define __cold                 __attribute__((__cold__))
+
+#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
+
+#ifndef __CHECKER__
+# define __compiletime_warning(message) __attribute__((warning(message)))
+# define __compiletime_error(message) __attribute__((error(message)))
+#endif /* __CHECKER__ */
+
+/*
+ * Mark a position in code as unreachable.  This can be used to
+ * suppress control flow warnings after asm blocks that transfer
+ * control elsewhere.
+ *
+ * Early snapshots of gcc 4.5 don't support this and we can't detect
+ * this in the preprocessor, but we can live with this because they're
+ * unreleased.  Really, we need to have autoconf for the kernel.
+ */
+#define unreachable() __builtin_unreachable()
+
+/* Mark a function definition as prohibited from being cloned. */
+#define __noclone      __attribute__((__noclone__))
+
+/*
+ * Tell the optimizer that something else uses this function or variable.
+ */
+#define __visible __attribute__((externally_visible))
+
+/*
+ * GCC 'asm goto' miscompiles certain code sequences:
+ *
+ *   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670
+ *
+ * Work it around via a compiler barrier quirk suggested by Jakub Jelinek.
+ *
+ * (asm goto is automatically volatile - the naming reflects this.)
+ */
+#define asm_volatile_goto(x...)        do { asm goto(x); asm (""); } while (0)
+
+#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP
+#define __HAVE_BUILTIN_BSWAP32__
+#define __HAVE_BUILTIN_BSWAP64__
+#define __HAVE_BUILTIN_BSWAP16__
+#endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP */
+
+#define KASAN_ABI_VERSION 4
diff --git a/version.m4 b/version.m4
index da30815..87b79ea 100644
--- a/version.m4
+++ b/version.m4
@@ -1,4 +1,4 @@
 m4_define([AC_PACKAGE_NAME],[GNU Mach])
-m4_define([AC_PACKAGE_VERSION],[1.8+git20170102])
+m4_define([AC_PACKAGE_VERSION],[1.8+git20170609])
 m4_define([AC_PACKAGE_BUGREPORT],address@hidden)
 m4_define([AC_PACKAGE_TARNAME],[gnumach])
diff --git a/vm/vm_object.h b/vm/vm_object.h
index f8f9bf8..80d449a 100644
--- a/vm/vm_object.h
+++ b/vm/vm_object.h
@@ -396,4 +396,18 @@ MACRO_END
 extern int     vm_object_external_count;
 extern int     vm_object_external_pages;
 
+/* Add a reference to a locked VM object. */
+static inline int
+vm_object_reference_locked (vm_object_t obj)
+{
+  return (++obj->ref_count);
+}
+
+/* Remove a reference from a locked VM object. */
+static inline int
+vm_object_unreference_locked (vm_object_t obj)
+{
+  return (--obj->ref_count);
+}
+
 #endif /* _VM_VM_OBJECT_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]