LINUX.ORG.RU

Получить указатель на стек на MIPS архитектуре

 


0

2

Привет!

Подскажите, мне нужно передать указатель на стек в некоторую функцию.

Если подробнее - то сначала выполняется некоторый код который может разместить на стеке ссылки на объекты, а когда он завершается, мне надо его стек просканировать.

Такой код верно будет работать? Не получится так что sp будет как-то изменен (в преамбуле например)

Все это делается в gcc

void run(void *(*code)(void *), void * arg, int stack_size) {
    unsigned int sp;
    asm volatile ("sw $sp, %0" : "=m" (sp));
    code->(arg);
    gc_collect((void*)sp, stack_size);
}

PS Да, я не могу тут выделить свой стек :(

★★★★

Последнее исправление: OxiD (всего исправлений: 5)

Если у тебя одна функция где-то в своем стекфрейме в локальных переменных чето размещает, а потом ты из функции, вызвавшей ее, хочешь достать из ее стека то, что там та функция записала в стекфрейм свой (который формально уже невалиден т.к. та функция «закончилась»), то лучше не делай так, это плохая идея.

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от SZT

Мм, а что может пойти не так? Метод который я использую для сканирования стека сделан для этой задачи специально. Единственная штука - нормальные люди выделяют стек через Malloc, а у меня нет такой возможности.

OxiD ★★★★
() автор топика
Ответ на: комментарий от OxiD

Мм, а что может пойти не так?

Ну например прерывание может сработать и что-то в стек запушить в процессе работы, и это что-то может затереть те данные. Если у тебя функция, из которой ты таким кривым методом собираешься доставать данные, написана на Си, то расположение локальных переменных в стеке будет зависеть от опций компилятора, так что тебе эту функцию надо наверное на асме писать.

Зачем вообще так делать? Ты не можешь до вызова своей функции узнать, сколько именно ей нужно места для данных, и потом сделать alloca() или VLA нужного размера и передать указатель на эту аллоцированную в стеке память в ту функцию, чтоб она туда набросала данных?

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 2)
Ответ на: комментарий от SZT

Не могу, и alloca() тут нет :( У меня микроконтроллер, с какой-то урезанной операционкой. Тут есть возможность создать поток, но нельзя указать свой стек (но можно размер). Заранее не известно ни что именно будет запускаться, ни сколько ему места потребуется.

Я переношу сюда интерпретатор ЯП, который хочет после завершения треда почистить стек (gc).

У меня есть перед глазами порты на другие архитектуры, где многопоточность сделана похожим образом, только там стек выделяется вручную через malloc и потом сканируется gc.

И кажется тут не важно расположение переменных. Этой штуке надо просканировать все слова в стеке, проверить каждое из них по словарю - не указатель ли это на что-то выделенное через аллокатор, и если это оно, то попытаться собрать мусор. В детали gc я не вникал пока.

OxiD ★★★★
() автор топика
Ответ на: комментарий от OxiD

Не могу, и alloca() тут нет :(

Попробуй сделай #define alloca(x) __builtin_alloca(x)
Ну и VLA можно использовать.

У меня есть перед глазами порты на другие архитектуры, где многопоточность сделана похожим образом, только там стек выделяется вручную через malloc и потом сканируется gc.

А почему нельзя сделать свой malloc поверх глобального массива, или взять готовую реализацию?

Этой штуке надо просканировать все слова в стеке, проверить каждое из них по словарю - не указатель ли это на что-то выделенное через аллокатор, и если это оно, то попытаться собрать мусор.

Блин, это тупизм какой-то, ведь совершенно не ясно, является ли такая-то ерунда в стеке каким-то числом или структурой, которая по случайному стечению побайтно совпала с указателем на что-то, или это именно указатель. Да и сам указатель мог быть не в стеке, а где-нибудь в регистрах, или быть успешно чем-то перезаписан...

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 2)
Ответ на: комментарий от SZT

Возможно и тупизм ;)

https://github.com/micropython/micropython/blob/5ed578e5b48730606536ded9a711223ae9a70262/py/gc.c#L342

А возможно там как-то гарантируется что выделенные объекты не кладутся в регистры. Вот как они проверяют на совпадение я не знаю, можно посмотреть в сорцах

OxiD ★★★★
() автор топика
Ответ на: комментарий от SZT

на эту аллоцированную в стеке память в ту функцию, чтоб она туда набросала данных Не понял этого, поясни пожалуйста.

Это же именно стек, не просто память. Т.е мне надо будет сделать alloca, и потом в $sp прописать этот адрес перед вызовом следующей функции? Но это же будет скорее всего та же самая память, что и если просто вызвать функцию - она же вызовется на том же самом стеке.

OxiD ★★★★
() автор топика
Ответ на: комментарий от OxiD

Это же именно стек, не просто память. Т.е мне надо будет сделать alloca, и потом в $sp прописать этот адрес перед вызовом следующей функции?

Ну вот допустим есть у тебя функция a() которая внутри у себя вызывает функцию b() и тебе в функции a() надо получать какие-то данные из функции b() в стек. Допустим, известно количество данных, которые та функция b() может передать, тогда можно сделать alloca() внутри функции a(), передать указатель на эту память в функцию b() и функция b() вернет в ту память какие-то данные.

Допустим если тебе известно, что та функция b() выделит максимум 10 указателей, и тебе те 10 указателей надо получить в функции a() то указатели должны будут там выделяться не просто как обычные локальные переменные, они должны в эту память записываться обязательно, и там храниться в строго единственном экземпляре... т.е. нужен специальный способ для выделения переменных в той памяти, который будет применяться только для указателей, которые потом надо особым образом освобождать в какой-то момент

Зачем вообще этот бред, почему б просто не сделать специальный глобальный стек указателей (т.е. тупо глобальная переменная-структура, где есть указатель на вершину стека, массив и функции push(), pop()), и пусть в этот глобальный стек разные функции добавляют те указатели, которые надо будет потом освободить, и потом пусть GC тупо пробегает этот стек.

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 3)

Ну так посмотри что в асме получается, делов-то.

А вообще с асмовыми вставками для MIPS надо аккуратно, потому что у MIPS есть особенность связанная с конструкцией конвейера - если MIPS выполняет команду перехода, то будет выполнена и следующая за ней команда, так что можно очень прилично проколоться. Возможно современный gcc это отдупляет и для ассемблерных вставок, но когда-то давно такие штуки приходилось проверять глазками.

Плюс ещё интенсивное использование регистров для аргументов функций и локальных переменных. В общем, c MIPS’ом надо точно знать что ты делаешь и как это всё работает.

Кстати, в твоём коде, на asm( "SW $sp,%0" : "=m" (sp) ) можно обломаться, потому что sp может оказаться регистровой переменной.

Наверно можно попробовать «размещать объекты» в памяти выделенной alloca, если хочется именно на стеке и точно знать где.

Stanson ★★★★★
()
Последнее исправление: Stanson (всего исправлений: 2)
Ответ на: комментарий от SZT

Да, но это опционально ;) Если уж перетаскивать поддержку тредов то надо сделать это полноценно, а то кто-то соберет его с GC и память потечет

OxiD ★★★★
() автор топика
Ответ на: комментарий от anonymous

Софт про который я спрашиваю - опенсорс

OxiD ★★★★
() автор топика
Ответ на: комментарий от OxiD

а что, софт работает без железа?

впрочем, это не важно, ведь проприетарщине не место на opensource.ru

anonymous
()
Ответ на: комментарий от anonymous

По-моему ты поехавший, анонимус ;)

Весь софт который тут обсуждают, включая туксрейсера и /bin/cat работает на проприетарном железе.

OxiD ★★★★
() автор топика
Ответ на: комментарий от OxiD

двойные стандарты у оределённых личностей тут, набрасывающих про опенсор.сру, а поехавший анон? ну-ну

anonymous
()
Ответ на: комментарий от SZT

Блин, это тупизм какой-то, ведь совершенно не ясно, является ли такая-то ерунда в стеке каким-то числом или структурой, которая по случайному стечению побайтно совпала с указателем на что-то, или это именно указатель.

Первый раз видишь conservative garbage collector?

utf8nowhere ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.