The
[Stdlib.at_exit](https://github.com/ocaml/ocaml/blob/744006bfbfa045cc1ca442ff7b52c2650d2abe32/stdlib/stdlib.ml#L559-L580)

```ocaml
let exit_function = atomic_make flush_all

let rec at_exit f =
  (* MPR#7253, MPR#7796: make sure "f" is executed only once *)
  let f_yet_to_run = atomic_make true in
  let old_exit = atomic_get exit_function in
  let new_exit () =
    if atomic_compare_and_set f_yet_to_run true false then f () ;
    old_exit ()
  in
  let success = atomic_compare_and_set exit_function old_exit new_exit in
  if not success then at_exit f

let do_domain_local_at_exit = ref (fun () -> ())

let do_at_exit () =
  (!do_domain_local_at_exit) ();
  (atomic_get exit_function) ()

let exit retcode =
  do_at_exit ();
  sys_exit retcode
```

leaves a lot to be desired.

First of all, it doesn't guarantee that actions registered through `at_exit` are
called. This is because after an action raises an exception, the remaining
actions are not called:

```ocaml
  let new_exit () =
    if atomic_compare_and_set f_yet_to_run true false then f () ;
    old_exit ()
  in
```

Did I already mention that
[`Domain.at_exit` has the same problem](https://github.com/ocaml/ocaml/blob/744006bfbfa045cc1ca442ff7b52c2650d2abe32/stdlib/domain.ml#L238-L240)?

At minimum this behaviour should be documented. It currently is not.

Also, `at_exit` unnecessarily allocates an atomic per registered action. The
idea there is to prevent an action from being called multiple times. However,
there is a much simpler and less expensive way to achieve that by atomically
exchanging the `exit_function` atomic:

```diff
 let do_at_exit () =
   (!do_domain_local_at_exit) ();
-  (atomic_get exit_function) ()
+  (atomic_exchange exit_function (fun x -> x)) ()
```