|
|
  |
свежак KGP win32/arm/avr/mips/m68k, GNU tools chain |
|
|
|
Sep 9 2016, 07:57
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (Terminator @ Sep 9 2016, 04:37)  А мне хочется и другой вариант попробовать, складывать команды в очередь пока есть свободная память, а потом, те что не влезают, выкидывать. У меня в таком случае в перегруженном operator new() из очереди удаляются самые старые события (которые, наверняка, уже мало кому интересны) и после каждого удаления производится повторная попытка выделить память для нового события. Если очередь уже пуста, а памяти все еще не хватает - то, значит, что-то уже сильно порушено и остается только перезагружаться. QUOTE (Terminator @ Sep 9 2016, 04:37)  С обычным new это невозможно. А с operator new ( std::size_t count, const std::nothrow_t& tag) - возможно. В этом случае компилятор вставляет проверку возвращенного new(std::nothrow) указателя и вызывает конструктор только в том случае, если new вернул не 0.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 10 2016, 05:51
|

Местный
  
Группа: Участник
Сообщений: 209
Регистрация: 7-12-04
Из: Томск
Пользователь №: 1 382

|
Цитата(Сергей Борщ @ Sep 9 2016, 14:57)  У меня в таком случае в перегруженном operator new() из очереди удаляются самые старые события (которые, наверняка, уже мало кому интересны) и после каждого удаления производится повторная попытка выделить память для нового события. Если очередь уже пуста, а памяти все еще не хватает - то, значит, что-то уже сильно порушено и остается только перезагружаться. Такой подход требует реализации собственного, аля, сборщика мусора. Цитата(Сергей Борщ @ Sep 9 2016, 14:57)  А с operator new ( std::size_t count, const std::nothrow_t& tag) - возможно. В этом случае компилятор вставляет проверку возвращенного new(std::nothrow) указателя и вызывает конструктор только в том случае, если new вернул не 0. Почти так и сделал. С std::nothrow сделать не получилось. Сделал проще, operator new(size_t,void*). Кстати, компилятор никаких проверок не вставляет, конструктор вызывается в любом случае. Вставил проверку перед вызовом new.
|
|
|
|
|
Sep 10 2016, 07:09
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (Terminator @ Sep 10 2016, 08:51)  Почти так и сделал. С std::nothrow сделать не получилось. Сделал проще, operator new(size_t,void*). Проще? Покажите, сравним. Это так по-русски - чуть что, придумывать свой велосипед. Причем почти всегда с квадратными колесами. QUOTE (Terminator @ Sep 10 2016, 08:51)  Кстати, компилятор никаких проверок не вставляет, конструктор вызывается в любом случае. У меня вставляет, что я делаю неправильно? CODE #include <new>
class a { public: a(); };
a * pA;
void test() { pA = new(std::nothrow) a;
} CODE 18:main.cpp **** void test() 19:main.cpp **** { 100 .loc 1 19 0 101 .cfi_startproc 102 @ args = 0, pretend = 0, frame = 0 103 @ frame_needed = 0, uses_anonymous_args = 0 104 0000 10B5 push {r4, lr} @ 105 .LCFI0: 106 .cfi_def_cfa_offset 8 107 .cfi_offset 4, -8 108 .cfi_offset 14, -4 20:main.cpp **** pA = new(std::nothrow) a; 109 .loc 1 20 0 110 0002 0549 ldr r1, .L7 @, 111 0004 0120 movs r0, #1 @, 112 0006 FFF7FEFF bl _ZnwjRKSt9nothrow_t @ <-------- new(std::nothrow) 113 .LVL0: 114 000a 0446 mov r4, r0 @ D.8513, 115 000c 08B1 cbz r0, .L2 @, <------- проверка 116 .loc 1 20 0 is_stmt 0 discriminator 1 117 000e FFF7FEFF bl _ZN1aC1Ev @ <------- вызов конструктора 118 .LVL1: 119 .L2: 120 .loc 1 20 0 discriminator 4 121 0012 024B ldr r3, .L7+4 @ tmp112, 122 0014 1C60 str r4, [r3] @ D.8513, pA 123 0016 10BD pop {r4, pc} @
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 11 2016, 12:44
|

бессмертным стать можно тремя способами
    
Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912

|
кусочек кода и конструктор CODE int main(void) { EngineTask = new TEngineTask() ; ......
CODE ........... class TEngineTask : public TTask { public: TEngineTask () { NOP(); active = false ; NOP(); } .........
ВАЖЕН атрибут которым оператор new помечен: inline void* operator new(size_t size) CODE 398 __libc_init_array() ; 0800a82a: bl 0x800aec0 <__libc_init_array> 0800a82e: movs r0, #12 <-------- выхов main() 0800a830: bl 0x800a394 <malloc(size_t)> <-------- EngineTask = new TEngineTask() ; 0800a834: movs r5, #0 <-------- вызов конструктора 0800a836: ldr r3, [pc, #248] ; (0x800a930 <ResetHandler()+744>) 0800a838: str r3, [r0, #0] 0800a83a: str r5, [r0, #4] 0800a83c: nop 14 active = false ; 0800a83e: strb r5, [r0, #8] 15 NOP(); 0800a840: nop 0800a842: ldr r3, [pc, #240] ; (0x800a934 <ResetHandler()+748>)
нет проверки результата malloc , компилятор полагает механизм генерации исключений - при вызове по нулю конструктора код перехватит эксепшен и все ок. inline void* operator new(size_t size) _GLIBCXX_NOEXCEPTCODE 398 __libc_init_array() ; 0800a82a: bl 0x800aec4 <__libc_init_array> 0800a82e: movs r0, #12 <-------- выхов main() 0800a830: bl 0x800a394 <malloc(size_t)> <-------- EngineTask = new TEngineTask() ; 0800a834: cbz r0, 0x800a844 <ResetHandler()+508> <-------- проверка того что вернул malloc 12 { 0800a836: ldr r2, [pc, #252] ; (0x800a934 <ResetHandler()+748>) <- вызов конструктора 0800a83a: stmia.w r0, {r2, r3} 13 NOP(); 0800a83e: nop 14 active = false ; 0800a840: strb r3, [r0, #8] 15 NOP(); 0800a842: nop 0800a844: ldr r3, [pc, #240] ; (0x800a938 <ResetHandler()+752>)
компилятор полагает что new не генерит эксепшенов и поэтому нужно проверить результат malloc чтоб не улететь в космом
|
|
|
|
|
Sep 11 2016, 18:58
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
CODE EngineTask = new TEngineTask(); CODE pA = new(std::nothrow) a; Найдите десять отличий.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 11 2016, 19:14
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(Сергей Борщ @ Sep 11 2016, 23:58)  Найдите десять отличий. Насколько я понял, klen привёл третий вариант, в котором void* operator new(size_t size)
объявлен как noexcept. В этом случае компилятор тоже вставляет проверку результата выделения памяти перед вызовом конструктора.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Sep 12 2016, 02:44
|

Местный
  
Группа: Участник
Сообщений: 209
Регистрация: 7-12-04
Из: Томск
Пользователь №: 1 382

|
Цитата(Сергей Борщ @ Sep 10 2016, 14:09)  Проще? Покажите, сравним. Это так по-русски - чуть что, придумывать свой велосипед. Причем почти всегда с квадратными колесами. Согласен, с "проще" я несколько погорячился  Просто с обычным new(std::nothrow) у меня проект не собирается, зачем-то тащит библиотечную "кучу" и что-то про исключения. Вот мой код. Код void* __mem = malloc(sizeof(Packet)); if (__mem == nullptr) { ... } else { packet = new(__mem) Packet(...); ... переопределение new Код void* operator new(size_t size, void* p) { (void) size; return p; }
|
|
|
|
|
Sep 12 2016, 06:06
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (AHTOXA @ Sep 11 2016, 22:14)  Насколько я понял, klen привёл третий вариант, в котором void* operator new(size_t size) объявлен как noexcept. В этом случае компилятор тоже вставляет проверку результата выделения памяти перед вызовом конструктора. Но это же велосипед. Уже существующий new(std::nothrow_t) делает ровно то же самое, всегда есть в заголовочном файле <new> любого компилятора и к нему там всегда приписан нужный правильный атрибут. Используя его не нужно думать, _GLIBСXX или какой еще _NOEXCEPT туда надо дописывать (хватает, кстати, обычного переносимого throw() ). Каюсь, тоже использовал такое переопределение, хоть это и грязный хак. Знакомый со стандартом программист, глядя в такой исходник и не зная о переопределении, вправе ожидать совершенно другого поведения кода. Это примерно равносильно #define true false, поэтому советовать такое кому-то еще я никогда не буду. QUOTE (Terminator @ Sep 12 2016, 05:44)  Просто с обычным new(std::nothrow) у меня проект не собирается, зачем-то тащит библиотечную "кучу" и что-то про исключения. Странно. Для new() ему нужен malloc(), для delete() - free(), если эти две функции определены в проекте - у меня ничего не тащит. Можете сделать и выложить простейший проект? QUOTE (Terminator @ Sep 12 2016, 05:44)  переопределение new Велосипед, такой велосипед  QUOTE If placement_params are provided, they are passed to the allocation function as additional arguments. Such allocation functions are known as "placement new", after the standard allocation function void* operator new(std::size_t, void*), which simply returns its second argument unchanged. This is used to construct objects in allocated storage: Кстати, чтобы не писать (void)size; вы можете опустить имя первого параметра в определении функции: CODE void* operator new(size_t, void* p) { return p; } И попробуйте все же победить, ваш код станет еще проще: CODE packet = new(std::nothrow) Packet; if (packet == nullptr) { ... } else { ...
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 18 2016, 21:52
|

бессмертным стать можно тремя способами
    
Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912

|
релизная сборка 6.2.0 linux64: http://klen.org/Files/DevTools/x86_64-kgp-....2.0_CORYLUS.7zwin64: http://klen.org/Files/DevTools/x86_64-kgp-....2.0_CORYLUS.7z2_Genadi Zawidowski проверяйте! сборка под линух у меня пережевала Ваш фалик  сборка под масдай под wine тоже wine ./arm-kgp-eabi-gcc.exe -c -mcpu=cortex-a9 -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -fno-math-errno -funroll-loops -fgraphite -ffunction-sections -fdata-sections -ffat-lto-objects -Ofast -flto -gdwarf-2 -fomit-frame-pointer -Wall -Wstrict-prototypes -DNDEBUG=1 -DCPUSTYLE_R7S721=1 -DCPUSTYLE_R7S721020=1 -I../ -I../rza1x_inc usbd.c -o usbd.o объектники бинарно идентичны  должно взлететь! Вы С++ используете? если да то используете ли исключения (try{} catch() )? если да то есть тонкие замечание пл кодогенерации.
|
|
|
|
|
  |
4 чел. читают эту тему (гостей: 4, скрытых пользователей: 0)
Пользователей: 0
|
|
|