Rename mj_stackAllocByte to mj_stackAlloc and make it public.
PiperOrigin-RevId: 561133040 Change-Id: I4f5ffe51c1287aa0c82af68bfe17ed6dd2ad09da
This commit is contained in:
committed by
Copybara-Service
parent
a48e0aa355
commit
4c899b92cc
@@ -1232,6 +1232,15 @@ mj_resetDataKeyframe
|
|||||||
|
|
||||||
Reset data, set fields from specified keyframe.
|
Reset data, set fields from specified keyframe.
|
||||||
|
|
||||||
|
.. _mj_stackAlloc:
|
||||||
|
|
||||||
|
mj_stackAlloc
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
.. mujoco-include:: mj_stackAlloc
|
||||||
|
|
||||||
|
Allocate a specific number of bytes on :ref:`mjData` stack. Call mju_error on stack overflow.
|
||||||
|
|
||||||
.. _mj_stackAllocNum:
|
.. _mj_stackAllocNum:
|
||||||
|
|
||||||
mj_stackAllocNum
|
mj_stackAllocNum
|
||||||
|
|||||||
+6
-4
@@ -38,20 +38,22 @@ General
|
|||||||
Euler integrator. See the :ref:`Numerical Integration<geIntegration>` section for more details.
|
Euler integrator. See the :ref:`Numerical Integration<geIntegration>` section for more details.
|
||||||
#. Added the flag :ref:`invdiscrete<option-flag-invdiscrete>`, which enables discrete-time inverse dynamics for all
|
#. Added the flag :ref:`invdiscrete<option-flag-invdiscrete>`, which enables discrete-time inverse dynamics for all
|
||||||
:ref:`integrators<option-integrator>` other than ``RK4``. See the flag documentation for more details.
|
:ref:`integrators<option-integrator>` other than ``RK4``. See the flag documentation for more details.
|
||||||
#. Renamed the function ``mj_stackAlloc`` to ``mj_stackAllocNum``.
|
#. Changed the function ``mj_stackAlloc`` to allocate an arbitrary number of bytes, rather than in multiples of
|
||||||
|
``sizeof(mjtNum)``, and add an additional argument for specifying the alignment of the returned pointer. The existing
|
||||||
|
functionality of allocating ``mjtNum`` arrays is still available through the new function ``mj_stackAllocNum``.
|
||||||
#. Renamed the ``nstack`` field in ``mjModel`` and ``mjData`` to ``narena``. Changed ``narena``, ``pstack``, and
|
#. Renamed the ``nstack`` field in ``mjModel`` and ``mjData`` to ``narena``. Changed ``narena``, ``pstack``, and
|
||||||
``maxuse_stack`` to count number of bytes rather than number of ``mjtNum``s.
|
``maxuse_stack`` to count number of bytes rather than number of ``mjtNum``s.
|
||||||
|
|
||||||
Python bindings
|
Python bindings
|
||||||
^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
9. Fixed `#870 <https://github.com/deepmind/mujoco/issues/870>`__ where calling ``update_scene`` with an invalid
|
10. Fixed `#870 <https://github.com/deepmind/mujoco/issues/870>`__ where calling ``update_scene`` with an invalid
|
||||||
camera name used the default camera.
|
camera name used the default camera.
|
||||||
|
|
||||||
Bug fixes
|
Bug fixes
|
||||||
^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
|
||||||
10. Fixed a bug that was causing the geom margins to be ignored during the midphase.
|
11. Fixed a bug that was causing the geom margins to be ignored during the midphase.
|
||||||
|
|
||||||
|
|
||||||
Version 2.3.7 (July 20, 2023)
|
Version 2.3.7 (July 20, 2023)
|
||||||
|
|||||||
@@ -2213,6 +2213,7 @@ mjData* mj_copyData(mjData* dest, const mjModel* m, const mjData* src);
|
|||||||
void mj_resetData(const mjModel* m, mjData* d);
|
void mj_resetData(const mjModel* m, mjData* d);
|
||||||
void mj_resetDataDebug(const mjModel* m, mjData* d, unsigned char debug_value);
|
void mj_resetDataDebug(const mjModel* m, mjData* d, unsigned char debug_value);
|
||||||
void mj_resetDataKeyframe(const mjModel* m, mjData* d, int key);
|
void mj_resetDataKeyframe(const mjModel* m, mjData* d, int key);
|
||||||
|
void* mj_stackAlloc(mjData* d, size_t bytes, size_t alignment);
|
||||||
mjtNum* mj_stackAllocNum(mjData* d, int size);
|
mjtNum* mj_stackAllocNum(mjData* d, int size);
|
||||||
int* mj_stackAllocInt(mjData* d, int size);
|
int* mj_stackAllocInt(mjData* d, int size);
|
||||||
void mj_deleteData(mjData* d);
|
void mj_deleteData(mjData* d);
|
||||||
|
|||||||
@@ -722,9 +722,8 @@ the scope. If not, saving and restoring the stack pointer should be done manuall
|
|||||||
The function :ref:`mj_stackAllocNum` checks if there is enough space, and if so it advances the stack pointer,
|
The function :ref:`mj_stackAllocNum` checks if there is enough space, and if so it advances the stack pointer,
|
||||||
otherwise it triggers an error. It also keeps track of the maximum stack allocation;
|
otherwise it triggers an error. It also keeps track of the maximum stack allocation;
|
||||||
see :ref:`diagnostics <siDiagnostics>` below. Note that :ref:`mj_stackAllocNum` is only used for allocating
|
see :ref:`diagnostics <siDiagnostics>` below. Note that :ref:`mj_stackAllocNum` is only used for allocating
|
||||||
``mjtNum`` arrays, the most common type of array. :ref:`mj_stackAllocInt` is provided for integer array allocation.
|
``mjtNum`` arrays, the most common type of array. :ref:`mj_stackAllocInt` is provided for integer array allocation,
|
||||||
Allocators for other types are also possible, as in
|
and :ref:`mj_stackAlloc` is provided for allocation of arbitrary number of bytes and alignment.
|
||||||
`engine_collision_driver.c <https://github.com/deepmind/mujoco/blob/main/src/engine/engine_collision_driver.c>`__.
|
|
||||||
|
|
||||||
.. _siError:
|
.. _siError:
|
||||||
|
|
||||||
|
|||||||
@@ -188,6 +188,9 @@ MJAPI void mj_resetDataDebug(const mjModel* m, mjData* d, unsigned char debug_va
|
|||||||
// Reset data, set fields from specified keyframe.
|
// Reset data, set fields from specified keyframe.
|
||||||
MJAPI void mj_resetDataKeyframe(const mjModel* m, mjData* d, int key);
|
MJAPI void mj_resetDataKeyframe(const mjModel* m, mjData* d, int key);
|
||||||
|
|
||||||
|
// Allocate a specific number of bytes on mjData stack. Call mju_error on stack overflow.
|
||||||
|
MJAPI void* mj_stackAlloc(mjData* d, size_t bytes, size_t alignment);
|
||||||
|
|
||||||
// Allocate array of mjtNums on mjData stack. Call mju_error on stack overflow.
|
// Allocate array of mjtNums on mjData stack. Call mju_error on stack overflow.
|
||||||
MJAPI mjtNum* mj_stackAllocNum(mjData* d, int size);
|
MJAPI mjtNum* mj_stackAllocNum(mjData* d, int size);
|
||||||
|
|
||||||
|
|||||||
@@ -677,6 +677,30 @@ FUNCTIONS: Mapping[str, FunctionDecl] = dict([
|
|||||||
),
|
),
|
||||||
doc='Reset data, set fields from specified keyframe.',
|
doc='Reset data, set fields from specified keyframe.',
|
||||||
)),
|
)),
|
||||||
|
('mj_stackAlloc',
|
||||||
|
FunctionDecl(
|
||||||
|
name='mj_stackAlloc',
|
||||||
|
return_type=PointerType(
|
||||||
|
inner_type=ValueType(name='void'),
|
||||||
|
),
|
||||||
|
parameters=(
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='d',
|
||||||
|
type=PointerType(
|
||||||
|
inner_type=ValueType(name='mjData'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='bytes',
|
||||||
|
type=ValueType(name='size_t'),
|
||||||
|
),
|
||||||
|
FunctionParameterDecl(
|
||||||
|
name='alignment',
|
||||||
|
type=ValueType(name='size_t'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
doc='Allocate a specific number of bytes on mjData stack. Call mju_error on stack overflow.', # pylint: disable=line-too-long
|
||||||
|
)),
|
||||||
('mj_stackAllocNum',
|
('mj_stackAllocNum',
|
||||||
FunctionDecl(
|
FunctionDecl(
|
||||||
name='mj_stackAllocNum',
|
name='mj_stackAllocNum',
|
||||||
|
|||||||
@@ -948,7 +948,7 @@ Euler integrator, semi-implicit in velocity.
|
|||||||
def test_can_raise_error(self):
|
def test_can_raise_error(self):
|
||||||
self.data.pstack = self.data.narena
|
self.data.pstack = self.data.narena
|
||||||
with self.assertRaisesRegex(mujoco.FatalError,
|
with self.assertRaisesRegex(mujoco.FatalError,
|
||||||
r'\Amj_stackAllocByte: stack overflow'):
|
r'\AmjData stack overflow'):
|
||||||
mujoco.mj_forward(self.model, self.data)
|
mujoco.mj_forward(self.model, self.data)
|
||||||
|
|
||||||
def test_mjcb_time(self):
|
def test_mjcb_time(self):
|
||||||
|
|||||||
@@ -208,7 +208,8 @@ int mj_collideOBB(const mjtNum aabb1[6], const mjtNum aabb2[6],
|
|||||||
}
|
}
|
||||||
|
|
||||||
static mjCollisionTree* mj_stackAllocTree(mjData* d, int max_stack) {
|
static mjCollisionTree* mj_stackAllocTree(mjData* d, int max_stack) {
|
||||||
return (mjCollisionTree*)mj_stackAllocByte(d, max_stack * sizeof(mjCollisionTree*));
|
return (mjCollisionTree*) mj_stackAlloc(
|
||||||
|
d, max_stack * sizeof(mjCollisionTree), _Alignof(mjCollisionTree));
|
||||||
}
|
}
|
||||||
|
|
||||||
// binary search between two body trees
|
// binary search between two body trees
|
||||||
@@ -751,8 +752,10 @@ int mj_broadphase(const mjModel* m, mjData* d, int* pair, int maxpair) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// allocate sort buffer
|
// allocate sort buffer
|
||||||
sortbuf = (mjtBroadphase*)mj_stackAllocByte(d, 2 * bufcnt * sizeof(mjtBroadphase));
|
sortbuf = (mjtBroadphase*) mj_stackAlloc(
|
||||||
activebuf = (mjtBroadphase*)mj_stackAllocByte(d, 2 *bufcnt * sizeof(mjtBroadphase));
|
d, 2 * bufcnt * sizeof(mjtBroadphase), _Alignof(mjtBroadphase));
|
||||||
|
activebuf = (mjtBroadphase*) mj_stackAlloc(
|
||||||
|
d, 2 * bufcnt * sizeof(mjtBroadphase), _Alignof(mjtBroadphase));
|
||||||
|
|
||||||
// init sortbuf with axis0
|
// init sortbuf with axis0
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
|||||||
@@ -21,19 +21,10 @@
|
|||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#elif !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L
|
|
||||||
// No C11 support in Visual Studio 2019 update 7 and earlier.
|
|
||||||
// However, MSVC allows C++ alignas to be used in C code, so
|
|
||||||
// we can just skip the #include <stdalign.h>.
|
|
||||||
#ifndef _MSC_VER
|
|
||||||
#error "Compiler does not support C11."
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#include <stdalign.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct mjCollisionTree_ {
|
struct mjCollisionTree_ {
|
||||||
alignas(mjtNum) int node1;
|
int node1;
|
||||||
int node2;
|
int node2;
|
||||||
};
|
};
|
||||||
typedef struct mjCollisionTree_ mjCollisionTree;
|
typedef struct mjCollisionTree_ mjCollisionTree;
|
||||||
|
|||||||
@@ -456,8 +456,8 @@ static void collideBVH(const mjModel* m, mjData* d, int g,
|
|||||||
int node;
|
int node;
|
||||||
};
|
};
|
||||||
typedef struct CollideTreeArgs_ CollideTreeArgs;
|
typedef struct CollideTreeArgs_ CollideTreeArgs;
|
||||||
CollideTreeArgs* stack = (CollideTreeArgs*) mj_stackAllocByte(
|
CollideTreeArgs* stack = (CollideTreeArgs*) mj_stackAlloc(
|
||||||
d, max_stack * sizeof(CollideTreeArgs));
|
d, max_stack * sizeof(CollideTreeArgs), _Alignof(CollideTreeArgs));
|
||||||
|
|
||||||
int nstack = 0;
|
int nstack = 0;
|
||||||
stack[nstack].node = 0;
|
stack[nstack].node = 0;
|
||||||
|
|||||||
@@ -64,7 +64,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(__clang__) && !defined(__cplusplus)
|
#if defined(_MSC_VER) && !defined(__clang__) && !defined(__cplusplus)
|
||||||
typedef long double max_align_t;
|
typedef long double mjtMaxAlign;
|
||||||
|
#else
|
||||||
|
typedef max_align_t mjtMaxAlign;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // MUJOCO_SRC_ENGINE_ENGINE_CROSSPLATFORM_H_
|
#endif // MUJOCO_SRC_ENGINE_ENGINE_CROSSPLATFORM_H_
|
||||||
|
|||||||
+15
-11
@@ -27,7 +27,6 @@
|
|||||||
#include <mujoco/mjplugin.h>
|
#include <mujoco/mjplugin.h>
|
||||||
#include <mujoco/mjxmacro.h>
|
#include <mujoco/mjxmacro.h>
|
||||||
#include "engine/engine_array_safety.h" // IWYU pragma: keep
|
#include "engine/engine_array_safety.h" // IWYU pragma: keep
|
||||||
#include "engine/engine_crossplatform.h" // IWYU pragma: keep
|
|
||||||
#include "engine/engine_resource.h"
|
#include "engine/engine_resource.h"
|
||||||
#include "engine/engine_macro.h"
|
#include "engine/engine_macro.h"
|
||||||
#include "engine/engine_plugin.h"
|
#include "engine/engine_plugin.h"
|
||||||
@@ -1200,9 +1199,9 @@ mjData* mj_copyData(mjData* dest, const mjModel* m, const mjData* src) {
|
|||||||
|
|
||||||
|
|
||||||
// allocate memory from the mjData arena
|
// allocate memory from the mjData arena
|
||||||
void* mj_arenaAlloc(mjData* d, int bytes, int alignment) {
|
void* mj_arenaAlloc(mjData* d, size_t bytes, size_t alignment) {
|
||||||
int misalignment = d->parena % alignment;
|
size_t misalignment = d->parena % alignment;
|
||||||
int padding = misalignment ? alignment - misalignment : 0;
|
size_t padding = misalignment ? alignment - misalignment : 0;
|
||||||
|
|
||||||
// check size
|
// check size
|
||||||
size_t bytes_available = d->narena - d->pstack;
|
size_t bytes_available = d->narena - d->pstack;
|
||||||
@@ -1228,8 +1227,9 @@ void* mj_arenaAlloc(mjData* d, int bytes, int alignment) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// allocate size bytes on the mjData stack
|
// internal: allocate size bytes on the mjData stack
|
||||||
void* mj_stackAllocByte(mjData* d, size_t size) {
|
// declared inline so that modular arithmetic with specific alignments can be optimized out
|
||||||
|
static inline void* stackalloc(mjData* d, size_t size, size_t alignment) {
|
||||||
// return NULL if empty
|
// return NULL if empty
|
||||||
if (!size) {
|
if (!size) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1254,8 +1254,8 @@ void* mj_stackAllocByte(mjData* d, size_t size) {
|
|||||||
// start of the memory to be allocated to the buffer
|
// start of the memory to be allocated to the buffer
|
||||||
uintptr_t start_ptr = end_ptr - (size + mjREDZONE);
|
uintptr_t start_ptr = end_ptr - (size + mjREDZONE);
|
||||||
|
|
||||||
// move start_ptr back to align to max_align_t
|
// align the pointer
|
||||||
start_ptr -= start_ptr % _Alignof(max_align_t); // NOLINT
|
start_ptr -= start_ptr % alignment;
|
||||||
|
|
||||||
// new top of the stack
|
// new top of the stack
|
||||||
uintptr_t new_pstack_ptr = start_ptr - mjREDZONE;
|
uintptr_t new_pstack_ptr = start_ptr - mjREDZONE;
|
||||||
@@ -1269,7 +1269,7 @@ void* mj_stackAllocByte(mjData* d, size_t size) {
|
|||||||
size_t stack_available_bytes = end_ptr - ((uintptr_t)d->arena + d->parena);
|
size_t stack_available_bytes = end_ptr - ((uintptr_t)d->arena + d->parena);
|
||||||
size_t stack_required_bytes = end_ptr - new_pstack_ptr;
|
size_t stack_required_bytes = end_ptr - new_pstack_ptr;
|
||||||
if (stack_required_bytes > stack_available_bytes) {
|
if (stack_required_bytes > stack_available_bytes) {
|
||||||
mjERROR("stack overflow: max = %zu, available = %zu, requested = %zu "
|
mju_error("mjData stack overflow: max = %zu, available = %zu, requested = %zu "
|
||||||
"(ne = %d, nf = %d, nefc = %d, ncon = %d)",
|
"(ne = %d, nf = %d, nefc = %d, ncon = %d)",
|
||||||
stack_size_bytes, stack_available_bytes, stack_required_bytes,
|
stack_size_bytes, stack_available_bytes, stack_required_bytes,
|
||||||
d->ne, d->nf, d->nefc, d->ncon);
|
d->ne, d->nf, d->nefc, d->ncon);
|
||||||
@@ -1303,12 +1303,16 @@ void* mj_stackAllocByte(mjData* d, size_t size) {
|
|||||||
return (void*)start_ptr;
|
return (void*)start_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* mj_stackAlloc(mjData* d, size_t bytes, size_t alignment) {
|
||||||
|
return stackalloc(d, bytes, alignment);
|
||||||
|
}
|
||||||
|
|
||||||
mjtNum* mj_stackAllocNum(mjData* d, int size) {
|
mjtNum* mj_stackAllocNum(mjData* d, int size) {
|
||||||
return (mjtNum*)mj_stackAllocByte(d, size * sizeof(mjtNum));
|
return (mjtNum*) stackalloc(d, size * sizeof(mjtNum), _Alignof(mjtNum));
|
||||||
}
|
}
|
||||||
|
|
||||||
int* mj_stackAllocInt(mjData* d, int size) {
|
int* mj_stackAllocInt(mjData* d, int size) {
|
||||||
return (int*)mj_stackAllocByte(d, size * sizeof(int));
|
return (int*) stackalloc(d, size * sizeof(int), _Alignof(int));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,10 @@
|
|||||||
#include <mujoco/mjmodel.h>
|
#include <mujoco/mjmodel.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
#include <cstddef>
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
#else
|
||||||
|
#include <stddef.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// internal hash map size factor (2 corresponds to a load factor of 0.5)
|
// internal hash map size factor (2 corresponds to a load factor of 0.5)
|
||||||
@@ -100,7 +103,10 @@ MJAPI void mj_resetDataDebug(const mjModel* m, mjData* d, unsigned char debug_va
|
|||||||
MJAPI void mj_resetDataKeyframe(const mjModel* m, mjData* d, int key);
|
MJAPI void mj_resetDataKeyframe(const mjModel* m, mjData* d, int key);
|
||||||
|
|
||||||
// mjData arena allocate
|
// mjData arena allocate
|
||||||
MJAPI void* mj_arenaAlloc(mjData* d, int bytes, int alignment);
|
MJAPI void* mj_arenaAlloc(mjData* d, size_t bytes, size_t alignment);
|
||||||
|
|
||||||
|
// mjData stack allocate
|
||||||
|
MJAPI void* mj_stackAlloc(mjData* d, size_t bytes, size_t alignment);
|
||||||
|
|
||||||
// mjData stack allocate for array of mjtNums
|
// mjData stack allocate for array of mjtNums
|
||||||
MJAPI mjtNum* mj_stackAllocNum(mjData* d, int size);
|
MJAPI mjtNum* mj_stackAllocNum(mjData* d, int size);
|
||||||
@@ -108,9 +114,6 @@ MJAPI mjtNum* mj_stackAllocNum(mjData* d, int size);
|
|||||||
// mjData stack allocate for array of ints
|
// mjData stack allocate for array of ints
|
||||||
MJAPI int* mj_stackAllocInt(mjData* d, int size);
|
MJAPI int* mj_stackAllocInt(mjData* d, int size);
|
||||||
|
|
||||||
// mjData stack allocate for a specific size of bytes
|
|
||||||
MJAPI void* mj_stackAllocByte(mjData* d, size_t size);
|
|
||||||
|
|
||||||
// de-allocate data
|
// de-allocate data
|
||||||
MJAPI void mj_deleteData(mjData* d);
|
MJAPI void mj_deleteData(mjData* d);
|
||||||
|
|
||||||
|
|||||||
@@ -13,16 +13,19 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
#include "engine/engine_util_container.h"
|
#include "engine/engine_util_container.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <mujoco/mujoco.h>
|
#include <mujoco/mujoco.h>
|
||||||
|
#include "engine/engine_crossplatform.h"
|
||||||
#include "engine/engine_io.h"
|
#include "engine/engine_io.h"
|
||||||
|
|
||||||
// stack allocate and initialize new mjArrayList
|
// stack allocate and initialize new mjArrayList
|
||||||
mjArrayList* mju_arrayListCreate(mjData* d, size_t element_size, size_t initial_capacity) {
|
mjArrayList* mju_arrayListCreate(mjData* d, size_t element_size, size_t initial_capacity) {
|
||||||
mjArrayList* array_list = (mjArrayList*) mj_stackAllocByte(d, sizeof(mjArrayList));
|
mjArrayList* array_list = (mjArrayList*) mj_stackAlloc(
|
||||||
|
d, sizeof(mjArrayList), _Alignof(mjArrayList));
|
||||||
initial_capacity = mjMAX(1, initial_capacity);
|
initial_capacity = mjMAX(1, initial_capacity);
|
||||||
array_list->d = d;
|
array_list->d = d;
|
||||||
array_list->element_size = element_size;
|
array_list->element_size = element_size;
|
||||||
@@ -31,7 +34,8 @@ mjArrayList* mju_arrayListCreate(mjData* d, size_t element_size, size_t initial_
|
|||||||
array_list->next_segment = NULL;
|
array_list->next_segment = NULL;
|
||||||
|
|
||||||
// allocate array list buffer
|
// allocate array list buffer
|
||||||
array_list->buffer = (void*) mj_stackAllocByte(d, element_size * initial_capacity);
|
array_list->buffer = (void*) mj_stackAlloc(
|
||||||
|
d, element_size * initial_capacity, _Alignof(mjtMaxAlign));
|
||||||
return array_list;
|
return array_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,12 +33,11 @@ constexpr int GetExpectedStackUsageBytes() {
|
|||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
constexpr auto RoundUpToAlignment =
|
constexpr auto RoundUpToAlignment =
|
||||||
[](int x) {
|
[](int x, int alignment) {
|
||||||
constexpr auto kAlignment = alignof(std::max_align_t);
|
return alignment * (x / alignment + ((x % alignment) ? 1 : 0));
|
||||||
return kAlignment * (x / kAlignment + ((x % kAlignment) ? 1 : 0));
|
|
||||||
};
|
};
|
||||||
return RoundUpToAlignment(sizeof(mjArrayList)) +
|
return RoundUpToAlignment(sizeof(mjArrayList), alignof(mjArrayList)) +
|
||||||
RoundUpToAlignment(Capacity * sizeof(T)) +
|
RoundUpToAlignment(Capacity * sizeof(T), alignof(std::max_align_t)) +
|
||||||
GetExpectedStackUsageBytes<T, N - Capacity, 2 * Capacity>();
|
GetExpectedStackUsageBytes<T, N - Capacity, 2 * Capacity>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3087,6 +3087,9 @@ public static unsafe extern void mj_resetDataDebug(mjModel_* m, mjData_* d, byte
|
|||||||
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static unsafe extern void mj_resetDataKeyframe(mjModel_* m, mjData_* d, int key);
|
public static unsafe extern void mj_resetDataKeyframe(mjModel_* m, mjData_* d, int key);
|
||||||
|
|
||||||
|
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
public static unsafe extern void* mj_stackAlloc(mjData_* d, UIntPtr bytes, UIntPtr alignment);
|
||||||
|
|
||||||
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
|
[DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)]
|
||||||
public static unsafe extern double* mj_stackAllocNum(mjData_* d, int size);
|
public static unsafe extern double* mj_stackAllocNum(mjData_* d, int size);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user