From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 7769C7EC6E for ; Fri, 3 Jan 2014 16:42:50 +0100 (CET) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of jdimino@janestreet.com) identity=pra; client-ip=38.105.200.229; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="jdimino@janestreet.com"; x-sender="jdimino@janestreet.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of jdimino@janestreet.com designates 38.105.200.229 as permitted sender) identity=mailfrom; client-ip=38.105.200.229; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="jdimino@janestreet.com"; x-sender="jdimino@janestreet.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@tot-dmz-mxout1.janestreet.com) identity=helo; client-ip=38.105.200.229; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="jdimino@janestreet.com"; x-sender="postmaster@tot-dmz-mxout1.janestreet.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AukBAOHZxlImacjlnGdsb2JhbABYg0NVsDOIV4EFHg4BAQEBAQYWCTyCUxkBAQwmBiVdDwMBBQEiMASHYwMCCJ0gixOEUgEFlgURBo5MPoI6D4F5jF+LPIEwhhCFHINLGCmEWYFq X-IPAS-Result: AukBAOHZxlImacjlnGdsb2JhbABYg0NVsDOIV4EFHg4BAQEBAQYWCTyCUxkBAQwmBiVdDwMBBQEiMASHYwMCCJ0gixOEUgEFlgURBo5MPoI6D4F5jF+LPIEwhhCFHINLGCmEWYFq X-IronPort-AV: E=Sophos;i="4.95,598,1384297200"; d="scan'208";a="51558295" Received: from mx5.janestreet.com (HELO tot-dmz-mxout1.janestreet.com) ([38.105.200.229]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 03 Jan 2014 16:42:49 +0100 Received: from tot-oib-smtp1.delacy.com ([172.27.22.15] helo=tot-smtp) by tot-dmz-mxout1.janestreet.com with esmtp (Exim 4.76) (envelope-from ) id 1Vz6tb-0002Zu-1k for caml-list@inria.fr; Fri, 03 Jan 2014 10:42:47 -0500 Received: from tot-dmz-mxgoog1.delacy.com ([172.27.224.14] helo=mxgoog2.janestreet.com) by tot-smtp with esmtps (TLSv1:AES256-SHA:256) (Exim 4.72) (envelope-from ) id 1Vz6tb-0007nJ-0n for caml-list@inria.fr; Fri, 03 Jan 2014 10:42:47 -0500 Received: from mail-ig0-f175.google.com ([209.85.213.175]) by mxgoog2.janestreet.com with esmtp (Exim 4.76) (envelope-from ) id 1Vz6ta-0004Ni-SD for caml-list@inria.fr; Fri, 03 Jan 2014 10:42:46 -0500 Received: by mail-ig0-f175.google.com with SMTP id j1so1339356iga.2 for ; Fri, 03 Jan 2014 07:42:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=janestreet.com; s=google; h=mime-version:date:message-id:subject:from:to:content-type; bh=w5dUXuhUgyVwyq6zfOUlWXhk1rkVpXO0QJQcL7Imjto=; b=ePTULcjlhfwKPm9W6iCy4/BBYRGcpA7qwRGjur1KLkhjVF+IQlA0m1u/0ZYKEVNNmt XMd95jdoRxnjBzAcZOfwYZBudqzpgpkZ3VkbHeeLHEZ8dapLluIyqi+3zvB2jwbV7iHz NXDnmaQAc7Tj29CdQ80xXpTWLMjZJPbOBACIc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:date:message-id:subject:from:to :content-type; bh=w5dUXuhUgyVwyq6zfOUlWXhk1rkVpXO0QJQcL7Imjto=; b=NSHHJ8xzY96zIAIhzRlM1zAprcf6Fo8dFWuyvP+D+OWUSAVaenRmtHA3yf1fzc6bgF sayJC6tU3yFHjGlLpjeovgLdh0qZOT5US2arVvt87H+sYHZOvcxROni/lKh/QvUY9p2Z PBWT2PAyEZZCcAaIo9rzpORNPJWJbRhPGMbjKVowwDSUXJOzqB+D6MNgvHDbXVxMsahI IFCFElxxfSPfDtw3TA4dlcUf43PZ5ihTOw6Rfd1916iiuj870MSglhHAJxzVjwzSBS+T Zr2tpL+HmcGN+SiQWJHowh/dxzMBdWU22+VH8nofOe3U1qNKZb+2r7RrrDgGWMYn1ucX 7cGA== X-Gm-Message-State: ALoCoQnGjOeB4PaCxDnn+bQdcpjG81g9sbvqHPjvn1Wk3jJI6CnP4xbiperHeqPyewmsOU7ag8zTp7OGoCz0tCvKDAKBYUFykQxEWl1iDA/CSI2gW/8WM4QyMhURfy2k1x+RAup8vPNeFDa6sVPwWrKM2Rl75EOnYQ== X-Received: by 10.50.36.67 with SMTP id o3mr3448872igj.47.1388763766622; Fri, 03 Jan 2014 07:42:46 -0800 (PST) MIME-Version: 1.0 X-Received: by 10.50.36.67 with SMTP id o3mr3448850igj.47.1388763766346; Fri, 03 Jan 2014 07:42:46 -0800 (PST) Received: by 10.50.170.40 with HTTP; Fri, 3 Jan 2014 07:42:46 -0800 (PST) Date: Fri, 3 Jan 2014 15:42:46 +0000 Message-ID: From: Jeremie Dimino To: "caml-list@inria.fr" Content-Type: multipart/alternative; boundary=089e01160174f8692604ef12c27f Subject: [Caml-list] [ANN] Core Suite 109.58.00 --089e01160174f8692604ef12c27f Content-Type: text/plain; charset=ISO-8859-1 I am pleased to announce the 109.58.00 release of the Core suite. Starting from 109.55.00, core libraries contain inline benchmark. It is now possible to run them: echo 'let () = Inline_benchmarks.Runner.main ~libname:"core_kernel"' > bench.ml ocamlfind ocamlopt -thread -linkpkg -linkall -package str,core_kernel,core_bench.inline_benchmarks bench.ml -o bench ./bench -benchmarks-runner Replace core_kernel by the library you want to run benchmarks for. Currently only core and core_kernel contain inline benchmark. In this release the following packages were upgraded: - async - async_extra - async_inotify - async_kernel - async_parallel - async_unix - core - core_bench - core_extended - core_kernel - jenga - sexplib Files and documentation for this release are available on our website and all packages are in opam: https://ocaml.janestreet.com/ocaml-core/109.58.00/individual/ https://ocaml.janestreet.com/ocaml-core/109.58.00/doc/ Here is list of changes for this version: # 109.58.00 ## async_extra - Changed `Cpu_usage` to use `Core.Percent` instead of `float` where appropriate. - Made `Bus.unsubscribe` check that the subscriber is subscribed to the given bus. - Made `Log.t` support `with sexp_of`. - Fixed `Tcp.on_port 0` to return the port actually being listened on, like `Tcp.on_port_chosen_by_os`. Previously, a serverlistening on `Tcp.on_port 0` would have its `Tcp.Server.listening_on` as `0`, which of course is not the port the server is listening on. ## async_kernel - Renamed the `Async_core` library as `Async_kernel`, to parallel `Core_kernel`. Someday `Async_core` will depend only on `Core_kernel`, but not yet. - Added a thread-safe queue of "external actions" that is checked after each job. - Fixed a race condition in `Clock.Event.abort`. Here is the race condition: * `Clock.Event.at` adds an alarm, its value is a job (let's call it job1) with this run function: ```ocaml let fire () ` t :` Happened; Ivar.fill ready `Happened; ``` * later a job (let's call it job2) aborting the clock event is queued in the async scheduler * in the same cycle, the `Timing_wheel.advance_clock` fires the alarm and job1 scheduled * at this point: + job1 and job2 are still pending + the alarm was removed so it is invalid + the clock event is still in the state `Waiting` * job2 is executed before job1: the clock event is still in the `Waiting` state, so the abort tries to remove the alarm from the timing wheel: CRASH The bugfix is for `Clock.Event.abort` to check if the alarm has already been removed from the timing wheel and if so, don't remove it again. - Changed `Monitor.try_with` when run with `~rest:\`Ignore`, the default, so that the created monitor is detached from the monitor tree. The detached monitor has no parent, rather than being a child of the current monitor. This will eliminate recently observed space leaks in `Sequencer_table` and `Throttle`, like: ```ocaml let leak () = let seq = Throttle.Sequencer.create () in let rec loop n = Throttle.enqueue seq (fun () -> loop (n + 1); Deferred.unit ) |> don't_wait_for in loop 0 ``` - Changed Async's scheduler to pool jobs rather than heap allocate them, decreasing the cost of a job by 30-40%. Changed the main scheduler queue of jobs to be an `Obj_array.t` that is essentially a specialized `Flat_queue` (the specialization was necessary for speed). Also, cleaned up the scheduler run-job loop. With these changes, the cost of a simple job decreases significantly (30-40%), across a range of live data sizes. Here are the nanoseconds-per-job numbers for a microbenchmark with the old and new approaches. ``` | num live jobs | old ns/job | new ns/job | |---------------+------------+------------| | 1 | 74 | 53 | | 2 | 75 | 47 | | 4 | 76 | 41 | | 8 | 63 | 39 | | 16 | 62 | 38 | | 32 | 61 | 37 | | 64 | 61 | 37 | | 128 | 60 | 37 | | 256 | 60 | 38 | | 512 | 60 | 38 | | 1024 | 60 | 39 | | 2048 | 61 | 40 | | 4096 | 67 | 41 | | 8192 | 65 | 45 | | 16384 | 75 | 56 | | 32768 | 115 | 67 | | 65536 | 171 | 108 | | 131072 | 255 | 158 | | 262144 | 191 | 130 | | 524288 | 216 | 139 | | 1048576 | 238 | 152 | ``` See async/bench/nanos\_per\_job.ml for the benchmark. - Removed `debug_space_leaks` from Async's internals. It hadn't been used in years. ## async_unix - Improved fairness of the async scheduler with respect to external threads, including I/O done in external threads. The change is to add a thread-safe queue of "external actions" that is checked after each job. Previously, when a job given to `In_thread.run` finished, `In_thread.run` would take the async lock, fill the result ivar and run a cycle. The problem is that in some situations, due to poor OS scheduling, the helper thread never had a chance to grab the lock. Now, `In_thread.run` tries to take the lock: - if it can it does as before - if it can't it enqueues a thunk in the external actions queue and wakes up the scheduler With this change, the helper thread doing an `In_thread.run` will always quickly finish once the work is done, and the async scheduler will fill in the result ivar as soon as the current job finishes. - Fixed `Epoll_file_descr_watcher.invariant` to deal with the timerfd, which has the edge-triggered flag set. - Added `Writer.write_gen`, a generic functor for blitting directly to a writer's buffer. ## core - Added `Debug.should_print_backtrace : bool ref`, to control whether `Debug.am*` functions print backtraces. - Added to `Float` inline benchmarks. - Moved all of the `Gc` module into `Core_kernel`. Part of the `Gc` module used to be in `Core` because it used threads. But it doesn't use threads anymore, so can be all in `Core_kernel`. - Improved `Iobuf` support for copying to/from strings and bigstrings. The new modules are `Iobuf.{Consume,Peek}.To_{bigstring,string}`. They match a `Blit`-like interface. We don't yet implement the `Blit` interface in all applicable contexts, but do use `Blit.Make` and expose some of the operations we want in the forms we expect them to take under a `Blit` interface. - Added `Linux_ext.Timerfd.to_file_descr`. - Added to `Time.next_multiple` an optional argument to control whether the inequality with `after` is strict. - Added `Time.Zone.local`, a lazily cached `Time.Zone.machine_zone ()`. This is the first stage in a plan to make explicit timezones more pervasive. First, they are made more convenient, by replacing the relatively wordy `Time.Zone.machine_zone ()` with `Time.Zone.local`. This involves making the underlying timezone type lazy. The next stage will be to remove `machine_zone` and use `Time.Zone.local` everywhere instead. Then (it is hoped) instead of `of_local_whatever`, we just say e.g. `of_date_ofday Time.Zone.local` and currently-implicitly-local functions will be able to switch over to explicit timezones without becoming too verbose. - Added `Timing_wheel.Alarm.null`. - Made `Unix.File_descr.t` have `with sexp`. Closes janestreet/async_unix#3 - Fixed OpenBSD compilation failures in C stubs. - Fixed `Lock_file.is_locked` to require read permission, not write permission, on the lock file. - Added to `Unix.mcast_join` an optional `?source:Inet_addr.t` argument. From pull-request on bitbucket: https://bitbucket.org/janestreet/core/pull-request/1/receive-source-specific-multicast/diff ## core_bench - Added support for saving inline benchmark measurements to tabular files for easy loading into Octave. ## core_extended - Cleaned up the `Stats_reporting` module ## core_kernel - Moved all of the `Gc` module into `Core_kernel`. Part of the `Gc` module used to be in `Core` because it used threads. But it doesn't use threads anymore, so can be all in `Core_kernel`. - Made `Stable.Map` and `Set` have `with compare`. - Added `String.rev`. Closes janestreet/core#16 We will not add `String.rev_inplace`, as we do not want to encourage mutation of strings. - Made `Univ_map.Key` equivalent to `Type_equal.Id`. - Added `Univ.view`, which exposes `Univ.t` as an existential, `type t = T : 'a Id.t * 'a -> t`. Exposing the existential makes it possible to, for example, use `Univ_map.set` to construct a `Univ_map.t`from a list of `Univ.t`s. This representation is currently the same as the underlying representation, but to make changes to the underlying representation easier, it has been put in a module `Univ.View`. -- Jeremie Dimino, for the Core team --089e01160174f8692604ef12c27f Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
I am pleased to announce the 109.58.00 release of the= Core suite.

Starting from 109.55.00, core librari= es contain inline benchmark. It
is now possible to run them:

=A0 =A0 echo 'let () =3D Inline_benchmarks.Runner.m= ain ~libname:"core_kernel"' > = bench.ml
=A0 =A0 ocamlfind ocamlopt -thread -linkpkg -linkall= -package str,core_kernel,core_bench.inline_benchmarks bench.ml -o bench
=A0 =A0 ./bench -benchmarks-runner

Replace co= re_kernel by the library you want to run benchmarks
for. Currentl= y only core and core_kernel contain inline benchmark.

<= div>
In this release the following packages were upgraded:
<= div>
- async
- async_extra
- async_inotif= y
- async_kernel
- async_parallel
- async_uni= x
- core
- core_bench
- core_extended
- co= re_kernel
- jenga
- sexplib

Fi= les and documentation for this release are available on our
websi= te and all packages are in opam:


Here is list of changes for this version:
# 109.58.00

## async_extra
<= br>
- Changed `Cpu_usage` to use `Core.Percent` instead of `float= ` where
=A0 appropriate.
- Made `Bus.unsubscribe` check that the sub= scriber is subscribed to
=A0 the given bus.
- Made `Log= .t` support `with sexp_of`.
- Fixed `Tcp.on_port 0` to return the= port actually being listened on,
=A0 like `Tcp.on_port_chosen_by_os`.

=A0 Prev= iously, a serverlistening on `Tcp.on_port 0` would have its
=A0 `= Tcp.Server.listening_on` as `0`, which of course is not the port
= =A0 the server is listening on.

## async_kernel

- Renamed the = `Async_core` library as `Async_kernel`, to parallel
=A0 `Core_ker= nel`.

=A0 Someday `Async_core` will depend only on= `Core_kernel`, but not yet.
- Added a thread-safe queue of "external actions" that is ch= ecked
=A0 after each job.
- Fixed a race condition in `= Clock.Event.abort`.

=A0 Here is the race condition= :

=A0 * `Clock.Event.at= ` adds an alarm, its value is a job (let's call it
=A0 = =A0 job1) with this run function:

=A0 =A0 ```ocaml=
=A0 =A0 let fire () `
=A0 =A0 =A0 t :` Happened;
=A0 = =A0 =A0 Ivar.fill ready `Happened;
=A0 =A0 ```
=A0 * la= ter a job (let's call it job2) aborting the clock event is queued
=
=A0 =A0 in the async scheduler
=A0 * in the same cycle, the `Timing_wheel.advance_clock` fires the
=A0 =A0 alarm and job1 scheduled
=A0 * at this point:
=A0 =A0 + job1 and job2 are still pending
=A0 =A0 + the al= arm was removed so it is invalid
=A0 =A0 + the clock event is still in the state `Waiting`
= =A0 * job2 is executed before job1: the clock event is still in the
=A0 =A0 `Waiting` state, so the abort tries to remove the alarm from the=
=A0 =A0 timing wheel: CRASH

=A0 The bugfix is for = `Clock.Event.abort` to check if the alarm has
=A0 already been re= moved from the timing wheel and if so, don't remove
=A0 it ag= ain.
- Changed `Monitor.try_with` when run with `~rest:\`Ignore`, the
=
=A0 default, so that the created monitor is detached from the monitor<= /div>
=A0 tree.

=A0 The detached monitor has n= o parent, rather than being a child of the
=A0 current monitor. =A0This will eliminate recently observed space le= aks
=A0 in `Sequencer_table` and `Throttle`, like:

=
=A0 ```ocaml
=A0 let leak () =3D
=A0 =A0 let= seq =3D Throttle.Sequencer.create () in
=A0 =A0 let rec loop n =3D
=A0 =A0 =A0 Throttle.enqueue seq = (fun () ->
=A0 =A0 =A0 =A0 loop (n + 1);
=A0 =A0 =A0= =A0 Deferred.unit
=A0 =A0 =A0 )
=A0 =A0 =A0 |> don&= #39;t_wait_for
=A0 =A0 in
=A0 =A0 loop 0
=A0 ```
- Changed Async's sched= uler to pool jobs rather than heap allocate
=A0 them, decreasing = the cost of a job by 30-40%.

=A0 Changed the main = scheduler queue of jobs to be an `Obj_array.t` that
=A0 is essentially a specialized `Flat_queue` (the specialization was<= /div>
=A0 necessary for speed).

=A0 Also, clea= ned up the scheduler run-job loop.

=A0 With these = changes, the cost of a simple job decreases significantly
=A0 (30-40%), across a range of live data sizes. =A0Here are the
=
=A0 nanoseconds-per-job numbers for a microbenchmark with the old and<= /div>
=A0 new approaches.

=A0 ```
= =A0 | num live jobs | old ns/job | new ns/job |
=A0 |---------------+------------+------------|
=A0 | =A0 = =A0 =A0 =A0 =A0 =A0 1 | =A0 =A0 =A0 =A0 74 | =A0 =A0 =A0 =A0 53 |
=A0 | =A0 =A0 =A0 =A0 =A0 =A0 2 | =A0 =A0 =A0 =A0 75 | =A0 =A0 =A0 =A0 47 = |
=A0 | =A0 =A0 =A0 =A0 =A0 =A0 4 | =A0 =A0 =A0 =A0 76 | =A0 =A0 = =A0 =A0 41 |
=A0 | =A0 =A0 =A0 =A0 =A0 =A0 8 | =A0 =A0 =A0 =A0 63 | =A0 =A0 =A0 =A0= 39 |
=A0 | =A0 =A0 =A0 =A0 =A0 =A016 | =A0 =A0 =A0 =A0 62 | =A0 = =A0 =A0 =A0 38 |
=A0 | =A0 =A0 =A0 =A0 =A0 =A032 | =A0 =A0 =A0 = =A0 61 | =A0 =A0 =A0 =A0 37 |
=A0 | =A0 =A0 =A0 =A0 =A0 =A064 | = =A0 =A0 =A0 =A0 61 | =A0 =A0 =A0 =A0 37 |
=A0 | =A0 =A0 =A0 =A0 =A0 128 | =A0 =A0 =A0 =A0 60 | =A0 =A0 =A0 =A0 3= 7 |
=A0 | =A0 =A0 =A0 =A0 =A0 256 | =A0 =A0 =A0 =A0 60 | =A0 =A0 = =A0 =A0 38 |
=A0 | =A0 =A0 =A0 =A0 =A0 512 | =A0 =A0 =A0 =A0 60 |= =A0 =A0 =A0 =A0 38 |
=A0 | =A0 =A0 =A0 =A0 =A01024 | =A0 =A0 =A0= =A0 60 | =A0 =A0 =A0 =A0 39 |
=A0 | =A0 =A0 =A0 =A0 =A02048 | =A0 =A0 =A0 =A0 61 | =A0 =A0 =A0 =A0 4= 0 |
=A0 | =A0 =A0 =A0 =A0 =A04096 | =A0 =A0 =A0 =A0 67 | =A0 =A0 = =A0 =A0 41 |
=A0 | =A0 =A0 =A0 =A0 =A08192 | =A0 =A0 =A0 =A0 65 |= =A0 =A0 =A0 =A0 45 |
=A0 | =A0 =A0 =A0 =A0 16384 | =A0 =A0 =A0 = =A0 75 | =A0 =A0 =A0 =A0 56 |
=A0 | =A0 =A0 =A0 =A0 32768 | =A0 =A0 =A0 =A0115 | =A0 =A0 =A0 =A0 67 = |
=A0 | =A0 =A0 =A0 =A0 65536 | =A0 =A0 =A0 =A0171 | =A0 =A0 =A0 = =A0108 |
=A0 | =A0 =A0 =A0 =A0131072 | =A0 =A0 =A0 =A0255 | =A0 = =A0 =A0 =A0158 |
=A0 | =A0 =A0 =A0 =A0262144 | =A0 =A0 =A0 =A0191= | =A0 =A0 =A0 =A0130 |
=A0 | =A0 =A0 =A0 =A0524288 | =A0 =A0 =A0 =A0216 | =A0 =A0 =A0 =A0139 = |
=A0 | =A0 =A0 =A0 1048576 | =A0 =A0 =A0 =A0238 | =A0 =A0 =A0 = =A0152 |
=A0 ```

=A0 See async/bench/nan= os\_per\_job.ml for the benchmark.
- Removed `debug_space_leaks` from Async's internals. =A0It hadn&#= 39;t been
=A0 used in years.

## async_un= ix

- Improved fairness of the async scheduler with= respect to external
=A0 threads, including I/O done in external threads.

=A0 The change is to add a thread-safe queue of "external acti= ons" that
=A0 is checked after each job.

=A0 Previously, when a job given to `In_thread.run` finished,
=A0= `In_thread.run` would take the async lock, fill the result ivar and
<= div>=A0 run a cycle. =A0The problem is that in some situations, due to poor= OS
=A0 scheduling, the helper thread never had a chance to grab the lock.=
=A0 Now, `In_thread.run` tries to take the lock:

<= /div>
=A0 - if it can it does as before
=A0 - if it can't= it enqueues a thunk in the external actions queue and
=A0 =A0 wakes up the scheduler

=A0 With this = change, the helper thread doing an `In_thread.run` will
=A0 alway= s quickly finish once the work is done, and the async scheduler
= =A0 will fill in the result ivar as soon as the current job finishes.
- Fixed `Epoll_file_descr_watcher.invariant` to deal with the timerfd,=
=A0 which has the edge-triggered flag set.
- Added `Wr= iter.write_gen`, a generic functor for blitting directly to
=A0 a= writer's buffer.

## core

- Added `Debug.should_= print_backtrace : bool ref`, to control whether
=A0 `Debug.am*` f= unctions print backtraces.
- Added to `Float` inline benchmarks.<= /div>
- Moved all of the `Gc` module into `Core_kernel`.

=A0 Part of the `Gc` module used to be in `Core` because it used
=A0 threads. =A0But it doesn't use threads anymore, so can be all= in
=A0 `Core_kernel`.
- Improved `Iobuf` support for copying to= /from strings and bigstrings.

=A0 The new modules = are `Iobuf.{Consume,Peek}.To_{bigstring,string}`.
=A0 They match = a `Blit`-like interface. =A0We don't yet implement the
=A0 `Blit` interface in all applicable contexts, but do use `Blit.Make= `
=A0 and expose some of the operations we want in the forms we e= xpect
=A0 them to take under a `Blit` interface.
- Adde= d `Linux_ext.Timerfd.to_file_descr`.
- Added to `Time.next_multiple` an optional argument to control
<= div>=A0 whether the inequality with `after` is strict.
- Added `T= ime.Zone.local`, a lazily cached `Time.Zone.machine_zone ()`.

=A0 This is the first stage in a plan to make explicit timezones= more
=A0 pervasive. =A0First, they are made more convenient, by = replacing the
=A0 relatively wordy `Time.Zone.machine_zone ()` wi= th `Time.Zone.local`.
=A0 This involves making the underlying timezone type lazy.
=
=A0 The next stage will be to remove `machine_zone` and use<= /div>
=A0 `Time.Zone.local` everywhere instead. =A0Then (it is hoped) i= nstead of
=A0 `of_local_whatever`, we just say e.g. `of_date_ofday
=A0= Time.Zone.local` and currently-implicitly-local functions will be
=A0 able to switch over to explicit timezones without becoming too
<= div> =A0 verbose.
- Added `Timing_wheel.Alarm.null`.
- Made = `Unix.File_descr.t` have `with sexp`.

=A0 Closes j= anestreet/async_unix#3
- Fixed OpenBSD compilation failures in C = stubs.
- Fixed `Lock_file.is_locked` to require read permission, not write
=A0 permission, on the lock file.
- Added to `Unix.mcast_= join` an optional `?source:Inet_addr.t` argument.

=A0 From pull-request on bitbucket:

## core_bench

- Added support = for saving inline benchmark measurements to tabular
=A0 files for= easy loading into Octave.

## core_extended

- Cleaned up the `Stats_reporting` module
## core_kernel

- Moved all of the `Gc`= module into `Core_kernel`.

=A0 Part of the `Gc` m= odule used to be in `Core` because it used
=A0 threads. =A0But it doesn't use threads anymore, so can be all = in
=A0 `Core_kernel`.
- Made `Stable.Map` and `Set` hav= e `with compare`.
- Added `String.rev`.

= =A0 Closes janestreet/core#16

=A0 We will not add `String.rev_inplace`, as we do not = want to encourage
=A0 mutation of strings.
- Made `Univ= _map.Key` equivalent to `Type_equal.Id`.
- Added `Univ.view`, whi= ch exposes `Univ.t` as an existential, `type t
=A0 =3D T : 'a Id.t * 'a -> t`.

= =A0 Exposing the existential makes it possible to, for example, use
=A0 `Univ_map.set` to construct a `Univ_map.t`from a list of `Univ.t`s.<= /div>

=A0 This representation is currently the same as the underly= ing
=A0 representation, but to make changes to the underlying rep= resentation
=A0 easier, it has been put in a module `Univ.View`.<= /div>

--=A0
Jeremie Dimino, for the Core team
=

--089e01160174f8692604ef12c27f--