SASGIS

Веб-картография и навигация


View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0001226SAS.ПланетаРефакторингpublic17-03-2012 23:2810-10-2012 11:46
Reportervasketsov 
Assigned Tovasketsov 
PrioritylowSeveritymajorReproducibilityN/A
StatusclosedResolutionfixed 
PlatformWindowsOSVistaOS VersionUltimate
Product Version.Nightly 
Target Version120808Fixed in Version120808 
Summary0001226: Использование примитивов синхронизации (разработчикам)
DescriptionПо результатам тестов на XP и Vista (к сожалению больше под рукой ничего не было последние пару дней, желающим тулзу для тестирования выдам) я таки наделал РЕАЛЬНЫХ функций для создания примитивов синхронизации, а не тупо просто примеров как попало.

Вправлено пока что одно место - это MapMainLayer. Остальное надо будет потихоньку разруливать (а также корректно кодить в новых местах) исходя из нижеследующих комментариев.

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

Итак в качестве базовых (системных и не очень) примитивов используются:
1. CriticalSection (со спинлоком).
2. Resource (>= NT4).
3. MREW (Delphi).
4. SlimRW (>= Vista).

Конкретный создаваемый примитив возвращается ТОЛЬКО как IReadWriteSync (об исключении из этого правила последний абзац), тип же его определяется вызывающей стороной исходя из потребностей и особенностей блокируемой сущности.

Первым делом напишу про SlimRW. Появилось это в Vista и базируется на объекте ядра KeyedEvent. Суть этого объекта ядра в том, что синхронизирующему объекту передаются для управления не только опции типа времени ожидания или Alertable, но и некий Key (указатель). Синхронизация выполняется только между вызовами для одного значения Key. Ограничение ровно одно - выравнивание значения Key (внутри ntoskrnl.exe есть проверка на младший байт). Несмотря на то что KeyedEvent появился в XP, реализация его была несколько неудачная. Так что несмотря на принципиальную возможность повторить реализацию SlimRW с точки зрения кода пользовательского режима, толку от этого будет мало.

Возможности SlimRW довольно скудны. Это примитив типа MREW, но со следующими отличиями:
1. Он жрёт куда меньше ресурсов (все SlimRW созданы над ОДНИМ объектом KeyedEvent и отличаются только значением Key).
2. Он не поддерживает рекурсивный вызов и изменение уровня блокировки.
3. Он всегда работает со спинлоком (правда небольшим).
4. В принципе возможно реализовать "участковую" блокировку списков объектов на основании некоторого "хэша" без каких-либо заметных потерь в ресурсах и производительности (не считая собственно списка и хэша), например интересной идеей представляется раскидывание тайлов в кэше в памяти по 4-м кэшам исходя из значения последнего символа QuadKey для уменьшения конкуренции на вставку, чтение и удаление тайлов из кэша, или другой аналогичный по сути финт.

Про критические секции и MREW и так все всё знают.

Про примитив Resource также напишу отдельно ввиду его малой известности. Этот примитив построен над критической секцией, внутренности его можно увидеть исходя из описания его структуры (всё в том же исходном файле с синхронизаторами). Примитив реализован в рамках rtl внутри ntdll, реализован на удивление качественно. Достаточно сказать, что по скорости работы он сравним с SlimRW и ощутимо уступает ему только при крайне кратковременных синхронизируемых операциях (типа чтение-установка значения переменной, или около того). Но очевидно по количеству сожранных ресурсов он куда более "тяжёлый". Впрочем он в любом случае "уделывает" MREW.

Вот исходя из такой логики и необходимо выбирать вызываемую фукнцию для создания примитива (из generic-функций!). Возможность рекурсивного вызова, передаваемая в качестве необязательного параметра, определяется следующим образом. Если существует хотя бы теоретическая возможность для рекурсивного вызова примитива синхронизации в любом потоке (в рамках того же потока повторный вызов любого Begin ДО вызова соответствующего End) - необходимо вызывать функцию с разрешением рекурсии. В этом случае SlimRW никак не создастся.

Также в качестве бонуса реализована возможность создавать объекты синхронизации над объектом ядра EventPair. Этот объект доступен начиная с NT4 и применяется для синхронизации ДВУХ потоков (на самом деле конечно с помощью небольшой фантазии и некоторой матери, в некоторых случаях с его помощью можно синхронизировать две ОЧЕРЕДИ потоков). Что с ним можно делать - несложно догадаться из реализованных над этим примитивом функций (интерфейс IEventPair). Чтобы этот интерфейс стал доступен - надо включить опцию ALLOW_USE_EVENTPAIR вверху файла (она откроет функцию для создания и подменит "фабрику классов"). Особенностью его является в теории и в некоторых версиях NT более быстрое переключение именно на смежный поток.
TagsNo tags attached.
Attached Files

- Relationships

-  Notes
There are no notes attached to this issue.

- Users who viewed this issue
User List Anonymous (1505x)
Total Views 1505
Last View 21-11-2024 09:58

- Issue History
Date Modified Username Field Change
17-03-2012 23:28 vasketsov New Issue
18-03-2012 16:47 zed Note Added: 0006190
18-03-2012 17:02 zed Note Deleted: 0006190
17-06-2012 19:45 vdemidov Status new => resolved
17-06-2012 19:45 vdemidov Fixed in Version => 120808
17-06-2012 19:45 vdemidov Resolution open => fixed
17-06-2012 19:45 vdemidov Assigned To => vasketsov
18-06-2012 11:25 vdemidov Target Version => 120808
10-10-2012 11:46 Tolik Status resolved => closed



Copyright © 2007 - 2024 SAS.Planet Team