Алгоритм маляра Шлемиэля даже в ядре? Хотя это скорее всего никому не нужный драйвер. Одно дело если бы такая ошибка была в fs/ и другое — в каком-то драйвере, которым пользуются только экстремалы.
Очень круто. Это из серии «надо бы сделать такую штуку, но лень». Но бывают и такие тесты:)
Не уверен, что правильно понял идею, но в gcc вроде бы a[5] = {0,0,0,0,0} то же что и a[5] = {0}. Т.е. можно задать длинный-предлинный массив и по ходу регистрации тестов закидывать в него указатели.
Я думаю это всё же контроль ошибок для объектов ядра. А объекты берутся явно не с потолка, для них сначала выделяют память через kmalloc, который не должен выделять адреса из пространства, зарезервированного под коды ошибок, так как сам возвращает коды ошибок из этого диапазона — круг замкнулся. По сути нужно лишь гарантировать, что malloc не вернёт адрес из области 0-MAX_ERRNO, а это достаточно просто.
Можно в принципе не полагаться на теорию вероятностей, а посмотреть, как происходит распределение сегментов памяти в программе. По крайней мере NULL — это невалидный указатель. Далее исходим из того, что память ядро выравнивает по 4 килобайта, а также из того, что по младшим адресам всегда помещаются сегменты кода и данных. То есть ядро (и тем более malloc) не будет размещать какие-либо данные как минимум в диапазоне адресов 0-4095.
Ну и /proc/xxxx/maps в помощь. Минус в том, что за все операционные системы ручаться нельзя, да и непонятно, что там на встраиваемых системах. На 64-разрядной машине виртуальная область памяти вообще содержит массу «дырок»:
Оставим невесть куда утекающие 87424K «кучи» на совести разработчиков, и обратим внимание, что ядро оставляет приличные области адресного пространства как «сверху», так и «снизу».
А в жизни обычно приходится ковыряться вот в этом: developer.gnome.org/glib/stable/glib-Error-Reporting.html Т.е. мы имеем: код возврата, указатель на объект, который хотим получить и указатель на объект «Ошибка», если код возврата false, после которого ещё надо память освобождать. Но зато можно передавать произвольные ошибки с произвольными сообщениями об ошибках.
Не думал, что в фише такой чудной синтаксис. Т.е. обратная совместимость напрочь отсутствует. Медленнее может быть из-за seq (внешняя команда).
dash быстр, но он требует дедовских методов программирования на шелле, так как по возможностям уступает даже busybox. И тут даже видно, как его обгоняет zsh:
$ time busybox sh -c 'for i in $(seq 1000000); do [[ "$1" = "123" ]] && echo ok; done'
real 0m3.783s
$ time busybox sh -c 'for i in $(seq 1000000); do [ "$1" = "123" ] && echo ok; done'
real 0m3.719s
$ time sh -c 'for i in {1..1000000}; do [[ "$1" = "123" ]] && echo ok; done'
real 0m6.310s
$ time sh -c 'for i in {1..1000000}; do [ "$1" = "123" ] && echo ok; done'
real 0m10.340s
$ time dash -c 'for i in $(seq 1000000); do [ "$1" = "123" ] && echo ok; done'
real 0m2.394s
$ time zsh -c 'for i in {1..1000000}; do [ "$1" = "123" ] && echo ok; done'
real 0m5.541s
$ time zsh -c 'for i in {1..1000000}; do [[ "$1" = "123" ]] && echo ok; done'
real 0m1.975s
Баш существо загадочное, соглашусь что это builtin (разница с не-builtin налицо), но и не возьмусь объяснить, почему так происходит:
$ time for i in {1..10000}; do [[ "$1" = "123" ]] && echo ok; done
real 0m0.061s
$ time for i in {1..10000}; do [ "$1" = "123" ] && echo ok; done
real 0m0.108s
$ time for i in {1..10000}; do /bin/[ "$1" = "123" ] && echo ok; done
real 0m10.617s
— функция есть не везде (у меня на андроиде busybox, и хотелось бы, чтобы там этот PS1 тоже работал);
— по ссылке — шелл-портянка, у меня всего две строчки, и делают то что надо.
<зануда>По скорости. Во многих «стандартных» скриптах используют синтаксис условий [ ] для совместимости. Совмещать приходится для убунты/дебиана из-за велосипеда под названием dash и для всевозможных бсдей. На деле [ является внешней командой, а [[ — внутренней, благодаря этому отрабатывает намного быстрее. Фича есть в баше и busybox, а больше и не надо.</зануда>
Как раз очень раздражающий факт состоит в том, что стол реагирует ещё до прикосновения. Обратная связь отсутствует практически полностью.
То есть если я хочу паралелльно запустить красивые визуалы и синтез звука, то мне нужен ретранслятор, поскольку если модуль сопряжения принимает TUIO обьект, то допустим Flash визуалы этот обьект уже не видят.
Для этого в ядре Linux есть интересная возможность — reuse сокеты.
Ладно, пошутили и хватит. Вот нормальный (цвета по вкусу):
Заголовок спойлера
function __prompt_command_generator() {
PS1=""
PS1+='$(__LAST_EXIT="$?";' # This needs to be first
local TXTRED='\[\e[0;31m\]' # red
local TXTGRN='\[\e[0;32m\]' # green
local TXTYLW='\[\e[0;33m\]' # yellow
local TXTBLU='\[\e[0;34m\]' # blue
local TXTPUR='\[\e[0;35m\]' # purple
local TXTCYN='\[\e[0;36m\]' # cyan
local TXTWHT='\[\e[0;37m\]' # white
local BLDRED='\[\e[1;31m\]' # red - Bold
local BLDGRN='\[\e[1;32m\]' # green
local BLDYLW='\[\e[1;33m\]' # yellow
local BLDBLU='\[\e[1;34m\]' # blue
local BLDPUR='\[\e[1;35m\]' # purple
local BLDCYN='\[\e[1;36m\]' # cyan
local BLDWHT='\[\e[1;37m\]' # white
local TXTRST='\[\e[0m\]' # Text reset
#mark root as red
PS1+='[[ $UID -eq 0 ]] && echo -n "'$TXTRED'" || echo -n "'$TXTCYN'";'
PS1+='echo -n "\u'$TXTRST'";'
#hide host name if we are on a local machine
if [[ -n "$SSH_CLIENT" || -n "$SSH_TTY" ]]; then
PS1+='echo -n "@'$TXTYLW'\h'$TXTRST'";'
fi
#append current path
PS1+='echo -n " '$BLDBLU'\W";'
#append git branch
if type -p git>/dev/null; then
PS1+='__GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2> /dev/null);'
PS1+='[[ -n "$__GIT_BRANCH" ]] && echo -n "'$TXTBLU'(${__GIT_BRANCH})";'
PS1+='unset __GIT_BRANCH;'
fi
#show exit code
PS1+='[[ $__LAST_EXIT -eq 0 ]] && echo -n "'$BLDGRN'" || echo -n "'$BLDRED'";';
PS1+='unset __LAST_EXIT)'
PS1+="\\\$ $TXTRST"
}
#do not use this in e.g. scp
if [ -z "$SSH_CLIENT" ] || [ -n "$SSH_TTY" ]; then
__prompt_command_generator
fi
unset __prompt_command_generator
Алгоритм маляра Шлемиэля даже в ядре? Хотя это скорее всего никому не нужный драйвер. Одно дело если бы такая ошибка была в fs/ и другое — в каком-то драйвере, которым пользуются только экстремалы.
if(__LINE__ > 1000) exit(-1);
Ошибка всплывёт не на этапе компиляции, но хотя бы в рантайме.
Не уверен, что правильно понял идею, но в gcc вроде бы a[5] = {0,0,0,0,0} то же что и a[5] = {0}. Т.е. можно задать длинный-предлинный массив и по ходу регистрации тестов закидывать в него указатели.
Ну и /proc/xxxx/maps в помощь. Минус в том, что за все операционные системы ручаться нельзя, да и непонятно, что там на встраиваемых системах. На 64-разрядной машине виртуальная область памяти вообще содержит массу «дырок»:
А чем NULL в free не понравился?
dash быстр, но он требует дедовских методов программирования на шелле, так как по возможностям уступает даже busybox. И тут даже видно, как его обгоняет zsh:
— по ссылке — шелл-портянка, у меня всего две строчки, и делают то что надо.
<зануда>По скорости. Во многих «стандартных» скриптах используют синтаксис условий [ ] для совместимости. Совмещать приходится для убунты/дебиана из-за велосипеда под названием dash и для всевозможных бсдей. На деле [ является внешней командой, а [[ — внутренней, благодаря этому отрабатывает намного быстрее. Фича есть в баше и busybox, а больше и не надо.</зануда>
Для этого в ядре Linux есть интересная возможность — reuse сокеты.
Эх, где вы были, когда я был студентом:)
У меня не странный результат — где-то ошибки округления:
^R
PgUp/PgDown
А чтобы команды листались по стрелке вверх, достаточно добавить в bashrc:
Ладно, пошутили и хватит. Вот нормальный (цвета по вкусу):