По идее pthread_cleanup_push это макрос, надо посмотреть, во что он разворачивается Чёт у меня пока не получается, какой-то while требует: https://godbolt.org/z/6_AZiP
Посмотри в исходниках самого pthread'а, как он создаёт потоки на самом низком уровне --- Сообщение объединено, 2 июн 2020 --- DevilDevil, https://man7.org/linux/man-pages/man2/clone.2.html
Я пытался понять исходники pthread.h - возникло ощущение, что он на низком уровне прописывает калбек. Но нужно для начала понять, что там вообще внутри происходит )
DevilDevil, Аллокатор стало быть. А что там писать, не старайся эффективнее не реализуешь https://wasm.in/threads/ukazatel-v-opisatel.33644/
Я создал похожую тему в UNIX: https://wasm.in/threads/otsledit-udalenie-potoka-bez-pthread_cleanup_push.33782/ Помогите, если кто-то может
DevilDevil, Я смысл не понимаю. Обычно нужен высокий профайл, пропускная способность. Тоесть запрос на аллокацию должен происходить как можно быстрее. Для этого резервируется большой блок и всего лишь синхронно(атомарно) увеличивается указатель на размер блока. Для оптимизации обьёма памяти нужен некоторый слой отображения(таблицы трансляции). Если же гонять блоки туда сюда в каких то списках, то в этом смысла нет, система сама это делает и лучше чем ты сделаешь(так как у тебя нет доступа к андок(нэйтив) ресурсам). Так вот какая цель ?
В многопоточных приложениях бутылочное горлышко - это синхронизация. Как правило выделяются небольшие куски и в рамках одного потока. В этом случае эффективно создать кеш-кучу, ассоциированную с потоком. Большие куски или кросспотоковая рутина разруливается отдельно. В момент умерщвления потока нужно грамотно разруливать оставшуюся от него кеш-кучу. Я посмотрел, твою ссылку, здорово, что ты дошёл до хеш-таблиц. Но это кстати не самый быстрый доступ к данным. С другой стороны для твоей задачи это может быть оптимальное решение.
DevilDevil, > ты дошёл до хеш-таблиц. Но это кстати не самый быстрый доступ к данным. Я разве использовал хэши, ты тему не прочитал - если бы прочитал, то знал бы что они помогут для заранее известных указателей, либо их области, но не для рандом на всё адр простр. > Но это кстати не самый быстрый доступ к данным. Самое эффективное решение, из за него невозможно было реализовать бинарную трансляцию, так как вся суть её в быстрой аллокации. Эффективнее реализации нет; перейди порог 150M/аллокаций в sec :P > В многопоточных приложениях бутылочное горлышко - это синхронизация. Нет, это сервисное ожидание. Когда тред сменяет мод. Для начала потести, сними профайл на всё с чем ты имеешь дело, прежде чем что либо утверждать. Я это сделал давно, при разрабтке визора(дий), на это ушли года и каждый раз на любое действие - замер тайминга. Что бы знать где садится профайл, это самое важное для dbi, так как апп крутятся иногда даже часами. > В момент умерщвления потока нужно грамотно разруливать оставшуюся от него кеш-кучу. Я делал это просто. Поток запрашивает локальный блок(tls), все блоки помечены в битовой карте. Тогда скан этой карты(bsf). Если она заполнена, то цикл очистки - ThreadTimes, если тред завершён, тогда освобождение ресурсов. Незачем что либо ожидать, нотифи не нужны. Код (Text): ; ; -= SYNC LOCAL STORAGE =- ; ; + ; PsOpenThread proc Tid:ULONG, Access:ULONG Local Cid:CLIENT_ID Local ThreadHandle:HANDLE Local ObjAttr:OBJECT_ATTRIBUTES xor eax,eax mov ecx,Tid mov ObjAttr.uLength,sizeof(OBJECT_ATTRIBUTES) mov ObjAttr.hRootDirectory,eax mov ObjAttr.uAttributes,eax mov ObjAttr.pSecurityDescriptor,eax mov ObjAttr.pSecurityQualityOfService,eax mov ObjAttr.pObjectName,eax mov Cid.UniqueProcess,eax mov Cid.UniqueThread,ecx invoke ZwOpenThread, addr ThreadHandle, Access, addr ObjAttr, addr Cid .if !Eax mov eax,ThreadHandle test ebx,ebx .else xor eax,eax .endif ret PsOpenThread endp ; + ; TlsCleaningCycle proc uses esi edi Local Times:KERNEL_USER_TIMES xor esi,esi ; N mov edi,G_TlsBase assume edi:PTLS .repeat bt D G_TlsMap,esi .if Carry? invoke ZwQueryInformationThread, [Edi].Handle, ThreadTimes, addr Times, sizeof(KERNEL_USER_TIMES), NULL .if !Eax mov ecx,D Times.ExitTime[0] mov edx,D Times.ExitTime[4] test ecx,edx .if !Zero? invoke ZwClose, [Edi].Handle lock bts D G_TlsMap,esi .endif .endif .endif inc esi add edi,sizeof(TLS) .until Esi > 256 ret TlsCleaningCycle endp ; + ; o Initial all bits set to 1. ; TlsQueryWorkSpace proc Scan: xor ecx,ecx ; N lea edx,G_TlsMap @@: bsf eax,D[edx][ecx*4] .if Zero? inc ecx cmp ecx,8 jb @b invoke TlsCleaningCycle jmp Scan .else lock btr D[edx][ecx*4],eax jnc Scan ; P = N*32 + I shl ecx,5 add eax,ecx .endif ret TlsQueryWorkSpace endp
Indy_, Я автор менеджера памяти BrainMM, который по производительности обгоняет передовые разработки Intel и Google Я не хочу с тобой спорить о пользе или вреде тех или иных подходов Я хочу, чтобы ты мне помог отслеживать удаления потоков в POSIX
DevilDevil, > по производительности обгоняет передовые разработки Intel и Google Так значит выложи семпл для теста. Норм спец первым делом бы приводил статистику по профайлу, а не названия крупных контор. Чувак тут не школоборд любое утверждение нужно обосновать/доказать.
Indy_, Погугли BrainMM Есть уже бенчмарки, таблицы, примеры Я не хочу ничего доказывать Я пытаюсь понять, как в POSIX отследить завершение потока. В Windows это можно. В POSIX судя по наличию соответствующего макроса - тоже