// ---------------------------------------------------------------------------
// - cgen.cxx                                                                -
// - standard system library - C generator functions implementation          -
// ---------------------------------------------------------------------------
// - This program is free software;  you can redistribute it  and/or  modify -
// - it provided that this copyright notice is kept intact.                  -
// -                                                                         -
// - This program  is  distributed in  the hope  that it will be useful, but -
// - without  any  warranty;  without  even   the   implied    warranty   of -
// - merchantability or fitness for a particular purpose.  In no event shall -
// - the copyright holder be liable for any  direct, indirect, incidental or -
// - special damages arising in any way out of the use of this software.     -
// ---------------------------------------------------------------------------
// - copyright (c) 1999-2006 amaury darsch                                   -
// ---------------------------------------------------------------------------

#include "cthr.hpp"
#include "csys.hpp"
#include "cgen.hpp"
#include "cgen.hxx"

namespace afnix {

  // static mutex creation function
  static void* mtx_create (void);
  // mutex or network services
  static void* mtx = mtx_create ();

  // this function destroy the mutex at exit
  static void mtx_destroy (void) {
    c_mtxdestroy (mtx);
  }

  // this function initialize a mutex statically and register its
  // destruction to be done at exit
  static void* mtx_create (void) {
    void* mtx = c_mtxcreate ();
    c_atexit (mtx_destroy);
    return mtx;
  }

  // return a long random number

  long c_longrnd (void) {
    c_mtxlock (mtx);
    long result = random ();
    c_mtxunlock (mtx);
    return result;
  }

  // return a long random number

  long c_longrnd (const long max) {
    if (max < RAND_MAX) {
      c_mtxlock (mtx);
      long result = 1 + (long) (((t_real) max) * random () / (RAND_MAX + 1.0));
      c_mtxunlock (mtx);
      return result;
    }
    long result = (long) (c_realrnd () * (t_real) max);
    return result;
  }

  // return a real random number between 0 and 1

  t_real c_realrnd (void) {
    c_mtxlock (mtx);
    t_real result = ((t_real) random ()) / ((t_real) RAND_MAX);
    c_mtxunlock (mtx);
    return result;
  }

  // return a random byte

  t_byte c_byternd (void) {
    c_mtxlock (mtx);
    t_byte result = 1 + (t_byte) (256.0 * random () / (RAND_MAX + 1.0));
    c_mtxunlock (mtx);
    return result;
  }
}
