From 4b1d43fa617abd85ac1d4e7491f2410d06bf65a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulysse=20G=C3=A9rard?= Date: Wed, 19 Feb 2020 18:19:34 +0100 Subject: [PATCH 1/5] Some updates to the `Hello Mirage World` and `lwt` tutorials --- tmpl/wiki/hello-world.md | 12 ++++++------ tmpl/wiki/tutorial-lwt.md | 17 +++++++++-------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/tmpl/wiki/hello-world.md b/tmpl/wiki/hello-world.md index 52a5357ef..f9d9ea097 100644 --- a/tmpl/wiki/hello-world.md +++ b/tmpl/wiki/hello-world.md @@ -214,7 +214,7 @@ First, let's look at the code: $ cat hello/unikernel.ml open Lwt.Infix -module Hello (Time : Mirage_time_lwt.S) = struct +module Hello (Time : Mirage_time.S) = struct let start _time = @@ -231,10 +231,10 @@ end ``` To veteran OCaml programmers among you, this might look a little odd: We have a -`Main` module parameterised by a module (`Time`, of type `Mirage_time_lwt.S`) that contains a method `start` taking an ignored parameter `_time` (an instance of a `time`). This is the basic structure required to make this a MirageOS unikernel +main `Hello` module parameterised by a module (`Time`, of type `Mirage_time.S`) that contains a method `start` taking an ignored parameter `_time` (an instance of a `time`). This is the basic structure required to make this a MirageOS unikernel rather than a standard OCaml POSIX application. -The module type for our `Time` module, `Mirage_time_lwt.S`, is defined in an +The module type for our `Time` module, `Mirage_time.S`, is defined in an external package [mirage-time](https://github.com/mirage/mirage-time). The name `S` for "the module type of things like this" is a common OCaml convention (comparable to naming the most-used type in a module `t`). There are many packages defining module types for use in Mirage. For ease of discovery, a list of the module types that Mirage knows about is maintained in the [`types/`](https://github.com/mirage/mirage/tree/master/types) directory of the main MirageOS repository. The `Mirage_types` module gives abstract definitions that leave some important primitives unspecified; the `Mirage_types_lwt` module contains more concrete definitions for use in programs. Since you'll find yourself referring back to @@ -509,7 +509,7 @@ explain this subsystem next. The [device-usage/block/](https://github.com/mirage/mirage-skeleton/tree/master/device-usage/block) directory in `mirage-skeleton` contains an example of attaching a raw block device to your unikernel. -The [Mirage_block_lwt](https://mirage.github.io/mirage-block-lwt) +The [Mirage_block](https://mirage.github.io/mirage-block) interface signature contains the operations that are possible on a block device: primarily reading and writing aligned buffers to a 64-bit offset within the device. @@ -759,7 +759,7 @@ let () = ``` We have a custom configuration key defining which TCP port to listen for connections on. -The network device is derived from `default_network`, a function provided by Mirage which will choose a reasonable default based on the target the user chooses to pass to `mirage configure` - just like the reasonable default provided by `generic_kv_ro` in the previous example. +The network device is derived from `default_network`, a function provided by Mirage which will choose a reasonable default based on the target the user chooses to pass to `mirage configure` - just like the reasonable default provided by `generic_kv_ro` in the previous example. `generic_stackv4` attempts to build a sensible network stack on top of the physical interface given by `default_network`. There are quite a few configuration keys exposed when `generic_stackv4` is given related to networking configuration. For a full list, try `mirage help configure` in the `device-usage/network` directory. @@ -816,7 +816,7 @@ Next, let's try using the direct MirageOS network stack. It will be necessary t To configure via DHCP: ```bash -$ cd device-usage/network +$ cd device-usage/network $ mirage configure -t unix --dhcp true --net direct $ make depend $ make diff --git a/tmpl/wiki/tutorial-lwt.md b/tmpl/wiki/tutorial-lwt.md index 3678517dd..9dee0b8cc 100644 --- a/tmpl/wiki/tutorial-lwt.md +++ b/tmpl/wiki/tutorial-lwt.md @@ -2,7 +2,7 @@ ##Basics -The full Lwt manual is available [elsewhere](http://ocsigen.org/lwt/manual/), but the minimal stuff needed to get started is here. +The full Lwt manual is available [elsewhere](https://ocsigen.org/lwt/5.1.2/manual/manual), but the minimal stuff needed to get started is here. The core type in Lwt is a "thread" (also known as a "promise" in some other systems). An `'a Lwt.t` is a thread that should produce a value of type `'a` (for example, an `int Lwt.t` should produce a single `int`). @@ -71,7 +71,7 @@ Two important functions to compose threads are `join` and `choose`. `choose l` behaves as the first thread in `l` to terminate. If several threads are already terminated, one is chosen at random. -The [Lwt_list](http://ocsigen.org/lwt/2.5.0/api/Lwt_list) module provides many other functions for handling lists of threads. +The [Lwt_list](https://ocsigen.org/lwt/5.1.2/api/Lwt_list) module provides many other functions for handling lists of threads. ## Challenge 1: Sleep and join @@ -81,7 +81,8 @@ amount of time, say 1 and 2 seconds and then one prints "Heads", the other To sleep for some number of nanoseconds use `OS.Time.sleep_ns`, and to print to the console use `C.log`. Note that `OS` is a Mirage-specific module; if you are -using Lwt in another context, use `Lwt_unix.sleep` and `Lwt_io.write`. +using Lwt in another context, use `Lwt_unix.sleep` and `Lwt_io.write`. (You will +also need to manually start the main evnt loop with `Lwt_main.run`.) For convenience, you'll likely want to also use the [Duration](https://github.com/hannesm/duration) library, which provides handy @@ -111,7 +112,7 @@ Add a file `unikernel.ml` with the following content and edit it: open OS open Lwt.Infix -module Heads1 (C: Mirage_console_lwt.S) = struct +module Heads1 (C: Mirage_console.S) = struct let start c = (* Add your implementation here... *) C.log c "Finished" @@ -135,7 +136,7 @@ If you prefer to build for another target (like `xen` or `hvt`), change the `-t` open OS open Lwt.Infix -module Heads1 (C: Mirage_console_lwt.S) = struct +module Heads1 (C: Mirage_console.S) = struct let start c = Lwt.join [ @@ -185,7 +186,7 @@ By the way, the `>|=` operator ("map") used here is similar to `>>=` but automat open OS open Lwt.Infix -module Echo_server (C: Mirage_console_lwt.S) (R: Mirage_random.C) = struct +module Echo_server (C: Mirage_console.S) (R: Mirage_random.S) = struct let read_line () = OS.Time.sleep_ns (Duration.of_ms (Randomconv.int ~bound:2500 R.generate)) @@ -496,13 +497,13 @@ Found in [lwt/tutorial/timeout2/unikernel.ml][timeout2_unikernel.ml] in the repo The `cancel` function should be used very sparingly, since it essentially throws an unexpected exception into the middle of some executing code that probably wasn't expecting it. A cancel that occurs when the thread happens to be performing an uncancellable operation will be silently ignored. -A safer alternative is to use [Lwt_switch](http://ocsigen.org/lwt/2.5.0/api/Lwt_switch). +A safer alternative is to use [Lwt_switch](http://ocsigen.org/lwt/5.1.2/api/Lwt_switch). This means that cancellation will only happen at well defined points, although it does require explicit support from the code being cancelled. If you have a function that only responds to cancel, you might want to wrap it in a function that takes a switch and cancels it when the switch is turned off. ## Other Lwt features -Lwt provides many more features. See [the manual](http://ocsigen.org/lwt/manual/) for details. +Lwt provides many more features. See [the manual](http://ocsigen.org/lwt/) for details. However, the vast majority of code will only need the basic features described here. [echo_server_unikernel.ml]: https://github.com/mirage/mirage-skeleton/blob/master/tutorial/lwt/echo_server/unikernel.ml From 3daef0fc3a6905f513c3167b477c8728459ffc91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulysse=20G=C3=A9rard?= Date: Fri, 13 Mar 2020 14:14:40 +0100 Subject: [PATCH 2/5] [CSS] Add bottom padding to `` --- files/css/site.css | 1 + 1 file changed, 1 insertion(+) diff --git a/files/css/site.css b/files/css/site.css index 8f0806437..b2d4cbd2b 100644 --- a/files/css/site.css +++ b/files/css/site.css @@ -29,6 +29,7 @@ article a:hover { body { background-image: url(/graphics/cloud-bg.png); background-repeat: repeat-x; + padding-bottom: 1.5em; } code { From 0c6cc39dbf30674bf9e52bf3089064b1d5c36e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulysse=20G=C3=A9rard?= Date: Mon, 23 Mar 2020 10:57:45 +0100 Subject: [PATCH 3/5] Add some build artefacts to the gitinore file --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 490a8fc09..dedbe0499 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,11 @@ /src/log /src/_build +/src/dune +/src/dune.build +/src/dune.config +/src/dune-project +/src/.merlin /src/mir-www /src/mir-main /src/main.native From fd6287318ac5cf1e2f4984aa7ea36a05324f9ad7 Mon Sep 17 00:00:00 2001 From: Ulysse <5031221+voodoos@users.noreply.github.com> Date: Mon, 23 Mar 2020 11:12:32 +0100 Subject: [PATCH 4/5] Typo correct (@talex5) Co-Authored-By: Thomas Leonard --- tmpl/wiki/tutorial-lwt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tmpl/wiki/tutorial-lwt.md b/tmpl/wiki/tutorial-lwt.md index 9dee0b8cc..6babbdc3a 100644 --- a/tmpl/wiki/tutorial-lwt.md +++ b/tmpl/wiki/tutorial-lwt.md @@ -82,7 +82,7 @@ amount of time, say 1 and 2 seconds and then one prints "Heads", the other To sleep for some number of nanoseconds use `OS.Time.sleep_ns`, and to print to the console use `C.log`. Note that `OS` is a Mirage-specific module; if you are using Lwt in another context, use `Lwt_unix.sleep` and `Lwt_io.write`. (You will -also need to manually start the main evnt loop with `Lwt_main.run`.) +also need to manually start the main event loop with `Lwt_main.run`.) For convenience, you'll likely want to also use the [Duration](https://github.com/hannesm/duration) library, which provides handy From 0d5eec99105733f8daf9d7adfbb5c8c6e7307252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulysse=20G=C3=A9rard?= Date: Mon, 23 Mar 2020 11:53:54 +0100 Subject: [PATCH 5/5] Use https links --- tmpl/wiki/tutorial-lwt.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tmpl/wiki/tutorial-lwt.md b/tmpl/wiki/tutorial-lwt.md index 6babbdc3a..b760c5678 100644 --- a/tmpl/wiki/tutorial-lwt.md +++ b/tmpl/wiki/tutorial-lwt.md @@ -1,8 +1,8 @@ -[Lwt](http://www.ocsigen.org/lwt) is a lightweight cooperative threading library for OCaml. A good way to understand Lwt and its use in MirageOS is to write some simple code. This document introduces the basic concepts and suggests programs to write. Code for all examples is in the `mirage-skeleton/tutorial/lwt/` [repository](https://github.com/mirage/mirage-skeleton/tree/master/tutorial/lwt). +[Lwt](https://www.ocsigen.org/lwt) is a lightweight cooperative threading library for OCaml. A good way to understand Lwt and its use in MirageOS is to write some simple code. This document introduces the basic concepts and suggests programs to write. Code for all examples is in the `mirage-skeleton/tutorial/lwt/` [repository](https://github.com/mirage/mirage-skeleton/tree/master/tutorial/lwt). ##Basics -The full Lwt manual is available [elsewhere](https://ocsigen.org/lwt/5.1.2/manual/manual), but the minimal stuff needed to get started is here. +The full Lwt manual is available [elsewhere](https://ocsigen.org/lwt), but the minimal stuff needed to get started is here. The core type in Lwt is a "thread" (also known as a "promise" in some other systems). An `'a Lwt.t` is a thread that should produce a value of type `'a` (for example, an `int Lwt.t` should produce a single `int`). @@ -229,7 +229,7 @@ event that will wake up the associated thread when possible. ##Mutexes and cooperation -With Lwt, it is often possible to avoid mutexes altogether! The web server from the [Ocsigen](http://ocsigen.org) project uses only two, for example. In usual concurrent systems, mutexes are used to prevent two (or more) threads executing concurrently on a given piece of data. This can happen when a thread is preemptively interrupted and another one starts running. In Lwt, a thread executes serially until it explicitly yields (most commonly via `>>=`); for this reason, Lwt threads are said to be [cooperative](http://en.wikipedia.org/wiki/Cooperative_multitasking#Cooperative_multitasking.2Ftime-sharing). +With Lwt, it is often possible to avoid mutexes altogether! The web server from the [Ocsigen](https://ocsigen.org) project uses only two, for example. In usual concurrent systems, mutexes are used to prevent two (or more) threads executing concurrently on a given piece of data. This can happen when a thread is preemptively interrupted and another one starts running. In Lwt, a thread executes serially until it explicitly yields (most commonly via `>>=`); for this reason, Lwt threads are said to be [cooperative](https://en.wikipedia.org/wiki/Cooperative_multitasking#Cooperative_multitasking.2Ftime-sharing). For example, consider this code to generate unique IDs: @@ -497,13 +497,13 @@ Found in [lwt/tutorial/timeout2/unikernel.ml][timeout2_unikernel.ml] in the repo The `cancel` function should be used very sparingly, since it essentially throws an unexpected exception into the middle of some executing code that probably wasn't expecting it. A cancel that occurs when the thread happens to be performing an uncancellable operation will be silently ignored. -A safer alternative is to use [Lwt_switch](http://ocsigen.org/lwt/5.1.2/api/Lwt_switch). +A safer alternative is to use [Lwt_switch](https://ocsigen.org/lwt/5.1.2/api/Lwt_switch). This means that cancellation will only happen at well defined points, although it does require explicit support from the code being cancelled. If you have a function that only responds to cancel, you might want to wrap it in a function that takes a switch and cancels it when the switch is turned off. ## Other Lwt features -Lwt provides many more features. See [the manual](http://ocsigen.org/lwt/) for details. +Lwt provides many more features. See [the manual](https://ocsigen.org/lwt/) for details. However, the vast majority of code will only need the basic features described here. [echo_server_unikernel.ml]: https://github.com/mirage/mirage-skeleton/blob/master/tutorial/lwt/echo_server/unikernel.ml