add doxygen docs and convert MyPage template class from header only to header plus implementation
This commit is contained in:
@ -410,24 +410,27 @@ WARN_LOGFILE = "../doxygen-warn.log"
|
|||||||
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
|
||||||
# Note: If this tag is empty the current directory is searched.
|
# Note: If this tag is empty the current directory is searched.
|
||||||
|
|
||||||
INPUT = @LAMMPS_SOURCE_DIR@/utils.cpp \
|
INPUT = @LAMMPS_SOURCE_DIR@/utils.cpp \
|
||||||
@LAMMPS_SOURCE_DIR@/utils.h \
|
@LAMMPS_SOURCE_DIR@/utils.h \
|
||||||
@LAMMPS_SOURCE_DIR@/library.cpp \
|
@LAMMPS_SOURCE_DIR@/library.cpp \
|
||||||
@LAMMPS_SOURCE_DIR@/library.h \
|
@LAMMPS_SOURCE_DIR@/library.h \
|
||||||
@LAMMPS_SOURCE_DIR@/lammps.cpp \
|
@LAMMPS_SOURCE_DIR@/lammps.cpp \
|
||||||
@LAMMPS_SOURCE_DIR@/lammps.h \
|
@LAMMPS_SOURCE_DIR@/lammps.h \
|
||||||
@LAMMPS_SOURCE_DIR@/lmptype.h \
|
@LAMMPS_SOURCE_DIR@/lmptype.h \
|
||||||
@LAMMPS_SOURCE_DIR@/pointers.h \
|
@LAMMPS_SOURCE_DIR@/pointers.h \
|
||||||
@LAMMPS_SOURCE_DIR@/atom.cpp \
|
@LAMMPS_SOURCE_DIR@/atom.cpp \
|
||||||
@LAMMPS_SOURCE_DIR@/atom.h \
|
@LAMMPS_SOURCE_DIR@/atom.h \
|
||||||
@LAMMPS_SOURCE_DIR@/input.cpp \
|
@LAMMPS_SOURCE_DIR@/input.cpp \
|
||||||
@LAMMPS_SOURCE_DIR@/input.h \
|
@LAMMPS_SOURCE_DIR@/input.h \
|
||||||
@LAMMPS_SOURCE_DIR@/tokenizer.cpp \
|
@LAMMPS_SOURCE_DIR@/tokenizer.cpp \
|
||||||
@LAMMPS_SOURCE_DIR@/tokenizer.h \
|
@LAMMPS_SOURCE_DIR@/tokenizer.h \
|
||||||
@LAMMPS_SOURCE_DIR@/text_file_reader.cpp \
|
@LAMMPS_SOURCE_DIR@/text_file_reader.cpp \
|
||||||
@LAMMPS_SOURCE_DIR@/text_file_reader.h \
|
@LAMMPS_SOURCE_DIR@/text_file_reader.h \
|
||||||
@LAMMPS_SOURCE_DIR@/potential_file_reader.cpp \
|
@LAMMPS_SOURCE_DIR@/potential_file_reader.cpp \
|
||||||
@LAMMPS_SOURCE_DIR@/potential_file_reader.h \
|
@LAMMPS_SOURCE_DIR@/potential_file_reader.h \
|
||||||
|
@LAMMPS_SOURCE_DIR@/my_page.cpp \
|
||||||
|
@LAMMPS_SOURCE_DIR@/my_page.h \
|
||||||
|
@LAMMPS_SOURCE_DIR@/my_pool_chunk.h \
|
||||||
|
|
||||||
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
|
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
|
||||||
# directories that are symbolic links (a Unix file system feature) are excluded
|
# directories that are symbolic links (a Unix file system feature) are excluded
|
||||||
|
|||||||
@ -53,7 +53,7 @@ command, e.g. ``src/force.cpp`` and the :cpp:class:`LAMMPS_NS::Force`
|
|||||||
class. They are discussed in the next section.
|
class. They are discussed in the next section.
|
||||||
|
|
||||||
A small number of C++ classes and utility functions are implemented with
|
A small number of C++ classes and utility functions are implemented with
|
||||||
only a ``.h`` file. Examples are the Pointer class and the mergesort function.
|
only a ``.h`` file. Examples are the Pointer class or the MyPool class.
|
||||||
|
|
||||||
LAMMPS class topology
|
LAMMPS class topology
|
||||||
=====================
|
=====================
|
||||||
@ -1102,3 +1102,12 @@ A file that would be parsed by the reader code fragment looks like this:
|
|||||||
:project: progguide
|
:project: progguide
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
|
|
||||||
|
----------
|
||||||
|
|
||||||
|
Memory pool classes
|
||||||
|
===================
|
||||||
|
|
||||||
|
.. doxygenclass:: LAMMPS_NS::MyPage
|
||||||
|
:project: progguide
|
||||||
|
:members:
|
||||||
|
|||||||
@ -1975,6 +1975,7 @@ MxN
|
|||||||
myCompute
|
myCompute
|
||||||
myIndex
|
myIndex
|
||||||
mylammps
|
mylammps
|
||||||
|
MyPool
|
||||||
mysocket
|
mysocket
|
||||||
myTemp
|
myTemp
|
||||||
myVec
|
myVec
|
||||||
|
|||||||
267
src/my_page.cpp
Normal file
267
src/my_page.cpp
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
/* -*- c++ -*- ----------------------------------------------------------
|
||||||
|
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
|
||||||
|
http://lammps.sandia.gov, Sandia National Laboratories
|
||||||
|
Steve Plimpton, sjplimp@sandia.gov
|
||||||
|
|
||||||
|
Copyright (2003) Sandia Corporation. Under the terms of Contract
|
||||||
|
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
|
||||||
|
certain rights in this software. This software is distributed under
|
||||||
|
the GNU General Public License.
|
||||||
|
|
||||||
|
See the README file in the top-level LAMMPS directory.
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
usage:
|
||||||
|
request one datum at a time, repeat, clear
|
||||||
|
request chunks of datums in each get() or vget(), repeat, clear
|
||||||
|
chunk size can vary from request to request
|
||||||
|
chunk size can be known in advance or registered after usage via vgot()
|
||||||
|
inputs:
|
||||||
|
template T = one datum, e.g. int, double, struct, int[3]
|
||||||
|
for int[3], access datum as ivec[i][2]
|
||||||
|
methods:
|
||||||
|
T *get() = return ptr to one datum
|
||||||
|
T *get(N) = return ptr to N datums, N < maxchunk required
|
||||||
|
T *vget() = return ptr to maxchunk datums, use as needed, then call vgot()
|
||||||
|
all gets return NULL if error encountered
|
||||||
|
vgot(N) = used N datums of previous vget(), N < maxchunk required
|
||||||
|
void init(maxchunk, pagesize, pagedelta)
|
||||||
|
define allocation params and allocate first page(s)
|
||||||
|
call right after constructor
|
||||||
|
can call again to reset allocation params and free previous pages
|
||||||
|
maxchunk = max # of datums in one chunk, default = 1
|
||||||
|
pagesize = # of datums in one page, default = 1024
|
||||||
|
should be big enough to store multiple chunks
|
||||||
|
pagedelta = # of pages to allocate at a time, default = 1
|
||||||
|
return 1 if bad params
|
||||||
|
void reset() = clear pages w/out freeing
|
||||||
|
int size() = return total size of allocated pages in bytes
|
||||||
|
int status() = return error status
|
||||||
|
0 = ok, 1 = chunksize > maxchunk, 2 = allocation error
|
||||||
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include "my_page.h"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#if defined(LMP_USER_INTEL) && !defined(LAMMPS_MEMALIGN) && !defined(_WIN32)
|
||||||
|
#define LAMMPS_MEMALIGN 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using namespace LAMMPS_NS;
|
||||||
|
|
||||||
|
/** \class LAMMPS_NS::MyPage
|
||||||
|
* \brief Templated class for storing chunks of datums in pages.
|
||||||
|
*
|
||||||
|
* The chunks are not returnable (i.e. cannot be freed individually).
|
||||||
|
* One can only reset and start over. The purpose of this
|
||||||
|
* class is to replace many small mallocs with a few large
|
||||||
|
* mallocs. Since the pages are never freed, they can be re-used
|
||||||
|
* without having to re-allocate them.
|
||||||
|
*
|
||||||
|
* The settings *maxchunk*, *pagesize*, and *pagedelta* contol
|
||||||
|
* the memory allocation strategy. The *maxchunk* value represents
|
||||||
|
* the expected largest number of items per chunk. If there is
|
||||||
|
* less space left on the current page, a new page is allocated
|
||||||
|
* for the next chunk. The *pagesize* value represents how many
|
||||||
|
* items can fit on a single page. It should have space for multiple
|
||||||
|
* chunks of size *maxchunk*. The combination of these two
|
||||||
|
* parameters determines how much memory is wasted by either switching
|
||||||
|
* to the next page too soon or allocating too large pages that never
|
||||||
|
* get properly used. It is an error, if a requested chunk is larger
|
||||||
|
* than *maxchunk*. The *pagedelta* parameter determines how many
|
||||||
|
* pages are allocated in one go. In combination with the *pagesize*
|
||||||
|
* setting, this determines how often blocks of memory get allocated
|
||||||
|
* (fewer allocations will result in faster execution).
|
||||||
|
*
|
||||||
|
* This class is the "workhorse" for the memory management of
|
||||||
|
* neighbor lists. */
|
||||||
|
|
||||||
|
/** Create a class instance
|
||||||
|
*
|
||||||
|
* Need to call init() before use to define allocation settings */
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
MyPage<T>::MyPage() : ndatum(0), nchunk(0), pages(nullptr), page(nullptr),
|
||||||
|
npage(0), ipage(-1), index(-1), maxchunk(-1),
|
||||||
|
pagesize(-1), pagedelta(1), errorflag(0) {};
|
||||||
|
|
||||||
|
/** Free all allocated pages of this class instance */
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
MyPage<T>::~MyPage() {
|
||||||
|
for (int i = 0; i < npage; i++) free(pages[i]);
|
||||||
|
free(pages);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** (Re-)initialize the set of pages and allocation parameters.
|
||||||
|
*
|
||||||
|
* This also frees all previously allocated storage and allocates
|
||||||
|
* the first page(s).
|
||||||
|
*
|
||||||
|
* \param user_maxchunk Expected maximum number of items for one chunk
|
||||||
|
* \param user_pagesize Number of items on a single memory page
|
||||||
|
* \param user_page_delta Number of pages to allocate with one malloc
|
||||||
|
* \return 1 if there was an error or 0 if successful */
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
int MyPage<T>::init(int user_maxchunk, int user_pagesize,
|
||||||
|
int user_pagedelta) {
|
||||||
|
maxchunk = user_maxchunk;
|
||||||
|
pagesize = user_pagesize;
|
||||||
|
pagedelta = user_pagedelta;
|
||||||
|
|
||||||
|
if (maxchunk <= 0 || pagesize <= 0 || pagedelta <= 0) return 1;
|
||||||
|
if (maxchunk > pagesize) return 1;
|
||||||
|
|
||||||
|
// free any previously allocated pages
|
||||||
|
|
||||||
|
for (int i = 0; i < npage; i++) free(pages[i]);
|
||||||
|
free(pages);
|
||||||
|
|
||||||
|
// initial page allocation
|
||||||
|
|
||||||
|
ndatum = nchunk = 0;
|
||||||
|
pages = NULL;
|
||||||
|
npage = 0;
|
||||||
|
allocate();
|
||||||
|
if (errorflag) return 2;
|
||||||
|
ipage = index = 0;
|
||||||
|
page = pages[ipage];
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Pointer to location that can store one item.
|
||||||
|
*
|
||||||
|
* This will allocate more pages as needed.
|
||||||
|
*
|
||||||
|
* \return memory location or null pointer, if memory allocation failed */
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T *MyPage<T>::get() {
|
||||||
|
ndatum++;
|
||||||
|
nchunk++;
|
||||||
|
if (index < pagesize) return &page[index++];
|
||||||
|
ipage++;
|
||||||
|
if (ipage == npage) {
|
||||||
|
allocate();
|
||||||
|
if (errorflag) return NULL;
|
||||||
|
}
|
||||||
|
page = pages[ipage];
|
||||||
|
index = 0;
|
||||||
|
return &page[index++];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Pointer to location that can store N items.
|
||||||
|
*
|
||||||
|
* This will allocate more pages as needed.
|
||||||
|
* If the parameter *N* is larger than the *maxchunk*
|
||||||
|
* setting an error is flagged.
|
||||||
|
*
|
||||||
|
* \param n number of items for which storage is requested
|
||||||
|
* \return memory location or null pointer, if error or allocation failed */
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T *MyPage<T>::get(int n) {
|
||||||
|
if (n > maxchunk) {
|
||||||
|
errorflag = 1;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ndatum += n;
|
||||||
|
nchunk++;
|
||||||
|
if (index+n <= pagesize) {
|
||||||
|
int start = index;
|
||||||
|
index += n;
|
||||||
|
return &page[start];
|
||||||
|
}
|
||||||
|
ipage++;
|
||||||
|
if (ipage == npage) {
|
||||||
|
allocate();
|
||||||
|
if (errorflag) return NULL;
|
||||||
|
}
|
||||||
|
page = pages[ipage];
|
||||||
|
index = n;
|
||||||
|
return &page[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get pointer to location that can store *maxchunk* items.
|
||||||
|
*
|
||||||
|
* This will return the same pointer as the previous call to
|
||||||
|
* this function unless vgot() is called afterwards to record
|
||||||
|
* how many items of the chunk were actually used.
|
||||||
|
*
|
||||||
|
* \return pointer to chunk of memory or null pointer if run out of memory */
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T *MyPage<T>::vget() {
|
||||||
|
if (index+maxchunk <= pagesize) return &page[index];
|
||||||
|
ipage++;
|
||||||
|
if (ipage == npage) {
|
||||||
|
allocate();
|
||||||
|
if (errorflag) return NULL;
|
||||||
|
}
|
||||||
|
page = pages[ipage];
|
||||||
|
index = 0;
|
||||||
|
return &page[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Mark *N* items as used of the chunk reserved with a preceding call to vget().
|
||||||
|
*
|
||||||
|
* This will advance the internal pointer inside the current memory page.
|
||||||
|
* It is not necessary to call this function for *N* = 0, that is the reserved
|
||||||
|
* storage was not used. A following call to vget() will then reserve the
|
||||||
|
* same location again. It is an error if *N* > *maxchunk*.
|
||||||
|
*
|
||||||
|
* \param n Number of iterms used in previously reserved chunk */
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void MyPage<T>::vgot(int n) {
|
||||||
|
if (n > maxchunk) errorflag = 1;
|
||||||
|
ndatum += n;
|
||||||
|
nchunk++;
|
||||||
|
index += n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Reset state of memory pool without freeing any memory */
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void MyPage<T>::reset() {
|
||||||
|
ndatum = nchunk = 0;
|
||||||
|
index = ipage = 0;
|
||||||
|
page = pages[ipage];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void MyPage<T>::allocate() {
|
||||||
|
npage += pagedelta;
|
||||||
|
pages = (T **) realloc(pages,npage*sizeof(T *));
|
||||||
|
if (!pages) {
|
||||||
|
errorflag = 2;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = npage-pagedelta; i < npage; i++) {
|
||||||
|
#if defined(LAMMPS_MEMALIGN)
|
||||||
|
void *ptr;
|
||||||
|
if (posix_memalign(&ptr, LAMMPS_MEMALIGN, pagesize*sizeof(T)))
|
||||||
|
errorflag = 2;
|
||||||
|
pages[i] = (T *) ptr;
|
||||||
|
#else
|
||||||
|
pages[i] = (T *) malloc(pagesize*sizeof(T));
|
||||||
|
if (!pages[i]) errorflag = 2;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// explicit instantiations
|
||||||
|
#include "REPLICA/fix_hyper_local.h"
|
||||||
|
namespace LAMMPS_NS {
|
||||||
|
template class MyPage<int>;
|
||||||
|
template class MyPage<long>;
|
||||||
|
template class MyPage<long long>;
|
||||||
|
template class MyPage<double>;
|
||||||
|
template class MyPage<FixHyperLocal::OneCoeff>;
|
||||||
|
}
|
||||||
193
src/my_page.h
193
src/my_page.h
@ -12,37 +12,7 @@
|
|||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
MyPage = templated class for storing chunks of datums in pages
|
templated class for storing chunks of datums in pages
|
||||||
chunks are not returnable, can only reset and start over
|
|
||||||
replaces many small mallocs with a few large mallocs
|
|
||||||
pages are never freed, so can reuse w/out reallocs
|
|
||||||
usage:
|
|
||||||
request one datum at a time, repeat, clear
|
|
||||||
request chunks of datums in each get() or vget(), repeat, clear
|
|
||||||
chunk size can vary from request to request
|
|
||||||
chunk size can be known in advance or registered after usage via vgot()
|
|
||||||
inputs:
|
|
||||||
template T = one datum, e.g. int, double, struct, int[3]
|
|
||||||
for int[3], access datum as ivec[i][2]
|
|
||||||
methods:
|
|
||||||
T *get() = return ptr to one datum
|
|
||||||
T *get(N) = return ptr to N datums, N < maxchunk required
|
|
||||||
T *vget() = return ptr to maxchunk datums, use as needed, then call vgot()
|
|
||||||
all gets return NULL if error encountered
|
|
||||||
vgot(N) = used N datums of previous vget(), N < maxchunk required
|
|
||||||
void init(maxchunk, pagesize, pagedelta)
|
|
||||||
define allocation params and allocate first page(s)
|
|
||||||
call right after constructor
|
|
||||||
can call again to reset allocation params and free previous pages
|
|
||||||
maxchunk = max # of datums in one chunk, default = 1
|
|
||||||
pagesize = # of datums in one page, default = 1024
|
|
||||||
should be big enough to store multiple chunks
|
|
||||||
pagedelta = # of pages to allocate at a time, default = 1
|
|
||||||
return 1 if bad params
|
|
||||||
void reset() = clear pages w/out freeing
|
|
||||||
int size() = return total size of allocated pages in bytes
|
|
||||||
int status() = return error status
|
|
||||||
0 = ok, 1 = chunksize > maxchunk, 2 = allocation error
|
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#ifndef LAMMPS_MY_PAGE_H
|
#ifndef LAMMPS_MY_PAGE_H
|
||||||
@ -52,7 +22,6 @@ methods:
|
|||||||
#define LAMMPS_MEMALIGN 64
|
#define LAMMPS_MEMALIGN 64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
namespace LAMMPS_NS {
|
namespace LAMMPS_NS {
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
@ -60,139 +29,33 @@ class MyPage {
|
|||||||
public:
|
public:
|
||||||
int ndatum; // total # of stored datums
|
int ndatum; // total # of stored datums
|
||||||
int nchunk; // total # of stored chunks
|
int nchunk; // total # of stored chunks
|
||||||
|
MyPage();
|
||||||
MyPage() {
|
virtual ~MyPage();
|
||||||
ndatum = nchunk = 0;
|
|
||||||
pages = NULL;
|
|
||||||
npage = 0;
|
|
||||||
errorflag = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// (re)initialize allocation params
|
|
||||||
// also allocate first page(s)
|
|
||||||
|
|
||||||
int init(int user_maxchunk = 1, int user_pagesize = 1024,
|
int init(int user_maxchunk = 1, int user_pagesize = 1024,
|
||||||
int user_pagedelta = 1) {
|
int user_pagedelta = 1);
|
||||||
maxchunk = user_maxchunk;
|
|
||||||
pagesize = user_pagesize;
|
T *get();
|
||||||
pagedelta = user_pagedelta;
|
T *get(int n);
|
||||||
|
|
||||||
if (maxchunk <= 0 || pagesize <= 0 || pagedelta <= 0) return 1;
|
T *vget();
|
||||||
if (maxchunk > pagesize) return 1;
|
void vgot(int n);
|
||||||
|
|
||||||
// free any previously allocated pages
|
void reset();
|
||||||
|
|
||||||
for (int i = 0; i < npage; i++) free(pages[i]);
|
/** Return total size of allocated pages
|
||||||
free(pages);
|
*
|
||||||
|
* \return total storage used in bytes */
|
||||||
// initial page allocation
|
|
||||||
|
|
||||||
ndatum = nchunk = 0;
|
|
||||||
pages = NULL;
|
|
||||||
npage = 0;
|
|
||||||
allocate();
|
|
||||||
if (errorflag) return 2;
|
|
||||||
ipage = index = 0;
|
|
||||||
page = pages[ipage];
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// free all allocated pages
|
|
||||||
|
|
||||||
~MyPage() {
|
|
||||||
for (int i = 0; i < npage; i++) free(pages[i]);
|
|
||||||
free(pages);
|
|
||||||
}
|
|
||||||
|
|
||||||
// get ptr to one datum
|
|
||||||
// return NULL if run out of memory
|
|
||||||
|
|
||||||
T *get() {
|
|
||||||
ndatum++;
|
|
||||||
nchunk++;
|
|
||||||
if (index < pagesize) return &page[index++];
|
|
||||||
ipage++;
|
|
||||||
if (ipage == npage) {
|
|
||||||
allocate();
|
|
||||||
if (errorflag) return NULL;
|
|
||||||
}
|
|
||||||
page = pages[ipage];
|
|
||||||
index = 0;
|
|
||||||
return &page[index++];
|
|
||||||
}
|
|
||||||
|
|
||||||
// get ptr to location that can store N datums
|
|
||||||
// error if N > maxchunk
|
|
||||||
// return NULL if run out of memory
|
|
||||||
|
|
||||||
T *get(int n) {
|
|
||||||
if (n > maxchunk) {
|
|
||||||
errorflag = 1;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
ndatum += n;
|
|
||||||
nchunk++;
|
|
||||||
if (index+n <= pagesize) {
|
|
||||||
int start = index;
|
|
||||||
index += n;
|
|
||||||
return &page[start];
|
|
||||||
}
|
|
||||||
ipage++;
|
|
||||||
if (ipage == npage) {
|
|
||||||
allocate();
|
|
||||||
if (errorflag) return NULL;
|
|
||||||
}
|
|
||||||
page = pages[ipage];
|
|
||||||
index = n;
|
|
||||||
return &page[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
// get ptr to location that can store maxchunk datums
|
|
||||||
// will return same ptr as previous call if vgot() not called
|
|
||||||
// return NULL if run out of memory
|
|
||||||
|
|
||||||
T *vget() {
|
|
||||||
if (index+maxchunk <= pagesize) return &page[index];
|
|
||||||
ipage++;
|
|
||||||
if (ipage == npage) {
|
|
||||||
allocate();
|
|
||||||
if (errorflag) return NULL;
|
|
||||||
}
|
|
||||||
page = pages[ipage];
|
|
||||||
index = 0;
|
|
||||||
return &page[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
// increment by N = # of values stored in loc returned by vget()
|
|
||||||
// OK to not call if vget() ptr was not used
|
|
||||||
// error if N > maxchunk
|
|
||||||
|
|
||||||
void vgot(int n) {
|
|
||||||
if (n > maxchunk) errorflag = 1;
|
|
||||||
ndatum += n;
|
|
||||||
nchunk++;
|
|
||||||
index += n;
|
|
||||||
}
|
|
||||||
|
|
||||||
// clear all pages, without freeing any memory
|
|
||||||
|
|
||||||
void reset() {
|
|
||||||
ndatum = nchunk = 0;
|
|
||||||
index = ipage = 0;
|
|
||||||
page = pages[ipage];
|
|
||||||
}
|
|
||||||
|
|
||||||
// return total size of allocated pages
|
|
||||||
|
|
||||||
int size() const {
|
int size() const {
|
||||||
return npage*pagesize*sizeof(T);
|
return npage*pagesize*sizeof(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
// return error status
|
/** Return error status
|
||||||
|
*
|
||||||
|
* \return 0 if no error, 1 requested chunk size > maxchunk, 2 if malloc failed */
|
||||||
|
|
||||||
int status() const {
|
int status() const { return errorflag; }
|
||||||
return errorflag;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T **pages; // list of allocated pages
|
T **pages; // list of allocated pages
|
||||||
@ -208,27 +71,7 @@ class MyPage {
|
|||||||
int errorflag; // flag > 0 if error has occurred
|
int errorflag; // flag > 0 if error has occurred
|
||||||
// 1 = chunk size exceeded maxchunk
|
// 1 = chunk size exceeded maxchunk
|
||||||
// 2 = memory allocation error
|
// 2 = memory allocation error
|
||||||
|
void allocate();
|
||||||
void allocate() {
|
|
||||||
npage += pagedelta;
|
|
||||||
pages = (T **) realloc(pages,npage*sizeof(T *));
|
|
||||||
if (!pages) {
|
|
||||||
errorflag = 2;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = npage-pagedelta; i < npage; i++) {
|
|
||||||
#if defined(LAMMPS_MEMALIGN)
|
|
||||||
void *ptr;
|
|
||||||
if (posix_memalign(&ptr, LAMMPS_MEMALIGN, pagesize*sizeof(T)))
|
|
||||||
errorflag = 2;
|
|
||||||
pages[i] = (T *) ptr;
|
|
||||||
#else
|
|
||||||
pages[i] = (T *) malloc(pagesize*sizeof(T));
|
|
||||||
if (!pages[i]) errorflag = 2;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user