[personal profile] dmitry_vk

Собрал виндовый инсталлятор SBCL 1.0.42 (раньше использовал 1.0.40) с поддержкой нитей.

https://sites.google.com/site/dmitryvksite/sbcl-distr/sbcl-1.0.42-threads.msi

Date: 2010-10-07 01:59 pm (UTC)
From: [identity profile] akovalenko.livejournal.com
Выяснилось, что частота появление этих нулей зависит от запросов на выделение памяти: если туда перед socket-errno влепить (make-sequence 'list 1000), будут сплошные нули. А если, наоборот, сделать сразу (let ((fd ..) (err ..))), чтобы между ними ничего не вызывалось — можно очень долго ни одного нуля не видеть (не знаю пока, «всегда» или нет). Without-gcing и without-interrupts вокруг socket-accept на ситуацию не влияет.

Так что похоже, что код ошибки затирает аллоцирующая часть GC.

Date: 2010-10-07 02:19 pm (UTC)
From: [identity profile] akovalenko.livejournal.com
(уточнение для dmitry_vk) всё-таки моментальное присваивание socket-errno помогает не навсегда.

Date: 2010-10-07 05:01 pm (UTC)
From: [identity profile] dmitry-vk.livejournal.com
Бурное обсуждение получилось, пока я отсутствовал :)
Спасибо (обоим) за находку - вероятно, в каком-то месте не сохраняется WSAGetLastError (кстати, а на винде errno и WSAGetLastError отличаются?), что и приводит к наблюдаемому эффекту.

>Не особо понимаю, почему правильным поведением является возвращать NIL, даже и при EINTR | EAGAIN (я бы condition выбросил),

Сигнал - это вполне нормально, и делать из этого событие (хм, игра слов получается :) ) не стоит; еще возврат EAGAIN/EWOULDBLOCK возможен при неблокирующем вводе-выводе. Есть два логичных варианта - либо вернуть NIL, либо перезапустить accept (но при неблокирующем вводе-выводе делать этого не стоит, т.к. следующий вызов закончится тем же).

Date: 2010-10-08 02:43 am (UTC)
From: [identity profile] akovalenko.livejournal.com
errno и WSAGetLastError() отличаются: errno принадлежит CRT, устанавливается всякими _open _write и так далее. Errno сохранять обычно не надо, вы его не перезапишете случайно — ну там какой-нибудь malloc() его не трогает.

GetLastError() и WSAGetLastError() не отличаются. Портятся от каждого чиха: сделали VirtualAlloc() — и получили там 0 (SUCCESS), сделали WaitForSingleObject — опять же получили 0.

Date: 2010-10-08 06:13 pm (UTC)
From: [identity profile] dmitry-vk.livejournal.com
Мне почему-то казалось, что {Get,Set}LastError() используют поле в Thread Information Block, и errno объявлен как макрос, ссылающийся на это же поле.

Date: 2010-10-08 07:55 pm (UTC)
From: [identity profile] avodonosov.blogspot.com (from livejournal.com)
Не все так просто. Там еще лучше придумали.

http://msdn.microsoft.com/en-us/library/ms737828%28VS.85%29.aspx

Date: 2010-10-08 08:14 am (UTC)
From: [identity profile] akovalenko.livejournal.com
1. Обнаружился баг (который непонятно, как устойчиво воспроизвести):
Тред внезапно перестаёт реагировать на прерывания. Обычный slime-repl thread, не внутри какого-либо цикла, не после каких-либо очевидных специфических действий... При прерывании в нём ставится *INTERRUPT-PENDING*, и нифига не обрабатывается. Если запустить новый тред, там всё нормально. Не подскажете, куда смотреть для диагностики? (*interrupts-enabled* t, *allow-with-interrupts* t)

2. По поводу неуместности condition для ewouldblock/eagain: в общем-то, в качестве локального performance trick решение оправдано, но с точки зрения чистоты интерфейса лучше всё-таки condition выбрасывать — а уж caller пусть решает, что делать. Функции из sb-unix и sb-posix таки выбрасывают, никого это не беспокоит (?).

Хотя я обнаружил, что в sb-bsd-sockets вроде как принято возвращать NIL для EAGAIN/EWOULDBLOCK, например, на socket-receive тоже так делается. Если это не нововведение, то трогать не стоит, конечно.

Тем более что socket-errno не является частью публичного API, и ответить на вопрос

Date: 2010-10-08 06:11 pm (UTC)
From: [identity profile] dmitry-vk.livejournal.com
Еще важны следующие вещи: *pseudo-atomic-bits*, *gc-safe*.
Вообще я обработку прерываний не очень подробно пока тестировал (я отношусь к этому как к вспомогательной функции, и для меня сейчас важнее довести все до смерживаемого состояния, а то боюсь, что пропадет мотивация); знаю, что с прерываниями есть проблемы. В threads.impure были подобные проблемы - прерывание не доходило - там это "лечилось" вставкой выражений (let ((x nil)) x) в определенные места кода (но обычно до того места, где прерывания переставали работать; поэтому мне кажется, что неправильно работает функция gc_safepoint и все-таки что-то пропускает).

Date: 2010-10-08 06:12 pm (UTC)
From: [identity profile] dmitry-vk.livejournal.com
И, конечно же, надо смотреть на отладочный вывод из check_pending_interrupts (если его нет, то добавить) - почему происходит выход из safepoint при установленном *interrupt-pending*.

Profile

dmitry_vk

April 2023

S M T W T F S
      1
234567 8
9101112131415
16171819202122
23242526272829
30      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Apr. 5th, 2026 03:10 pm
Powered by Dreamwidth Studios