/*
 * Copyright (C) 2011 UChicago Argonne, LLC
 * All Rights Reserved
 *
 * Permission to use, reproduce, prepare derivative works, and to redistribute
 * to others this software, derivatives of this software, and future versions
 * of this software as well as its documentation is hereby granted, provided
 * that this notice is retained thereon and on all copies or modifications.
 * This permission is perpetual, world-wide, and provided on a royalty-free
 * basis. UChicago Argonne, LLC and all other contributors make no
 * representations as to the suitability and operability of this software for
 * any purpose. It is provided "as is" without express or implied warranty. 
 *
 * Portions of this software are copyright by UChicago Argonne, LLC. Argonne
 * National Laboratory with facilities in the state of Illinois, is owned by
 * The United States Government, and operated by UChicago Argonne, LLC under
 * provision of a contract with the Department of Energy. 
 *
 * PORTIONS OF THIS SOFTWARE  WERE PREPARED AS AN ACCOUNT OF WORK SPONSORED BY
 * AN AGENCY OF THE UNITED STATES GOVERNMENT. NEITHER THE UNITED STATES
 * GOVERNMENT NOR ANY AGENCY THEREOF, NOR THE UNIVERSITY OF CHICAGO, NOR ANY OF
 * THEIR EMPLOYEES OR OFFICERS, MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
 * ASSUMES ANY LEGAL LIABILITY OR RESPONSIBILITY FOR THE ACCURACY,
 * COMPLETENESS, OR USEFULNESS OF ANY INFORMATION, APPARATUS, PRODUCT, OR
 * PROCESS DISCLOSED, OR REPRESENTS THAT ITS USE WOULD NOT INFRINGE PRIVATELY
 * OWNED RIGHTS. REFERENCE HEREIN TO ANY SPECIFIC COMMERCIAL PRODUCT, PROCESS,
 * OR SERVICE BY TRADE NAME, TRADEMARK, MANUFACTURER, OR OTHERWISE, DOES NOT
 * NECESSARILY CONSTITUTE OR IMPLY ITS ENDORSEMENT, RECOMMENDATION, OR FAVORING
 * BY THE UNITED STATES GOVERNMENT OR ANY AGENCY THEREOF. THE VIEW AND OPINIONS
 * OF AUTHORS EXPRESSED HEREIN DO NOT NECESSARILY STATE OR REFLECT THOSE OF THE
 * UNITED STATES GOVERNMENT OR ANY AGENCY THEREOF. 
 *
 * Author: Hal Finkel <hfinkel@anl.gov>
 */

#ifndef BIGCHUNK_H
#define BIGCHUNK_H

#include <stddef.h>
#include <stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Allocates memory from the big chunck, falling back to the system's allocator.
 */

void *bigchunk_malloc(size_t sz);

/*
 * Frees memory, this does nothing if the memory comes from the big chunk.
 */

void bigchunk_free(void *ptr);

/*
 * Resets the state of the big chunk (marks all memory in the chunk as free).
 */

void bigchunk_reset();

/*
 * Initialize the big chunk (to the specified size).
 */

void bigchunk_init(size_t sz);

/*
 * Free the big chunk (all memory within it should already be free).
 */

void bigchunk_cleanup();

/*
 * Get the size of the big chunk.
 */

size_t bigchunk_get_size();

/*
 * Get the total amount of memory allocated
 * (freed memory is not subtracted, so this measures the total of all allocation
 * requests in between calls to bigchunk_reset().
 */

size_t bigchunk_get_total();

#ifdef __cplusplus
}

template <typename T>
class bigchunk_allocator
{
public:
  typedef T value_type;
  typedef T *pointer;
  typedef T &reference;
  typedef const T *const_pointer;
  typedef const T &const_reference;
  typedef size_t size_type;
  typedef ptrdiff_t difference_type;

  template <typename U>
  struct rebind {
  	typedef bigchunk_allocator<U> other;
  };

public:
  bigchunk_allocator() throw() {};
  bigchunk_allocator(const bigchunk_allocator&) throw() {};

  template <typename U>
  bigchunk_allocator(const bigchunk_allocator<U>&) throw() {};

public:
  ~bigchunk_allocator() throw () {};

public:
  pointer address(reference x) const { return &x; }
  const_pointer address (const_reference x) const { return &x; }

  size_type max_size() const throw() { return size_t(-1) / sizeof(T); }

  void construct(pointer p, const_reference val) { ::new ((void*)p) T(val); }
  void destroy(pointer p) { ((T*)p)->~T(); }

public:
  pointer allocate(size_type n,
                   const void * /*hint*/ = 0)
  {
    return (pointer) ::bigchunk_malloc(n*sizeof(T));
  }

  void deallocate(pointer p, size_type n)
  {
    ::bigchunk_free((void *) p);
  }
};

#endif // __cplusplus
#endif // BIGCHUNK_H

