(**************************************************************************)
(*                                                                        *)
(*  Ocamlviz --- real-time profiling tools for Objective Caml             *)
(*  Copyright (C) by INRIA - CNRS - Universite Paris Sud                  *)
(*  Authors: Julien Robert                                                *)
(*           Guillaume Von Tokarski                                       *)
(*           Sylvain Conchon                                              *)
(*           Jean-Christophe Filliatre                                    *)
(*           Fabrice Le Fessant                                           *)
(*  GNU Library General Public License version 2                          *)
(*  See file LICENSE for details                                          *)
(*                                                                        *)
(**************************************************************************)

(** Common signature for [Ocamlviz] and [Ocamlviz_threads] *)

module type Monitor = sig


  (* Observers *)
  
  
  (* Program points *)

  module Point : sig
     
    type t
      (** The abstract type for a point. *)
      
    val create : string -> t
      (** [create s] creates a point called [s]. *)
      
    val kill : t -> unit
      (** [kill p] kills a point [p]. This means that this point 
	  won't be monitored anymore. *)
      
    val observe : t -> unit
      (** [observe p] puts a checkpoint [p]
	  at the place where it is used. *)
      
      
    (** High-levels observators *)
      
    val observe_calls : string -> ('a -> 'b -> 'c) -> ('a -> 'b -> 'c)
      (** [observe_calls s f] create a point called [s] inside the function [f] that has one argument and isn't recursive. *)

    val observe_calls2 : string -> ('a -> 'b -> 'c) -> ('a -> 'b -> 'c)
      (** [observe_calls2 s f] create a point called [s] inside the function [f] that has two arguments and isn't recursive. *)
      
    val observe_calls_rec : string  -> (('a -> 'b) -> 'a -> 'b) -> 
      'a -> 'b
      (** [observe_calls_rec s f] create a point called [s] inside the function [f] that has one argument and is recursive. *)
      
    val observe_calls_rec2 : string  -> (('a -> 'b -> 'c) -> 'a -> 'b -> 'c) ->
      'a -> 'b -> 'c
      (** [observe_calls_rec2 s f] create a point called [s] inside the function [f] that has two arguments and is recursive. *)
      
  end
    (** A module that allows to create checkpoints and
	watch how many times the program go through these points. *)
    
    
  (* Tags *)

  module Tag : sig
    
    (**/**) 
    module WeakHash :sig
      type t
      type data
      val create : int -> t
      val clear : t -> unit
      val merge : t -> data -> data
      val add : t -> data -> unit
      val remove : t -> data -> unit
      val find : t -> data -> data
      val find_all : t -> data -> data list
      val mem : t -> data -> bool
      val iter : (data -> unit) -> t -> unit
      val fold : (data -> 'a -> 'a) -> t -> 'a -> 'a
      val count : t -> int
      val stats : t -> int * int * int * int * int * int
    end
      (**/**) 
      
    type t
      (** The abstract type for a tag. *)
      
    val create : ?size:bool -> ?count:bool -> ?fct_size:(WeakHash.t -> Int64.t) -> ?period:int -> string -> t
      (** [create s] creates a tag called [s].
	  @param size Chooses whether the tag will handle the size of its values 
	  @param count Chooses whether the tag will handle the number of its values
	  @param fct_size Puts your own function to calculate the size
	  @param period Sets the period to which the size and/or the count will be calculated (in milliseconds). Default is 100ms.
      *)
      
    val kill : t -> unit
      (** [kill t] kills a tag [t]. This means that this tag
	  won't be monitored anymore. This may improve considerably the program's speed. *)
      
    val set_period : t -> int -> unit 
      (** [set_period t p] changes the period to which the operations on the tag [t] are made.
	  @param t Tag
	  @param p Period (in milliseconds) 
      *)

    val mark : t -> 'a -> 'a
      (** [mark t v] marks any value [v] of type 'a with the tag [t].
	  One tag can mark many values.
	  One value can be marked by many tags.
	  A tag may contain any value of any type.
      *)
      
  end
    (** A module that allows to create tags and mark values.
      It calculates tags' cardinal and size in memory. *)
    
    
  (* Times *)
    
  module Time : sig
    
    type t
         
      
    val elapsed_time : unit -> float
      (** Time passed since the initialization (in seconds). *)
      
    val create : string -> t
      (** [create s] creates a time called [s]. *)
      
    val kill : t -> unit
      (** [kill t] kills a time [t]. This means that this time
	  won't be monitored anymore. *)
      
    val start : t -> unit
      (** [start t] starts the time monitoring [t]
	  at the place where it is used. 
	  @raise Already_started if [t] is already running. *)
      
    val stop : t -> unit
      (** [stop t] sets the end of the time monitoring [t]
	  at the place where it is used.
	  @raise Not_started if no [start t] was previously called. *)
      
    val time : string -> ('a -> 'b) -> 'a -> 'b
      (** [time s f arg] monitors the time spent in the function [f].
	  @param f Function
	  @param arg Function argument
	  @param s Time monitor's name
      *)
      
  end
    (** A module that allows time monitoring. *)
    
    
  (* Values *)
    
  module Value : sig
      
    val observe_int_fct :  ?weak:bool -> ?period:int -> string -> (unit -> int) -> unit
      (** [observe_int n f] monitors an integer given by the function [f].
	  @param n [Value] name
	  @param weak Chooses whether the integer is attached to a weak pointer or a normal pointer. 
	  @param period Sets the period to which the value will be calculated (in milliseconds). Default is 100ms. *)

    val observe_int :  ?weak:bool -> ?period:int -> string -> int -> unit
      (** [observe_int_now n i] monitors an integer [i].*)

    val observe_float_fct : ?weak:bool -> ?period:int -> string -> (unit -> float) -> unit
      (** [observe_float n f] monitors a floating-point number given by the function [f]. *)

    val observe_float : ?weak:bool -> ?period:int -> string -> float -> unit
      (** [observe_float_now n f] monitors a floating-point number [f]. *)

    val observe_bool_fct : ?weak:bool -> ?period:int -> string -> (unit -> bool) -> unit
      (** [observe_bool n f] monitors a boolean given by the function [f]. *)      
      
    val observe_bool : ?weak:bool -> ?period:int -> string -> bool -> unit
      (** [observe_bool_now n b] monitors a boolean [b]. *)

    val observe_string_fct : ?weak:bool -> ?period:int -> string -> (unit -> string ) -> unit
      (** [observe_string n f] monitors a string given by the function [f]. *)

    val observe_string : ?weak:bool -> ?period:int -> string -> string -> unit
      (** [observe_string_now n s] monitors a string [s]. *)

    (*   module Make(X : sig type t val to_string : t -> string) : sig *)
    (*     val observe : string -> (X.t -> unit) -> unit *)
    (*   end *)
      
    val observe_int_ref : ?period:int -> string -> int ref -> int ref
      (** [observe_int_ref n i] monitors an integer reference [i]. *)
      

    val observe_float_ref : ?period:int -> string -> float ref -> float ref
      (** [observe_float_ref n f] monitors a floating-point number reference [f]. *)


    val observe_bool_ref : ?period:int -> string -> bool ref -> bool ref
      (** [observe_bool_ref n b] monitors a boolean reference [b]. *)

      
    val observe_string_ref : ?period:int -> string -> string ref -> string ref
      (** [observe_string_ref n s] monitors a string reference [s]. *)

      
  end
    (** A module to monitor OCaml values such as native integers, floating-point numbers, booleans, strings.  *)
    
    
  module Tree : sig
    
    val observe : ?period:int -> string -> (unit -> Protocol.variant) -> unit
      (** [observe s f] monitors a variant called [s] given by the function [f].
      *)

  end
    (** A module to monitor OCaml variant types and trees. *)


  module Hashtable : sig
   
    type 'a t

    val observe : ?period:int -> string -> 'a -> 'a
      (** [observe s h] monitors a hash table [h] called [s].
	  One can observe six things about the table:
	  - hash table length (number of elements inside the table)
	  - array length (number of entries of the table)
	  - number of empty buckets
	  - hash table filling rate
	  - longest bucket
	  - mean bucket length
      *)
   
  end
    (** A module that allows hash tables monitoring. *) 




  (**/**) 
  val to_send : unit -> string
    
  val declare_tags : unit -> string
    
  (**/**) 
    

  val log : ('a, Format.formatter, unit, unit) format4 -> 'a
    (** Similar to an Ocaml printf function. *)
    
  val wait_for_connected_clients : int -> unit
    (** [wait_for_connected_clients n] blocks the program 
	until [n] clients are connected. *)
    
  val wait_for_killed_clients : unit -> unit
    (** [wait_for_killed_clients ()] blocks the program 
	until every clients are disconnected. *) 
    
  (**/**)
  val set_nb_clients : int -> unit

end
  
(*
  Local Variables: 
  compile-command: "unset LANG; make -C .."
  End: 
*)
