diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 93c59e1..0000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: ci -on: - push: - branches: - - "main" -jobs: - docker: - runs-on: ubuntu-latest - steps: - - - name: Checkout - uses: actions/checkout@v3 - with: - submodules: true - - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Login to Docker Hub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push - uses: docker/build-push-action@v3 - with: - context: . - platforms: linux/amd64,linux/arm64 - push: true - tags: patricoferris/meio:latest \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 833cd28..08164fb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,13 +16,10 @@ jobs: with: submodules: true - - name: Use OCaml 5.1.0 - uses: ocaml/setup-ocaml@v2 + - name: Set-up OCaml + uses: ocaml/setup-ocaml@v3 with: - ocaml-compiler: ocaml-base-compiler.5.1.0 - opam-repositories: | - default: https://github.com/ocaml/opam-repository.git - dune-cache: true + ocaml-compiler: 5 - name: Meio Deps 🐈‍⬛ run: | # notty is pinned to hardcode the tty size (160 * 40) @@ -32,36 +29,36 @@ jobs: - name: Build run: opam exec -- dune build @all - - name: Update asciicast dependencies - run: | - go install github.com/TheLortex/asciiscript@latest - sudo apt install asciinema fonts-firacode - - - name: Run asciicast and convert to GIF - run: | - export PATH=${PATH}:`go env GOPATH`/bin - export TERM=xterm-256color - sudo sed -i 's/return os\.get_terminal_size()/return (160, 40)/' /usr/lib/python3/dist-packages/asciinema/term.py - asciiscript .screencast/example.sh .screencast/example.cast --overwrite - wget https://github.com/asciinema/agg/releases/download/v1.4.1/agg-x86_64-unknown-linux-gnu -O agg - echo "3c933591d396d22355a37ff40b4259c8b1e2de8f896cf8c7dec1fab72e5f527e agg" | sha256sum --check - chmod +x agg - ./agg .screencast/example.cast .screencast/example.gif --font-family "Fira Code" --font-size=18 - - - uses: actions/upload-artifact@v3 - with: - name: asciicast - path: | - .screencast/example.cast - .screencast/example.gif - - - name: Create Pull Request - uses: peter-evans/create-pull-request@v5 - if: ${{ github.event_name == 'push' }} - with: - add-paths: .screencast/example.gif - commit-message: Update screencast - title: Update screencast - body: | - _Generated by [create-pull-request](https://github.com/peter-evans/create-pull-request) Github action_ - labels: ci + # - name: Update asciicast dependencies + # run: | + # go install github.com/TheLortex/asciiscript@latest + # sudo apt install asciinema fonts-firacode + # + # - name: Run asciicast and convert to GIF + # run: | + # export PATH=${PATH}:`go env GOPATH`/bin + # export TERM=xterm-256color + # sudo sed -i 's/return os\.get_terminal_size()/return (160, 40)/' /usr/lib/python3/dist-packages/asciinema/term.py + # asciiscript .screencast/example.sh .screencast/example.cast --overwrite + # wget https://github.com/asciinema/agg/releases/download/v1.4.1/agg-x86_64-unknown-linux-gnu -O agg + # echo "3c933591d396d22355a37ff40b4259c8b1e2de8f896cf8c7dec1fab72e5f527e agg" | sha256sum --check + # chmod +x agg + # ./agg .screencast/example.cast .screencast/example.gif --font-family "Fira Code" --font-size=18 + # + # - uses: actions/upload-artifact@v3 + # with: + # name: asciicast + # path: | + # .screencast/example.cast + # .screencast/example.gif + # + # - name: Create Pull Request + # uses: peter-evans/create-pull-request@v5 + # if: ${{ github.event_name == 'push' }} + # with: + # add-paths: .screencast/example.gif + # commit-message: Update screencast + # title: Update screencast + # body: | + # _Generated by [create-pull-request](https://github.com/peter-evans/create-pull-request) Github action_ + # labels: ci diff --git a/.ocamlformat b/.ocamlformat index e938c30..646d3cb 100644 --- a/.ocamlformat +++ b/.ocamlformat @@ -1 +1 @@ -version=0.25.1 \ No newline at end of file +version=0.26.0 \ No newline at end of file diff --git a/dune-project b/dune-project index 361600e..548126f 100644 --- a/dune-project +++ b/dune-project @@ -1,2 +1,2 @@ (lang dune 2.9) -(name ec) +(name meio) diff --git a/example/burn.ml b/example/burn.ml index 84a63ce..9b9decd 100644 --- a/example/burn.ml +++ b/example/burn.ml @@ -1,25 +1,24 @@ open Eio let woops_sleepy ~clock = - Private.Ctf.set_name "sleeper"; - Switch.run ~name:"sleeper" @@ fun sw -> + Switch.run ~name:"unix sleeper ctx" @@ fun sw -> Fiber.fork ~sw (fun () -> - Private.Ctf.set_name "unix sleeper"; + Eio_name.name "unix sleeper"; (* Woops! Wrong sleep function, we blocked the fiber *) traceln "Woops! Blocked by Unix.sleepf"; Unix.sleepf 5.; Time.sleep clock 10.) let spawn ~clock min max = - Private.Ctf.set_name (Fmt.str "spawn %d %d" min max); + Eio_name.name (Fmt.str "spawn %d %d" min max); (* Some GC action *) for _i = 0 to 100 do ignore (Sys.opaque_identity @@ Array.init 1000000 float_of_int) done; - Switch.run @@ fun sw -> + Switch.run ~name:"spawn ctx" @@ fun sw -> for i = min to max do Fiber.fork ~sw (fun () -> - Private.Ctf.set_name (Fmt.str "worker>%d" i); + Eio_name.name (Fmt.str "worker>%d" i); for i = 0 to max do (* Some more GC action *) for _i = 0 to 100 do @@ -37,9 +36,10 @@ let spawn ~clock min max = let main clock = let p, r = Promise.create () in Switch.run ~name:"main" @@ fun sw -> + Eio_name.name "main fiber"; (* A long running task *) Fiber.fork ~sw (fun () -> - Private.Ctf.set_name "waiter"; + Eio_name.name "waiter"; traceln "stuck waiting :("; Promise.await p; traceln "Done"); @@ -53,6 +53,5 @@ let main clock = let () = Eio_main.run @@ fun env -> - Ctf.with_tracing @@ fun () -> let clock = Stdenv.clock env in main clock diff --git a/example/burn_domains.ml b/example/burn_domains.ml index 73da2ec..c0ffe3a 100644 --- a/example/burn_domains.ml +++ b/example/burn_domains.ml @@ -42,7 +42,6 @@ let main dom_mgr clock = let () = Eio_main.run @@ fun env -> - Ctf.with_tracing @@ fun () -> let clock = Stdenv.clock env in let dom_mgr = Stdenv.domain_mgr env in main dom_mgr clock diff --git a/example/deadlock.ml b/example/deadlock.ml index 86bb168..c57bd82 100644 --- a/example/deadlock.ml +++ b/example/deadlock.ml @@ -4,7 +4,7 @@ let fork wait = Switch.run @@ fun sw -> Fiber.fork ~sw (fun () -> (* Also add a really big label to test the handling of that in CTF. *) - Eio.Private.Ctf.log (String.make 5000 'e'); + Eio_name.name (String.make 5000 'e'); Promise.await wait) let main () = diff --git a/example/dune b/example/dune index 1c6fdb3..40dacf8 100644 --- a/example/dune +++ b/example/dune @@ -1,3 +1,9 @@ (executables (names main deadlock burn burn_domains) - (libraries astring eio eio_main unix eio.unix)) + (modules :standard \ eio_name) + (libraries astring eio eio_main unix eio.unix eio_name)) + +(library + (name eio_name) + (modules eio_name) + (libraries eio)) diff --git a/example/eio_name.ml b/example/eio_name.ml new file mode 100644 index 0000000..ad8feb4 --- /dev/null +++ b/example/eio_name.ml @@ -0,0 +1,3 @@ +let name s = + let ctx = Effect.perform Eio.Private.Effects.Get_context in + Eio.Private.Trace.name (Eio.Private.Fiber_context.tid ctx) s diff --git a/example/main.ml b/example/main.ml index a908654..dbc81d7 100644 --- a/example/main.ml +++ b/example/main.ml @@ -21,6 +21,5 @@ let main clock = let () = Eio_main.run @@ fun env -> - Ctf.with_tracing @@ fun () -> let clock = Stdenv.clock env in main clock diff --git a/example/zero.ml b/example/zero.ml index bbca728..1607357 100644 --- a/example/zero.ml +++ b/example/zero.ml @@ -8,13 +8,12 @@ let main clock = (* Eio.Switch.run ~name:"forked context" @@ fun sw -> traceln "in another context I do this" *)) *) (* for i = 0 to 10 do - Eio.Switch.run ~name:(Fmt.str "switch %d" i) @@ fun sw -> - traceln "welcome %d" i - done; *) + Eio.Switch.run ~name:(Fmt.str "switch %d" i) @@ fun sw -> + traceln "welcome %d" i + done; *) Eio.Time.sleep clock 100000.0 let () = Eio_main.run @@ fun env -> - Ctf.with_tracing @@ fun () -> let clock = Stdenv.clock env in main clock diff --git a/meio.opam b/meio.opam index af108aa..4129bf4 100644 --- a/meio.opam +++ b/meio.opam @@ -1,19 +1,19 @@ opam-version: "2.0" synopsis: "Monitor live Eio programs" description: - "Eio-console provides an executable that allows you to monitor OCaml programs using Eventring." + "Meio provides an executable that allows you to monitor OCaml programs using Eventring." maintainer: ["patrick@sirref.org"] authors: ["Patrick Ferris"] license: "MIT" homepage: "https://github.com/ocaml-multicore/meio" bug-reports: "https://github.com/ocaml-multicore/meio/issues" depends: [ - "dune" {>= "2.9"} + "dune" {>= "3.10"} "eio_main" - "eio" + "eio" {>= "0.14"} "astring" "ptime" - "nottui" + "nottui-unix" "logs" "cmdliner" "hdr_histogram" @@ -35,11 +35,4 @@ build: [ ] ["dune" "install" "-p" name "--create-install-files" name] ] -dev-repo: "git+https://github.com/ocaml-multicore/meio.git" -pin-depends: [ - # Rebased version of https://github.com/TheLortex/eio/tree/runtime-events - ["eio.dev" "git+https://github.com/tmcgilchrist/eio#48fa41f1c6d915fc39848a406aed8c8a49cc25ba"] - ["eio_main.dev" "git+https://github.com/tmcgilchrist/eio#48fa41f1c6d915fc39848a406aed8c8a49cc25ba"] - ["eio_linux.dev" "git+https://github.com/tmcgilchrist/eio#48fa41f1c6d915fc39848a406aed8c8a49cc25ba"] - ["eio_posix.dev" "git+https://github.com/tmcgilchrist/eio#48fa41f1c6d915fc39848a406aed8c8a49cc25ba"] -] \ No newline at end of file +dev-repo: "git+https://github.com/ocaml-multicore/meio.git" \ No newline at end of file diff --git a/src/bin/meio.ml b/src/bin/meio.ml index fbed467..7ded910 100644 --- a/src/bin/meio.ml +++ b/src/bin/meio.ml @@ -12,7 +12,9 @@ let run _stdenv exec_args = |] (Unix.environment ()) in - let dev_null = Unix.openfile Filename.null [ Unix.O_WRONLY; Unix.O_KEEPEXEC ] 0o666 in + let dev_null = + Unix.openfile Filename.null [ Unix.O_WRONLY; Unix.O_KEEPEXEC ] 0o666 + in let child_pid = Unix.create_process_env executable_filename argsl env Unix.stdin dev_null dev_null diff --git a/src/lib/console.ml b/src/lib/console.ml index 7b5fe2e..31494d8 100644 --- a/src/lib/console.ml +++ b/src/lib/console.ml @@ -97,8 +97,8 @@ let render_tree_line ~filtered depth is_active attr = |> Ui.hcat let render_task sort now ~depth ~filtered - ({ Task.id; domain; start; loc; name; busy; selected; status; kind; _ } as - t) = + ({ Task.id; domain; start; loc; name; busy; selected; status; kind; _ } as t) + = let is_active = Task.is_active t in let attr = attr' !selected is_active in let attr = @@ -147,9 +147,9 @@ let render_task sort now ~depth ~filtered let kind = W.string ~attr (match kind with - | Cancellation_context _ -> "cc" - | Task -> "task" - | _ -> "??") + | `Create (_, `Cc _) -> "cc" + | `Create (_, `Fiber_in _) -> "task" + | _ -> Fmt.str "%a" Eio_runtime_events.pp_event kind) in (attr, !selected, [ domain; id; kind; name; busy; idle; entered; loc ], t) diff --git a/src/lib/dune b/src/lib/dune index 1c3cf6a..542ad59 100644 --- a/src/lib/dune +++ b/src/lib/dune @@ -4,4 +4,12 @@ (foreign_stubs (language c) (names meio_console_stubs)) - (libraries eio eio.utils runtime_events ptime logs nottui hdr_histogram)) + (libraries + eio + eio.utils + runtime_events + eio.runtime_events + ptime + logs + nottui-unix + hdr_histogram)) diff --git a/src/lib/help.ml b/src/lib/help.ml index 29b6df5..aac3e65 100644 --- a/src/lib/help.ml +++ b/src/lib/help.ml @@ -22,7 +22,7 @@ let footer sort screen = space; key_help ~attr:(attr `Task) 'e' "Fiber info"; space; - key_help ~attr:(attr `Logs) 'l' ("Logs"); + key_help ~attr:(attr `Logs) 'l' "Logs"; space; key_help 's' ("Sort " ^ Sort.to_string sort); space; diff --git a/src/lib/meio.ml b/src/lib/meio.ml index 41d66c8..51531c3 100644 --- a/src/lib/meio.ml +++ b/src/lib/meio.ml @@ -1,6 +1,4 @@ -module Ctf = Eio.Private.Ctf - -let add_callback = Runtime_events.Callbacks.add_user_event +module RE = Eio_runtime_events let task_events ~latency_begin ~latency_end q = let current_id = ref (-1) in @@ -12,44 +10,27 @@ let task_events ~latency_begin ~latency_end q = Logs.warn (fun f -> f "[Domain %d] Lost %d events." domain count)) () in - let id_event_callback d ts c ((i : Ctf.id), v) = - match (Runtime_events.User.tag c, v) with - | Ctf.Created, (Ctf.Task | Ctf.Cancellation_context _) -> - Queue.push q (`Created ((i :> int), !current_id, d, ts, v)) - | _ -> () - in - let two_ids_callback _d ts c ((child : Ctf.id), (parent : Ctf.id)) = - match Runtime_events.User.tag c with - | Ctf.Parent -> Queue.push q (`Parent ((child :> int), (parent :> int), ts)) - | _ -> () - in - let unit_callback d ts c () = - match Runtime_events.User.tag c with - | Ctf.Suspend -> + let callback d (ts : Runtime_events.Timestamp.t) (e : RE.event) = + match e with + (* | -> Queue.push q () *) + | `Create (fiber, `Fiber_in parent) -> + Queue.push q (`Created ((fiber :> int), parent, d, ts, e)) + | `Create (id, `Cc _) -> + Queue.push q (`Created ((id :> int), !current_id, d, ts, e)); + (* Bit of a hack -- eio could label this for us? *) + if id = 0 then Queue.push q (`Name (id, "root")) + | `Suspend_fiber _ -> current_id := -1; Queue.push q (`Suspend (d, ts)) - | _ -> () - in - let id_callback d ts c i = - match Runtime_events.User.tag c with - | Ctf.Resolved -> Queue.push q (`Resolved (i, d, ts)) - | Ctf.Switch -> + | `Exit_fiber i -> Queue.push q (`Resolved (i, d, ts)) + | `Fiber i -> current_id := i; Queue.push q (`Switch ((i :> int), d, ts)) + | `Name (i, s) -> Queue.push q (`Name ((i :> int), s)) + | `Log s -> Queue.push q (`Log ((!current_id :> int), s)) | _ -> () in - let id_label_callback _d _ts c ((i : Ctf.id), s) = - match Runtime_events.User.tag c with - | Ctf.Name -> Queue.push q (`Name ((i :> int), s)) - | Ctf.Log -> Queue.push q (`Log ((i :> int), s)) - | Ctf.Loc -> Queue.push q (`Loc ((i :> int), s)) - | _ -> () - in - add_callback Ctf.created_type id_event_callback evs - |> add_callback Runtime_events.Type.int id_callback - |> add_callback Runtime_events.Type.unit unit_callback - |> add_callback Ctf.labelled_type id_label_callback - |> add_callback Ctf.two_ids_type two_ids_callback + RE.add_callbacks callback evs let get_selected () = Task_tree.find_first_lwd State.tasks (fun v -> !(v.Task.selected)) @@ -174,7 +155,7 @@ let ui_loop ~q ~hist = in Logs.info (fun f -> f "UI ready !"); - Nottui.Ui_loop.run ~quit_on_escape:false ~quit + Nottui_unix.run ~quit_on_escape:false ~quit ~tick:(fun () -> Logging.poll (); Console.set_prev_now (Timestamp.current ()); @@ -185,7 +166,8 @@ let ui_loop ~q ~hist = while not (Queue.is_empty q) do match Queue.pop q with | None -> () - | Some (`Created v) -> State.add_tasks v + | Some (`Created (id, parent_id, domain, ts, v)) -> + State.add_tasks ~id ~parent_id ~domain ts v | Some (`Switch (v, domain, ts)) -> State.switch_to ~id:(v :> int) ~domain ts | Some (`Suspend (domain, ts)) -> State.switch_to ~id:(-1) ~domain ts diff --git a/src/lib/state.ml b/src/lib/state.ml index f0a87fc..145e37d 100644 --- a/src/lib/state.ml +++ b/src/lib/state.ml @@ -6,7 +6,7 @@ let set_parent ~child ~parent ts = ~parent:(Task.Id.eio_of_int parent) (Runtime_events.Timestamp.to_int64 ts) -let add_tasks (id, parent_id, domain, ts, kind) = +let add_tasks ~id ~parent_id ~domain ts kind = let task = Task.create ~id ~domain ~parent_id (Runtime_events.Timestamp.to_int64 ts) diff --git a/src/lib/state.mli b/src/lib/state.mli index b95c57c..1461122 100644 --- a/src/lib/state.mli +++ b/src/lib/state.mli @@ -1,7 +1,12 @@ val tasks : Task_tree.t val add_tasks : - int * int * int * Runtime_events.Timestamp.t * Eio.Private.Ctf.event -> unit + id:int -> + parent_id:int -> + domain:int -> + Runtime_events.Timestamp.t -> + Eio_runtime_events.event -> + unit val update_loc : int -> string -> unit val update_logs : int -> string -> unit diff --git a/src/lib/task.ml b/src/lib/task.ml index 5a4d81a..f3c07f5 100644 --- a/src/lib/task.ml +++ b/src/lib/task.ml @@ -91,7 +91,7 @@ type t = { loc : string list; logs : string list; status : status; - kind : Eio.Private.Ctf.event; + kind : Eio_runtime_events.event; selected : bool ref; display : display ref; } @@ -122,7 +122,7 @@ let ns_span i = Fmt.(to_to_string uint64_ns_span (Int64.of_int i)) let ui task = match task.kind with - | Cancellation_context _ -> + | `Create (_, `Cc _) -> W.fmt ~attr:Notty.A.(st bold ++ fg green) "Cancellation context %a in domain %i" Id.pp task.id task.domain diff --git a/src/lib/task.mli b/src/lib/task.mli index 23ab6c7..bc5ee8f 100644 --- a/src/lib/task.mli +++ b/src/lib/task.mli @@ -37,7 +37,7 @@ type t = { loc : string list; logs : string list; status : status; - kind : Eio.Private.Ctf.event; + kind : Eio_runtime_events.event; selected : bool ref; display : display ref; } @@ -45,6 +45,11 @@ type t = { val is_active : t -> bool val create : - id:int -> domain:int -> parent_id:int -> int64 -> Eio.Private.Ctf.event -> t + id:int -> + domain:int -> + parent_id:int -> + int64 -> + Eio_runtime_events.event -> + t val ui : t -> Nottui.ui diff --git a/src/lib/task_tree.ml b/src/lib/task_tree.ml index fe1ebeb..f00eded 100644 --- a/src/lib/task_tree.ml +++ b/src/lib/task_tree.ml @@ -14,7 +14,7 @@ let make () = let node = { (Task.create ~id:(-1) ~domain:0 ~parent_id:(-1) (Timestamp.current ()) - Task) + (`Create (-1, `Fiber_in (-1)))) with name = [ "sleep" ]; selected = ref true; @@ -36,7 +36,7 @@ let invalidate t = List.iter Lwd.invalidate t.waiters let add t (task : Task.t) = match task.kind with - | Eio.Private.Ctf.Cancellation_context _ -> ( + | `Create (_, (`Fiber_in _ | `Cc _)) -> ( match Hashtbl.find_opt t.by_id (Task.Id.eio_of_int task.parent_id) with | None -> Logs.warn (fun f -> @@ -81,9 +81,7 @@ let update_active t ~id ts = invalidate t let is_cancellation_context task = - match task.Task.kind with - | Eio.Private.Ctf.Cancellation_context _ -> true - | _ -> false + match task.Task.kind with `Create (_, `Cc _) -> true | _ -> false let set_parent t ~child ~parent ts = Logs.debug (fun f ->