library math;

architecture behavior of server is

begin

  service : process is

    variable served_token : token_type;
    variable release_time : time;
    variable number_of_tokens_served : natural := 0;
    variable service_time : natural;  -- in time_unit
    variable sum_of_service_times : real := 0.0;  -- in time_unit
    variable sum_of_squares_of_service_times : real := 0.0;  --in time_unit**2

    variable random_info : random_info_record;
    variable random_number : real;

    use std.textio.all;
    file info_file : text;
    variable L : line;

    use math.math_real.sqrt;

    procedure write_summary is
      variable measured_mean_service_time : real
        := sum_of_service_times / real(number_of_tokens_served);
      variable measured_std_dev_of_service_times : real
        := sqrt ( ( sum_of_squares_of_service_times
                    - sum_of_service_times**2 / real(number_of_tokens_served) )
                  / real( number_of_tokens_served - 1 ) );
    begin
      write(L, string'("Summary information for server "));
      write(L, name);
      write(L, string'(" up to time "));
      write(L, now, unit => time_unit);
      writeline(info_file, L);
      write(L, string'("  Service distribution: "));
      write(L, distribution_type'image(distribution));
      write(L, string'(" with mean service time of "));
      write(L, mean_service_time, unit => time_unit);
      writeline(info_file, L);
      write(L, string'("  Number of tokens served = "));
      write(L, natural(number_of_tokens_served));
      writeline(info_file, L);
      write(L, string'("  Mean service time = "));
      write(L, measured_mean_service_time * time_unit, unit => time_unit);
      writeline(info_file, L);
      write(L, string'("  Standard deviation of service times = "));
      write(L, measured_std_dev_of_service_times * time_unit, unit => time_unit);
      writeline(info_file, L);
      write(L, string'("  Utilization = "));
      write(L, sum_of_service_times / real(now / time_unit), digits => 4);
      writeline(info_file, L);
      writeline(info_file, L);
    end procedure write_summary;

    procedure write_trace_service is
    begin
      write(L, string'("Server "));
      write(L, name);
      write(L, string'(": at "));
      write(L, now, unit => time_unit);
      write(L, string'(" served "));
      write(L, in_arc.token, time_unit);
      writeline(info_file, L);
    end procedure write_trace_service;

    procedure write_trace_release is
    begin
      write(L, string'("Server "));
      write(L, name);
      write(L, string'(": at "));
      write(L, now, unit => time_unit);
      write(L, string'(" released "));
      write(L, served_token, time_unit);
      writeline(info_file, L);
    end procedure write_trace_release;

  begin
    file_open(info_file, info_file_name, write_mode);

    case distribution is
      when fixed =>
        init_fixed(random_info, real(mean_service_time / time_unit));
      when uniform =>
        init_uniform( random_info,
                      lower_bound => 0.0,
                      upper_bound => 2.0 * real(mean_service_time / time_unit),
                      seed => seed );
      when exponential =>
        init_exponential( random_info,
                          mean => real(mean_service_time / time_unit),
                          seed => seed );
    end case;

    in_ready <= true;
    loop
      wait on info_detail'transaction, in_arc;
      if info_detail'active and info_detail = summary then
        write_summary;
      end if;
      if in_arc'event then
	in_ready <= false;
        if info_detail = trace then
          write_trace_service;
        end if;
        served_token := in_arc.token;
        generate_random(random_info, random_number);
        service_time :=  natural(random_number);
        release_time := service_time * time_unit + now;
        loop
          wait on info_detail'transaction for release_time - now;
          if info_detail'active and info_detail = summary then
            write_summary;
          end if;
          exit when release_time = now;
        end loop;
	in_ready <= true;
	out_arc <= arc_type'( transaction => not out_arc.transaction'driving_value,
			      token => served_token );
        number_of_tokens_served := number_of_tokens_served + 1;
        sum_of_service_times := sum_of_service_times + real(service_time);
        sum_of_squares_of_service_times := sum_of_squares_of_service_times
                                           + real(service_time) ** 2;
        if info_detail = trace then
          write_trace_release;
        end if;
      end if;
    end loop;
  end process service;

end architecture behavior;

<div align="center"><br /><script type="text/javascript"><!--
google_ad_client = "pub-7293844627074885";
//468x60, Created at 07. 11. 25
google_ad_slot = "8619794253";
google_ad_width = 468;
google_ad_height = 60;
//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script><br />&nbsp;</div>