summaryrefslogtreecommitdiff
path: root/testsuite/tests/lib-threads/bank.ml
blob: bb31fc24c0213c51da9cf48bcf5c2e31bf7bc9f3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
(***********************************************************************)
(*                                                                     *)
(*                                OCaml                                *)
(*                                                                     *)
(*            Xavier Leroy, projet Cristal, INRIA Rocquencourt         *)
(*                                                                     *)
(*  Copyright 1996 Institut National de Recherche en Informatique et   *)
(*  en Automatique.  All rights reserved.  This file is distributed    *)
(*  under the terms of the Q Public License version 1.0.               *)
(*                                                                     *)
(***********************************************************************)

(* The bank account example, using events and channels *)

open Printf
open Event

type account = int channel * int channel

let account (put_ch, get_ch) =
  let rec acc balance =
    select [
      wrap (send get_ch balance) (fun () -> acc balance);
      wrap (receive put_ch) (fun amount ->
        if balance + amount < 0 then failwith "negative balance";
        acc (balance + amount))
    ]
  in acc 0

let get ((put_ch, get_ch): account) = sync (receive get_ch)
let put ((put_ch, get_ch): account) amount = sync (send put_ch amount)

let _ =
  let a : account = (new_channel(), new_channel()) in
  ignore (Thread.create account a);
  put a 100;
  printf "Current balance: %d\n" (get a);
  for i = 1 to 99 do put a (-2); put a 1 done;
  printf "Final balance: %d\n" (get a)