deque, block_size, __add_back_capacity

Hello all,

First, apologizes if this is the wrong mailing list for this discussion.

I am using the TI 18.1.5 compiler to compile for the TM4C1294NCPDT chip. A longer/better explanation of my problems might be obtained from the TI forums of my issue, which didn’t gain traction: https://e2e.ti.com/support/tools/ccs/f/81/t/787948

So I am trying to go upstream for more discussion.

Summary of my problem: Using deque::push_back on structures over 64 bytes will cause a crash.

Example code:

#include

struct s {

char d[65];

};

int main()

{

int size = sizeof(s);

std::deque test;

test.push_back(s());

test.push_back(s()); // will crash here

while (1){}

}

Digging in to the problem more, I found that if I call resize(1) first, push_back will work just fine thereafter. I found there are differences between __add_back_capacity() vs __add_back_capacity(1). Should there be?

Example, look at comments for output result:

#define protected public

#define private public

#include

struct s {

char d[65];

};

int main()

{

{

std::deque test;

test.resize(1, s());

int back_spare = test.__back_spare(); // 0

int cap = test.__capacity(); // 1

}

{

std::deque test;

test.push_back(s());

int back_spare = test.__back_spare(); // -1

int cap = test.__capacity(); // 0

}

{

std::deque test;

test.__add_back_capacity(1);

int back_spare = test.__back_spare(); // 1

int cap = test.__capacity(); // 1

}

{

std::deque test;

test.__add_back_capacity();

int back_spare = test.__back_spare(); // 0

int cap = test.__capacity(); // 0

}

while (1){}

}

TI’s implementation of the struct __deque_block_size allows a minimum size of 1. Not sure if this should cause a problem or not.

TI:

template <class _ValueType, class _DiffType>

struct __deque_block_size {

enum attribute((packed)) { _MAX_BYTES = 32 * sizeof(void*) };

static const _DiffType value = sizeof(_ValueType) < _MAX_BYTES ? (_MAX_BYTES / sizeof(_ValueType)) : 1;

};

So, is this a problem in LLVM’s __add_back_capacity() or TI’s block_size?

Jason

Hello all,

First, apologizes if this is the wrong mailing list for this discussion.

This is not a terrible place.

I am using the TI 18.1.5 compiler to compile for the TM4C1294NCPDT chip. A longer/better explanation of my problems might be obtained from the TI forums of my issue, which didn’t gain traction: https://e2e.ti.com/support/tools/ccs/f/81/t/787948

So I am trying to go upstream for more discussion.

Summary of my problem: Using deque::push_back on structures over 64 bytes will cause a crash.

Example code:

#include

struct s {

char d[65];

};

int main()

{

int size = sizeof(s);

std::deque test;

test.push_back(s());

test.push_back(s()); // will crash here

while (1){}

}

I tried this on my desktop, and it did not crash.
I also turned on address sanitizer to see if there might be an out-of-bounds read or write, but it didn’t report any.

I tried your second program (again, on my desktop), and added some printf statements, and I got:

back_spare cap

61 62
61 62
62 62
62 62

TI’s implementation of the struct __deque_block_size allows a minimum size of 1. Not sure if this should cause a problem or not.

TI:

template <class _ValueType, class _DiffType>

struct __deque_block_size {

enum attribute((packed)) { _MAX_BYTES = 32 * sizeof(void*) };

static const _DiffType value = sizeof(_ValueType) < _MAX_BYTES ? (_MAX_BYTES / sizeof(_ValueType)) : 1;

};

So, is this a problem in LLVM’s __add_back_capacity() or TI’s block_size?

I’m suspecting TI’s block_size.

here’s the one from trunk:

template <class _ValueType, class _DiffType>
struct __deque_block_size {
static const _DiffType value = sizeof(_ValueType) < 256 ? 4096 / sizeof(_ValueType) : 16;
};

Note that it never is smaller than 16.

– Marshall

I recompiled TI’s runtime library with the original block size from trunk and do not have issues.

So my question is, is a block size of 1 unsupported, and therefor the error is in TI’s changes? Or is there an error in _add_back_capacity()?

Why does __add_back_capacity(1) allocate more blocks if the base is empty, while __add_back_capacity() makes no check?

I’m talking about line 2510 of https://github.com/llvm-mirror/libcxx/blob/master/include/deque

FYI, w/o changes to TI’s code, as long as I resize(1) first, then push_back() will work just fine thereafter!

Somehow just that first push_back screws something up.

I really don’t want to have to run a modified version of TI’s runtime, but may have to.

The former - libc++ does not support a block size of 1.
The code was designed for a minimum block size of 16.

– Marshall

Thank you