<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ada-Ru Community</title>
	<atom:link href="http://ru.ada-community.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://ru.ada-community.org</link>
	<description>Сообщество русскоговорящих Ada программистов</description>
	<lastBuildDate>Wed, 09 Mar 2011 17:14:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Анонс axmpp 0.0.1</title>
		<link>http://ru.ada-community.org/2011/03/09/%d0%b0%d0%bd%d0%be%d0%bd%d1%81-axmpp-0-0-1/</link>
		<comments>http://ru.ada-community.org/2011/03/09/%d0%b0%d0%bd%d0%be%d0%bd%d1%81-axmpp-0-0-1/#comments</comments>
		<pubDate>Wed, 09 Mar 2011 17:14:32 +0000</pubDate>
		<dc:creator>Alexander Basov</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[axmpp]]></category>
		<category><![CDATA[xmpp]]></category>

		<guid isPermaLink="false">http://ru.ada-community.org/?p=25</guid>
		<description><![CDATA[Всем привет. Хочу анонсировать первый релиз библиотеки AXMPP. AXMPP &#8211; это реализация протокола XMPP для языка программирования Ада. Это первый релиз библиотеки, которые включает в себя следующие возможности: 1. Поддержка безопасного соединения с помощью agnutsl (ada-binding для gnutls). 2. Реализация базовой части протокола XMPP: * Управление списком контактов (ростер). * Прием/отправка сообщений. * Поддержка конференций. [...]]]></description>
			<content:encoded><![CDATA[<p>Всем привет.<br />
Хочу анонсировать первый релиз библиотеки AXMPP.</p>
<p>AXMPP &#8211; это реализация протокола XMPP для языка программирования Ада.<br />
Это первый релиз библиотеки, которые включает в себя следующие возможности:<br />
1. Поддержка безопасного соединения с помощью agnutsl (ada-binding для gnutls).<br />
2. Реализация базовой части протокола XMPP:<br />
* Управление списком контактов (ростер).<br />
* Прием/отправка сообщений.<br />
* Поддержка конференций.<br />
* Поддержка информации о присутствии<br />
* Возможности управления ресурсами.<br />
* Возможность обработки/генерации IQ в сыром виде.<br />
3. Поддержка расширения для получения информации о клиенте.</p>
<p>Ознакомиться с библиотекой, а также скачать исходники можно на сайте:</p>
<p><a href="http://adaforge.qtada.com/cgi-bin/tracker.fcgi/axmpp">http://adaforge.qtada.com/cgi-bin/tracker.fcgi/axmpp</a></p>
<p>AXMPP распространяется под BSD подобной лицезией.</p>
]]></content:encoded>
			<wfw:commentRss>http://ru.ada-community.org/2011/03/09/%d0%b0%d0%bd%d0%be%d0%bd%d1%81-axmpp-0-0-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Типы данных с копированием-при-модификации (оптимизированный вариант)</title>
		<link>http://ru.ada-community.org/2010/09/30/%d1%82%d0%b8%d0%bf%d1%8b-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d1%81-%d0%ba%d0%be%d0%bf%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5%d0%bc-%d0%bf%d1%80%d0%b8-%d0%bc%d0%be%d0%b4%d0%b8%d1%84%d0%b8-2/</link>
		<comments>http://ru.ada-community.org/2010/09/30/%d1%82%d0%b8%d0%bf%d1%8b-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d1%81-%d0%ba%d0%be%d0%bf%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5%d0%bc-%d0%bf%d1%80%d0%b8-%d0%bc%d0%be%d0%b4%d0%b8%d1%84%d0%b8-2/#comments</comments>
		<pubDate>Thu, 30 Sep 2010 20:00:21 +0000</pubDate>
		<dc:creator>Vadim Godunko</dc:creator>
				<category><![CDATA[Статьи]]></category>

		<guid isPermaLink="false">http://ru.ada-community.org/?p=17</guid>
		<description><![CDATA[В прошлой статье была рассмотрена разработка типа данных с копированием-при-модификации, в этот же раз внимание будет уделено оптимизации реализации, в частности: исключено выделение динамической памяти для &#8220;пустого&#8221; совместно используемого объекта; в некоторых случаях исключено выделение динамической памяти для копии объекта при подготовке к модификации; исключено выполнение дорогих операций атомарного инкремента/декремента при использовании &#8220;пустого&#8221; совместно используемого [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">В прошлой статье была рассмотрена разработка типа данных с копированием-при-модификации, в этот же раз внимание будет уделено оптимизации реализации, в частности:</p>
<ul style="text-align: justify;">
<li>исключено выделение динамической памяти для &#8220;пустого&#8221; совместно используемого объекта;</li>
<li>в некоторых случаях исключено выделение динамической памяти для копии объекта при подготовке к модификации;</li>
<li>исключено выполнение дорогих операций атомарного инкремента/декремента при использовании &#8220;пустого&#8221; совместно используемого объекта;</li>
<li>обеспечена возможность категоризации пакета как Preelaborate, а типа данных как Preelaborable_Initialization.</li>
</ul>
<p style="text-align: justify;">Выделяемый при создании каждого объекта сегмент совместно используемой памяти всегда освобождается при установке значения или присваивании объекту значения другого объекта, т.е. фактически всегда он освобождается до использования. Поскольку операция выделения памяти в куче достаточно ресурсоёмкая, желательно исключить ненужные выделения/освобождения сегментов памяти. Сделать это можно разово выделив сегмент памяти для &#8220;пустого&#8221; совместно используемого объекта, например, при предысполнении спецификации пакета.</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;Empty_Shared : Shared_Data_Access := <span style="color: #46aa03; font-weight:bold;">new</span> Shared_Data;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> Holder <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">new</span> Ada.<span style="color: #202020;">Finalization</span>.<span style="color: #202020;">Controlled</span> <span style="color: #46aa03; font-weight:bold;">with</span> <span style="color: #46aa03; font-weight:bold;">record</span><br />
&nbsp; &nbsp; &nbsp; Data : Shared_Data_Access := Empty_Shared;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> <span style="color: #46aa03; font-weight:bold;">record</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">overriding</span> <span style="color: #46aa03; font-weight:bold;">procedure</span> Initialize <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder<span style="color: #66cc66;">&#41;</span>;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">Для корректного подсчёта ссылок необходимо добавить подпрограмму Initialize, задача которой заключается в увеличении счётчика ссылок при инициализации объекта по умолчанию.</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Initialize <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; Reference <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Data</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Initialize;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">Использование разово выделенного при предысполнении сегмента памяти имеет оборотную сторону — пакет более не может быть классифицирован как Preelaborate, а тип данных как Preelaborable_Initialization. Столь жесткая классификация пакета и типа может быть полезна в некоторых применениях (например, при использовании средств распределённых вычислений). Исправить ситуацию возможно за счёт отказа от распределения &#8220;пустого&#8221; совместно используемого сегмента памяти в динамической памяти и распределении его статически.</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;Empty_Shared : <span style="color: #46aa03; font-weight:bold;">aliased</span> Shared_Data := <span style="color: #66cc66;">&#40;</span><span style="color: #46aa03; font-weight:bold;">others</span> =&gt; &lt;&gt;<span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> Holder <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">new</span> Ada.<span style="color: #202020;">Finalization</span>.<span style="color: #202020;">Controlled</span> <span style="color: #46aa03; font-weight:bold;">with</span> <span style="color: #46aa03; font-weight:bold;">record</span><br />
&nbsp; &nbsp; &nbsp; Data : Shared_Data_Access := Empty_Shared'<span style="color: #46aa03; font-weight:bold;">Access</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> <span style="color: #46aa03; font-weight:bold;">record</span>;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">При этом необходимо исключить выполнение освобождения статически выделенного сегмента памяти в подпрограмме Unreference:</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Unreference <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Free <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">new</span> Ada.<span style="color: #202020;">Unchecked_Deallocation</span> <span style="color: #66cc66;">&#40;</span>Shared_Data, Shared_Data_Access<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">if</span> Counters.<span style="color: #202020;">Decrement</span> <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Counter</span>'<span style="color: #46aa03; font-weight:bold;">Access</span><span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #00007f;">if</span> Self /= Empty_Shared'<span style="color: #46aa03; font-weight:bold;">Access</span> <span style="color: #00007f;">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Free <span style="color: #66cc66;">&#40;</span>Self<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #00007f;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Self := <span style="color: #46aa03; font-weight:bold;">null</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Self := <span style="color: #46aa03; font-weight:bold;">null</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Unreference;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">Фактически же получается, что значение счётчика статически распределённого сегмента не представляет никакого интереса. Поскольку операции атомарного инкремента/декремента значительно более ресурсоёмки нежели проверка значения и переход, вполне логично полностью отказаться от поддержания значения счётчика для статически выделенного сегмента в актуальном состоянии, для чего можно переписать реализацию Reference и Unreference (обратите внимание на использование короткозамкнутой формы логических операций, гарантирующей последовательность вычисления предикатов):</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Reference <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">if</span> Self /= Empty_Shared'<span style="color: #46aa03; font-weight:bold;">Access</span> <span style="color: #00007f;">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Counters.<span style="color: #202020;">Increment</span> <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Counter</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Reference;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Unreference <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">procedure</span> Free <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">new</span> Ada.<span style="color: #202020;">Unchecked_Deallocation</span> <span style="color: #66cc66;">&#40;</span>Shared_Data, Shared_Data_Access<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">if</span> Self /= Empty_Shared'<span style="color: #46aa03; font-weight:bold;">Access</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">and</span> <span style="color: #00007f;">then</span> Counters.<span style="color: #202020;">Decrement</span> <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Counter</span>'<span style="color: #46aa03; font-weight:bold;">Access</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Free <span style="color: #66cc66;">&#40;</span>Self<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Self := <span style="color: #46aa03; font-weight:bold;">null</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Unreference;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">Теперь обратив внимание на выделение динамической памяти при подготовке к модификации значения в подпрограмме Detach. Сейчас подготовка к модификации заключается в выделении нового сегмента для совместно используемого объекта в динамической памяти. Однако, если значение счётчика равно единице, то такое выделение не имеет смысла, поскольку старый объект будет освобождён непоследственно после копирования значения; а следовательно можно использовать старый объект, не только исключив выделение динамической памяти, но и сэкономив на выполнении копирования данных. Отметим, что подготавливаемый к модификации объект не должен быть статически выделенным &#8220;пустым&#8221; объектом, в противном случае всё же необходимо выделение нового объекта.</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Detach <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; &nbsp; Old : Shared_Data_Access := Self;<br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">if</span> Self = Empty_Shared'<span style="color: #46aa03; font-weight:bold;">Access</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">or</span> <span style="color: #00007f;">else</span> <span style="color: #0000ff;">not</span> Counters.<span style="color: #202020;">Is_One</span> <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Counter</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Self := <span style="color: #46aa03; font-weight:bold;">new</span> Shared_Data'<span style="color: #66cc66;">&#40;</span>Counter =&gt; &lt;&gt;, Value =&gt; Old.<span style="color: #202020;">Value</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Unreference <span style="color: #66cc66;">&#40;</span>Old<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Detach;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">Теперь пришло время привести полный исходные текст спецификации и реализации пакета.</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #46aa03; font-weight:bold;">private</span> <span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Finalization</span>;<br />
<span style="color: #46aa03; font-weight:bold;">private</span> <span style="color: #46aa03; font-weight:bold;">with</span> Counters;<br />
<br />
<span style="color: #46aa03; font-weight:bold;">generic</span><br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> T <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">private</span>;<br />
<span style="color: #46aa03; font-weight:bold;">package</span> Holders <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">pragma</span> Preelaborate;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> Holder <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">private</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">pragma</span> Preelaborable_Initialization <span style="color: #66cc66;">&#40;</span>Holder<span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp;Empty : <span style="color: #46aa03; font-weight:bold;">constant</span> Holder;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Set <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder; Value : T<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">function</span> Get <span style="color: #66cc66;">&#40;</span>Self : Holder<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">return</span> T;<br />
<br />
<span style="color: #46aa03; font-weight:bold;">private</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> Shared_Data <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">record</span><br />
&nbsp; &nbsp; &nbsp; Counter : <span style="color: #46aa03; font-weight:bold;">aliased</span> Counters.<span style="color: #202020;">Counter</span>;<br />
&nbsp; &nbsp; &nbsp; Value &nbsp; : T;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> <span style="color: #46aa03; font-weight:bold;">record</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> Shared_Data_Access <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">access</span> <span style="color: #46aa03; font-weight:bold;">all</span> Shared_Data;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Reference <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Unreference <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Detach <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp;Empty_Shared : <span style="color: #46aa03; font-weight:bold;">aliased</span> Shared_Data := <span style="color: #66cc66;">&#40;</span><span style="color: #46aa03; font-weight:bold;">others</span> =&gt; &lt;&gt;<span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> Holder <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">new</span> Ada.<span style="color: #202020;">Finalization</span>.<span style="color: #202020;">Controlled</span> <span style="color: #46aa03; font-weight:bold;">with</span> <span style="color: #46aa03; font-weight:bold;">record</span><br />
&nbsp; &nbsp; &nbsp; Data : Shared_Data_Access := Empty_Shared'<span style="color: #46aa03; font-weight:bold;">Access</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> <span style="color: #46aa03; font-weight:bold;">record</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">overriding</span> <span style="color: #46aa03; font-weight:bold;">procedure</span> Adjust <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">overriding</span> <span style="color: #46aa03; font-weight:bold;">procedure</span> Finalize <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder<span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp;Empty : <span style="color: #46aa03; font-weight:bold;">constant</span> Holder<br />
&nbsp; &nbsp; &nbsp;:= <span style="color: #66cc66;">&#40;</span>Ada.<span style="color: #202020;">Finalization</span>.<span style="color: #202020;">Controlled</span> <span style="color: #46aa03; font-weight:bold;">with</span> <span style="color: #46aa03; font-weight:bold;">others</span> =&gt; &lt;&gt;<span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #00007f;">end</span> Holders;</div></td></tr></tbody></table></div>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br />80<br />81<br />82<br />83<br />84<br />85<br />86<br />87<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Unchecked_Deallocation</span>;<br />
<br />
<span style="color: #46aa03; font-weight:bold;">package</span> <span style="color: #46aa03; font-weight:bold;">body</span> Holders <span style="color: #00007f;">is</span><br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">------------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Adjust --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">------------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">overriding</span> <span style="color: #46aa03; font-weight:bold;">procedure</span> Adjust <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; Reference <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Data</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Adjust;<br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">------------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Detach --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">------------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Detach <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; &nbsp; Old : Shared_Data_Access := Self;<br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">if</span> Self = Empty_Shared'<span style="color: #46aa03; font-weight:bold;">Access</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">or</span> <span style="color: #00007f;">else</span> <span style="color: #0000ff;">not</span> Counters.<span style="color: #202020;">Is_One</span> <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Counter</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Self := <span style="color: #46aa03; font-weight:bold;">new</span> Shared_Data'<span style="color: #66cc66;">&#40;</span>Counter =&gt; &lt;&gt;, Value =&gt; Old.<span style="color: #202020;">Value</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Unreference <span style="color: #66cc66;">&#40;</span>Old<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Detach;<br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">--------------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Finalize --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">--------------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">overriding</span> <span style="color: #46aa03; font-weight:bold;">procedure</span> Finalize <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">if</span> Self.<span style="color: #202020;">Data</span> /= <span style="color: #46aa03; font-weight:bold;">null</span> <span style="color: #00007f;">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Unreference <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Data</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Finalize;<br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Get --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">function</span> Get <span style="color: #66cc66;">&#40;</span>Self : Holder<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">return</span> T <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">return</span> Self.<span style="color: #202020;">Data</span>.<span style="color: #202020;">Value</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Get;<br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Reference --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Reference <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">if</span> Self /= Empty_Shared'<span style="color: #46aa03; font-weight:bold;">Access</span> <span style="color: #00007f;">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Counters.<span style="color: #202020;">Increment</span> <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Counter</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Reference;<br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Set --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Set <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder; Value : T<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; Detach <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Data</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; Self.<span style="color: #202020;">Data</span>.<span style="color: #202020;">Value</span> := Value;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Set;<br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-----------------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Unreference --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-----------------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Unreference <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">procedure</span> Free <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">new</span> Ada.<span style="color: #202020;">Unchecked_Deallocation</span> <span style="color: #66cc66;">&#40;</span>Shared_Data, Shared_Data_Access<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">if</span> Self /= Empty_Shared'<span style="color: #46aa03; font-weight:bold;">Access</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">and</span> <span style="color: #00007f;">then</span> Counters.<span style="color: #202020;">Decrement</span> <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Counter</span>'<span style="color: #46aa03; font-weight:bold;">Access</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Free <span style="color: #66cc66;">&#40;</span>Self<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Self := <span style="color: #46aa03; font-weight:bold;">null</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Unreference;<br />
<br />
<span style="color: #00007f;">end</span> Holders;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">И дать ссылку на архив исходных текстов [download id="3"].</p>
]]></content:encoded>
			<wfw:commentRss>http://ru.ada-community.org/2010/09/30/%d1%82%d0%b8%d0%bf%d1%8b-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d1%81-%d0%ba%d0%be%d0%bf%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5%d0%bc-%d0%bf%d1%80%d0%b8-%d0%bc%d0%be%d0%b4%d0%b8%d1%84%d0%b8-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>QtAda: Как подавить предупреждения компилятора о неизвестных прагмах Q_Slot и Q_Signal</title>
		<link>http://ru.ada-community.org/2010/09/23/qtada-%d0%ba%d0%b0%d0%ba-%d0%bf%d0%be%d0%b4%d0%b0%d0%b2%d0%b8%d1%82%d1%8c-%d0%bf%d1%80%d0%b5%d0%b4%d1%83%d0%bf%d1%80%d0%b5%d0%b6%d0%b4%d0%b5%d0%bd%d0%b8%d1%8f-%d0%ba%d0%be%d0%bc%d0%bf%d0%b8%d0%bb/</link>
		<comments>http://ru.ada-community.org/2010/09/23/qtada-%d0%ba%d0%b0%d0%ba-%d0%bf%d0%be%d0%b4%d0%b0%d0%b2%d0%b8%d1%82%d1%8c-%d0%bf%d1%80%d0%b5%d0%b4%d1%83%d0%bf%d1%80%d0%b5%d0%b6%d0%b4%d0%b5%d0%bd%d0%b8%d1%8f-%d0%ba%d0%be%d0%bc%d0%bf%d0%b8%d0%bb/#comments</comments>
		<pubDate>Thu, 23 Sep 2010 20:00:02 +0000</pubDate>
		<dc:creator>Vadim Godunko</dc:creator>
				<category><![CDATA[Статьи]]></category>

		<guid isPermaLink="false">http://ru.ada-community.org/?p=15</guid>
		<description><![CDATA[При компиляции программ, использующих QtAda нередко встречаются диагностические сообщения компилятора о неизвестных прагмах Q_Slot и Q_Signal. Эти прагмы предназначены для компилятора метаинформации, а соответствующие предупреждения компилятора не являются актуальными; более того, они не позволяют использовать режим компилятора при котором любые предупреждения рассматриваются как ошибки. Простейшим способом подавления этих предупреждений является отключение предупреждений перед прагмами Q_Slot [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">При компиляции программ, использующих QtAda нередко встречаются диагностические сообщения компилятора о неизвестных прагмах Q_Slot и Q_Signal. Эти прагмы предназначены для компилятора метаинформации, а соответствующие предупреждения компилятора не являются актуальными; более того, они не позволяют использовать режим компилятора при котором любые предупреждения рассматриваются как ошибки.</p>
<p style="text-align: justify;">Простейшим способом подавления этих предупреждений является отключение предупреждений перед прагмами Q_Slot и Q_Signal и включение предупреждений сразу же после прагм. Для этого возможно использовать прагму Warnings:</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> My_Slot <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> <span style="color: #46aa03; font-weight:bold;">access</span> My_Widget'Class<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">pragma</span> Warnings <span style="color: #66cc66;">&#40;</span>Off<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">pragma</span> Q_Slot <span style="color: #66cc66;">&#40;</span>My_Slot<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">pragma</span> Warnings <span style="color: #66cc66;">&#40;</span>On<span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> My_Signal <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> <span style="color: #46aa03; font-weight:bold;">access</span> My_Widget'Class<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">pragma</span> Warnings <span style="color: #66cc66;">&#40;</span>Off<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">pragma</span> Q_Signal <span style="color: #66cc66;">&#40;</span>My_Signal<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">pragma</span> Warnings <span style="color: #66cc66;">&#40;</span>On<span style="color: #66cc66;">&#41;</span>;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">Серьёзным недостатком этого способа является нарушение читаемости кода за счёт наличия дополнительных прагм. При использовании компилятора GNAT GPL 2010 можно использовать особую форму прагмы Warnings, позволяющую отключить не все, а только конкретные предупреждения. В этом случае в контексте пакета можно написать:</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #46aa03; font-weight:bold;">pragma</span> Warnings <span style="color: #66cc66;">&#40;</span>Off, <span style="color: #7f007f;">&quot;unrecognized pragma &quot;</span><span style="color: #7f007f;">&quot;Q_Slot&quot;</span><span style="color: #7f007f;">&quot;&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #46aa03; font-weight:bold;">pragma</span> Warnings <span style="color: #66cc66;">&#40;</span>Off, <span style="color: #7f007f;">&quot;unrecognized pragma &quot;</span><span style="color: #7f007f;">&quot;Q_Signal&quot;</span><span style="color: #7f007f;">&quot;&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #46aa03; font-weight:bold;">package</span> My_Widgets <span style="color: #00007f;">is</span></div></td></tr></tbody></table></div>
<p style="text-align: justify;">Этот способ подходит для приложений в которых не используется большое количество собственных классов объектов, в противном случае указанные прагмы необходимо включать в любой пакет где объявляется порождённый от Q_Object тип, что тоже не очень приятно. Поэтому пожалуй самым интересным является глобальное отключение этих предупреждений с использованием файла конфигурации. Для этого необходимо создать файл конфигурации, например qtada.adc, следующего содержания:</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #46aa03; font-weight:bold;">pragma</span> Warnings <span style="color: #66cc66;">&#40;</span>Off, <span style="color: #7f007f;">&quot;unrecognized pragma &quot;</span><span style="color: #7f007f;">&quot;Q_Slot&quot;</span><span style="color: #7f007f;">&quot;&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #46aa03; font-weight:bold;">pragma</span> Warnings <span style="color: #66cc66;">&#40;</span>Off, <span style="color: #7f007f;">&quot;unrecognized pragma &quot;</span><span style="color: #7f007f;">&quot;Q_Signal&quot;</span><span style="color: #7f007f;">&quot;&quot;</span><span style="color: #66cc66;">&#41;</span>;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">Теперь осталось проинструктировать копилятор о необходимости использования файла конфигурации. Это возможно сделать с помошью ключа -gnatec=qtada.adc (если вызов компилятора выполняется напрямую) или же просто добавив атрибут Global_Configuration_Pragmas пакета Builder в файл проекта:</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">package</span> Builder <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">for</span> Global_Configuration_Pragmas <span style="color: #46aa03; font-weight:bold;">use</span> <span style="color: #7f007f;">&quot;qtada.adc&quot;</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Builder;</div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss>http://ru.ada-community.org/2010/09/23/qtada-%d0%ba%d0%b0%d0%ba-%d0%bf%d0%be%d0%b4%d0%b0%d0%b2%d0%b8%d1%82%d1%8c-%d0%bf%d1%80%d0%b5%d0%b4%d1%83%d0%bf%d1%80%d0%b5%d0%b6%d0%b4%d0%b5%d0%bd%d0%b8%d1%8f-%d0%ba%d0%be%d0%bc%d0%bf%d0%b8%d0%bb/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Типы данных с копированием-при-модификации (простой вариант)</title>
		<link>http://ru.ada-community.org/2010/09/16/%d1%82%d0%b8%d0%bf%d1%8b-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d1%81-%d0%ba%d0%be%d0%bf%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5%d0%bc-%d0%bf%d1%80%d0%b8-%d0%bc%d0%be%d0%b4%d0%b8%d1%84%d0%b8/</link>
		<comments>http://ru.ada-community.org/2010/09/16/%d1%82%d0%b8%d0%bf%d1%8b-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d1%81-%d0%ba%d0%be%d0%bf%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5%d0%bc-%d0%bf%d1%80%d0%b8-%d0%bc%d0%be%d0%b4%d0%b8%d1%84%d0%b8/#comments</comments>
		<pubDate>Thu, 16 Sep 2010 20:00:53 +0000</pubDate>
		<dc:creator>Vadim Godunko</dc:creator>
				<category><![CDATA[Статьи]]></category>

		<guid isPermaLink="false">http://ru.ada-community.org/?p=12</guid>
		<description><![CDATA[Типы данных с копированием-при-модификации находят широкое применение в современной программной индустрии с целью упрощения управления и минимизации объёма использованной динамической памяти. Менее известными, но подчас более важными свойствами таких типов данных является константное время выполнения операции присваивания и использование небольшого и независящего от фактического размера данных объёма памяти стэка, используемой для объектов. Для реализации обычно [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Типы данных с копированием-при-модификации находят широкое применение в современной программной индустрии с целью упрощения управления и минимизации объёма использованной динамической памяти. Менее известными, но подчас более важными свойствами таких типов данных является константное время выполнения операции присваивания и использование небольшого и независящего от фактического размера данных объёма памяти стэка, используемой для объектов.</p>
<p style="text-align: justify;">Для реализации обычно используется технология неявного совместного использования данных, когда объект хранит только ссылку на сегмент совместно используемых данных, а управление освобождением сегмента совместно используемых данных осуществляется с использованием счётчика ссылок. В общем случае эта технология имеет одно важное ограничение, не позволяющее активно использовать её в Ada программах — сегмент совместно используемых данных не должен использоваться более чем одной задачей. Для снятия этого ограничения достаточно защитить счётчик ссылок от одновременного доступа несколькими задачами. В предыдущей статье обуждался вопрос эффективной реализации атомарного счётчика ссылок с достаточной степенью переносимости, что даёт возможность создания эффективной реализации типов данных с копированием-при-модификации.</p>
<p style="text-align: justify;">В качестве примера будем рассматривать упрощённый аналог стандартного контейнера Ada.Containers.Holders, предназначенный для хранения одного значения определённого при настройке типа данных. Для хранения данных будем использовать структуру данных, состоящую из двух полей: атомарного счётчика ссылок и значения. Над ссылочным типом на эту структуру необходимо иметь три базовые операции:</p>
<ul>
<li style="text-align: justify;">Reference, увеличивающую счётчик ссылок на единицу;</li>
<li style="text-align: justify;">Unreference, уменьшающую счётчик ссылок на единицу и освобождающую совместно используемый объект при достижении счётчиком нулевого значения;</li>
<li style="text-align: justify;">Detach, выполняющую создание копии объекта для последующей модификации.</li>
</ul>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> Shared_Data <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">record</span><br />
&nbsp; &nbsp; &nbsp; Counter : <span style="color: #46aa03; font-weight:bold;">aliased</span> Counters.<span style="color: #202020;">Counter</span>;<br />
&nbsp; &nbsp; &nbsp; Value &nbsp; : T;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> <span style="color: #46aa03; font-weight:bold;">record</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> Shared_Data_Access <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">access</span> <span style="color: #46aa03; font-weight:bold;">all</span> Shared_Data;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Reference <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Unreference <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Detach <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span>;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">Реализация подпрограммы Reference содержит исключительно вызов подпрограммы увеличения значения счётчика. Для исключения необходимости проверки факта переполнения счётчика предполагается, что он способен хранить достаточно большое значение достигнуть которое невозможно:</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Reference <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; Counters.<span style="color: #202020;">Increment</span> <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Counter</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Reference;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">Реализация подпрограммы Unreference вызывает функцию декремента значения счётчика и освобождает задействованный под совместно используемые данные сегмент при достижении счётчиком нулевого значения; в противном случае она просто сбрасывает переданный указатель на значение null (то же самое делает и вызов функции Free):</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; <span style="color: #46aa03; font-weight:bold;">procedure</span> Unreference <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">procedure</span> Free <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">new</span> Ada.<span style="color: #202020;">Unchecked_Deallocation</span> <span style="color: #66cc66;">&#40;</span>Shared_Data, Shared_Data_Access<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">if</span> Counters.<span style="color: #202020;">Decrement</span> <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Counter</span>'<span style="color: #46aa03; font-weight:bold;">Access</span><span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Free <span style="color: #66cc66;">&#40;</span>Self<span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Self := <span style="color: #46aa03; font-weight:bold;">null</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Unreference;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">Подпрограмму Detach можно реализовать весьма просто, как создание нового объекта совместно используемых данных с инициализацией имеющимся значением:</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Detach <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; &nbsp; Old : Shared_Data_Access := Self;<br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; Self := <span style="color: #46aa03; font-weight:bold;">new</span> Shared_Data'<span style="color: #66cc66;">&#40;</span>Counter =&gt; &lt;&gt;, Value =&gt; Old.<span style="color: #202020;">Value</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; Unreference <span style="color: #66cc66;">&#40;</span>Old<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Detach;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">Интерфейс настраиваемого пакета состоит из типа-контейнера, константы этого типа, представляющей &#8220;пустое&#8221; значение и подпрограмм для установки и получения значения; тип-контейнер является контролируемым и для него переопределяются стандартные подпрограммы Adjust (копирование) и Finalize (деструктор):</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #46aa03; font-weight:bold;">private</span> <span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Finalization</span>;<br />
<span style="color: #46aa03; font-weight:bold;">private</span> <span style="color: #46aa03; font-weight:bold;">with</span> Counters;<br />
<br />
<span style="color: #46aa03; font-weight:bold;">generic</span><br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> T <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">private</span>;<br />
<span style="color: #46aa03; font-weight:bold;">package</span> Holders <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> Holder <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">private</span>;<br />
&nbsp; &nbsp;Empty : <span style="color: #46aa03; font-weight:bold;">constant</span> Holder;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Set <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder; Value : T<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">function</span> Get <span style="color: #66cc66;">&#40;</span>Self : Holder<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">return</span> T;<br />
<span style="color: #46aa03; font-weight:bold;">private</span><br />
&nbsp; &nbsp;...<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> Holder <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">new</span> Ada.<span style="color: #202020;">Finalization</span>.<span style="color: #202020;">Controlled</span> <span style="color: #46aa03; font-weight:bold;">with</span> <span style="color: #46aa03; font-weight:bold;">record</span><br />
&nbsp; &nbsp; &nbsp; Data : Shared_Data_Access := <span style="color: #46aa03; font-weight:bold;">new</span> Shared_Data;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> <span style="color: #46aa03; font-weight:bold;">record</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">overriding</span> <span style="color: #46aa03; font-weight:bold;">procedure</span> Adjust <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">overriding</span> <span style="color: #46aa03; font-weight:bold;">procedure</span> Finalize <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder<span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp;Empty : <span style="color: #46aa03; font-weight:bold;">constant</span> Holder := <span style="color: #66cc66;">&#40;</span>Ada.<span style="color: #202020;">Finalization</span>.<span style="color: #202020;">Controlled</span> <span style="color: #46aa03; font-weight:bold;">with</span> <span style="color: #46aa03; font-weight:bold;">others</span> =&gt; &lt;&gt;<span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #00007f;">end</span> Holders;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">Тип Holder содержит одно единственное поле &#8211; ссылку на совместно испольуемый объект данных. Это поле автоматически инициализируется при создании объекта типа Holder ссылкой на выделенный совместно используемый объект. Поскольку, согласно соглашению, счётчик автоматически инициализируется значением 1 нет необходимости увеличивать его значение и переопределять подпрограмму Initialize.</p>
<p style="text-align: justify;">Подпрограмма Adjust выполняет вызов описанной выше подпрограммы Reference:</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">overriding</span> <span style="color: #46aa03; font-weight:bold;">procedure</span> Adjust <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; Reference <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Data</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Adjust;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">Подпрограмма Finalize выполняет вызов подпрограммы Unreference, но необходимо помнить, что язык позволяет осуществлять вызов этой подпрограммы многократно (что имеет место быть в условиях хитросплетённых ситуаций очистки при выявлении непредвиденного поведения программы), поэтому перед вызовом Unreference внутренняя ссылка проверяется на ненулевое значение (значение указателя сбрасывается в null при выполнении подпрограммы Unreference):</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">overriding</span> <span style="color: #46aa03; font-weight:bold;">procedure</span> Finalize <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">if</span> Self.<span style="color: #202020;">Data</span> /= <span style="color: #46aa03; font-weight:bold;">null</span> <span style="color: #00007f;">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Unreference <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Data</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Finalize;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">Подпрограмма Get возвращает хранящееся в совместно используемом объекте значение.</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">function</span> Get <span style="color: #66cc66;">&#40;</span>Self : Holder<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">return</span> T <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">return</span> Self.<span style="color: #202020;">Data</span>.<span style="color: #202020;">Value</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Get;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">Подпрограмма Set устанавливает значение внутри совместно используемого объекта, но перед этим выполняет вызов подпрограммы Detach для создания собственной копии данных.</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Set <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder; Value : T<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; Detach <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Data</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; Self.<span style="color: #202020;">Data</span>.<span style="color: #202020;">Value</span> := Value;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Set;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">Как видно из примера, шаблон реализации типов с копированием-при-модификации достаточно прост. Отметим, что рассмотренная реализация  может быть усовершенствована для повышения производительности, эффективности использования памяти, возможности использования в пакетах категории Preelaborate, а в некоторых случаях и для использования Preelaborable_Initialization типов. Вопросы возможной оптимизации будут рассмотрены в следующей статье.</p>
<p style="text-align: justify;">В заключение приводится полный исходный текст примера:</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #46aa03; font-weight:bold;">private</span> <span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Finalization</span>;<br />
<span style="color: #46aa03; font-weight:bold;">private</span> <span style="color: #46aa03; font-weight:bold;">with</span> Counters;<br />
<br />
<span style="color: #46aa03; font-weight:bold;">generic</span><br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> T <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">private</span>;<br />
<br />
<span style="color: #46aa03; font-weight:bold;">package</span> Holders <span style="color: #00007f;">is</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> Holder <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">private</span>;<br />
&nbsp; &nbsp;Empty : <span style="color: #46aa03; font-weight:bold;">constant</span> Holder;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Set <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder; Value : T<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">function</span> Get <span style="color: #66cc66;">&#40;</span>Self : Holder<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">return</span> T;<br />
<br />
<span style="color: #46aa03; font-weight:bold;">private</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> Shared_Data <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">record</span><br />
&nbsp; &nbsp; &nbsp; Counter : <span style="color: #46aa03; font-weight:bold;">aliased</span> Counters.<span style="color: #202020;">Counter</span>;<br />
&nbsp; &nbsp; &nbsp; Value &nbsp; : T;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> <span style="color: #46aa03; font-weight:bold;">record</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> Shared_Data_Access <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">access</span> <span style="color: #46aa03; font-weight:bold;">all</span> Shared_Data;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Reference <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Unreference <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Detach <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> Holder <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">new</span> Ada.<span style="color: #202020;">Finalization</span>.<span style="color: #202020;">Controlled</span> <span style="color: #46aa03; font-weight:bold;">with</span> <span style="color: #46aa03; font-weight:bold;">record</span><br />
&nbsp; &nbsp; &nbsp; Data : Shared_Data_Access := <span style="color: #46aa03; font-weight:bold;">new</span> Shared_Data;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> <span style="color: #46aa03; font-weight:bold;">record</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">overriding</span> <span style="color: #46aa03; font-weight:bold;">procedure</span> Adjust <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">overriding</span> <span style="color: #46aa03; font-weight:bold;">procedure</span> Finalize <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder<span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp;Empty : <span style="color: #46aa03; font-weight:bold;">constant</span> Holder<br />
&nbsp; &nbsp; &nbsp;:= <span style="color: #66cc66;">&#40;</span>Ada.<span style="color: #202020;">Finalization</span>.<span style="color: #202020;">Controlled</span> <span style="color: #46aa03; font-weight:bold;">with</span> <span style="color: #46aa03; font-weight:bold;">others</span> =&gt; &lt;&gt;<span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #00007f;">end</span> Holders;</div></td></tr></tbody></table></div>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #46aa03; font-weight:bold;">with</span> Ada.<span style="color: #202020;">Unchecked_Deallocation</span>;<br />
<br />
<span style="color: #46aa03; font-weight:bold;">package</span> <span style="color: #46aa03; font-weight:bold;">body</span> Holders <span style="color: #00007f;">is</span><br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">------------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Adjust --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">------------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">overriding</span> <span style="color: #46aa03; font-weight:bold;">procedure</span> Adjust <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; Reference <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Data</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Adjust;<br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">------------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Detach --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">------------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Detach <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; &nbsp; Old : Shared_Data_Access := Self;<br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; Self := <span style="color: #46aa03; font-weight:bold;">new</span> Shared_Data'<span style="color: #66cc66;">&#40;</span>Counter =&gt; &lt;&gt;, Value =&gt; Old.<span style="color: #202020;">Value</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; Unreference <span style="color: #66cc66;">&#40;</span>Old<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Detach;<br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">--------------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Finalize --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">--------------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">overriding</span> <span style="color: #46aa03; font-weight:bold;">procedure</span> Finalize <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">if</span> Self.<span style="color: #202020;">Data</span> /= <span style="color: #46aa03; font-weight:bold;">null</span> <span style="color: #00007f;">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Unreference <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Data</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Finalize;<br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Get --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">function</span> Get <span style="color: #66cc66;">&#40;</span>Self : Holder<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">return</span> T <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">return</span> Self.<span style="color: #202020;">Data</span>.<span style="color: #202020;">Value</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Get;<br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Reference --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Reference <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; Counters.<span style="color: #202020;">Increment</span> <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Counter</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Reference;<br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Set --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Set <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Holder; Value : T<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; Detach <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Data</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; Self.<span style="color: #202020;">Data</span>.<span style="color: #202020;">Value</span> := Value;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Set;<br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-----------------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Unreference --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-----------------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Unreference <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Shared_Data_Access<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">procedure</span> Free <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">new</span> Ada.<span style="color: #202020;">Unchecked_Deallocation</span> <span style="color: #66cc66;">&#40;</span>Shared_Data, Shared_Data_Access<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">if</span> Counters.<span style="color: #202020;">Decrement</span> <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Counter</span>'<span style="color: #46aa03; font-weight:bold;">Access</span><span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Free <span style="color: #66cc66;">&#40;</span>Self<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Self := <span style="color: #46aa03; font-weight:bold;">null</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">end</span> <span style="color: #00007f;">if</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Unreference;<br />
<br />
<span style="color: #00007f;">end</span> Holders;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">Полный комплект исходных текстов можно скачать по ссылке [download id="2"].</p>
]]></content:encoded>
			<wfw:commentRss>http://ru.ada-community.org/2010/09/16/%d1%82%d0%b8%d0%bf%d1%8b-%d0%b4%d0%b0%d0%bd%d0%bd%d1%8b%d1%85-%d1%81-%d0%ba%d0%be%d0%bf%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5%d0%bc-%d0%bf%d1%80%d0%b8-%d0%bc%d0%be%d0%b4%d0%b8%d1%84%d0%b8/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Портируемая реализация атомарного счётчика</title>
		<link>http://ru.ada-community.org/2010/09/10/%d0%bf%d0%be%d1%80%d1%82%d0%b8%d1%80%d1%83%d0%b5%d0%bc%d0%b0%d1%8f-%d1%80%d0%b5%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%b0%d1%82%d0%be%d0%bc%d0%b0%d1%80%d0%bd%d0%be%d0%b3%d0%be-%d1%81/</link>
		<comments>http://ru.ada-community.org/2010/09/10/%d0%bf%d0%be%d1%80%d1%82%d0%b8%d1%80%d1%83%d0%b5%d0%bc%d0%b0%d1%8f-%d1%80%d0%b5%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%b0%d1%82%d0%be%d0%bc%d0%b0%d1%80%d0%bd%d0%be%d0%b3%d0%be-%d1%81/#comments</comments>
		<pubDate>Fri, 10 Sep 2010 20:00:54 +0000</pubDate>
		<dc:creator>Vadim Godunko</dc:creator>
				<category><![CDATA[Статьи]]></category>

		<guid isPermaLink="false">http://ru.ada-community.org/?p=1</guid>
		<description><![CDATA[Для решения некоторых задач на современных многопроцессорных и многоядерных вычислительных машинах требуются счётчики, значение которых может увеличиваться и уменьшаться одновременно из нескольких задач, при этом не разрушая значения и не затирая изменённое другой задачей значение. В качестве примера будем рассматривать тип данных-счётчик, инициализируемый начальным значением 1, и три операции над ним: Increment — увеличивает значение [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Для решения некоторых задач на современных многопроцессорных и многоядерных вычислительных машинах требуются счётчики, значение которых может увеличиваться и уменьшаться одновременно из нескольких задач, при этом не разрушая значения и не затирая изменённое другой задачей значение.</p>
<p style="text-align: justify;">В качестве примера будем рассматривать тип данных-счётчик, инициализируемый начальным значением 1, и три операции над ним:</p>
<ul>
<li>
<p style="text-align: justify;">Increment — увеличивает значение счётчика на единицу;</p>
</li>
<li>
<p style="text-align: justify;">Decrement — уменьшает значение счётчика на единицу, возвращает True если значение  достигло нуля, в противном случае возвращает False;</p>
</li>
<li>
<p style="text-align: justify;">Is_One — проверяет текущее значение счётчика, возвращает True если оно равно единице, в противном случае возвращает False.</p>
</li>
</ul>
<p>Поставленная задача может быть решена встроенными средствами языка, например так:</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #46aa03; font-weight:bold;">with</span> Interfaces;<br />
<br />
<span style="color: #46aa03; font-weight:bold;">package</span> Counters <span style="color: #00007f;">is</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> Counter <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">limited</span> <span style="color: #46aa03; font-weight:bold;">private</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Increment <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Counter<span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">function</span> Decrement <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> <span style="color: #46aa03; font-weight:bold;">access</span> Counter<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">return</span> Boolean;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">function</span> Is_One <span style="color: #66cc66;">&#40;</span>Self : Counter<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">return</span> Boolean;<br />
<br />
<span style="color: #46aa03; font-weight:bold;">private</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">protected</span> <span style="color: #46aa03; font-weight:bold;">type</span> Counter <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">procedure</span> Increment;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">procedure</span> Decrement <span style="color: #66cc66;">&#40;</span>Is_Zero : <span style="color: #46aa03; font-weight:bold;">out</span> Boolean<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">function</span> Is_One <span style="color: #00007f;">return</span> Boolean;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">private</span><br />
&nbsp; &nbsp; &nbsp; Value : Interfaces.<span style="color: #202020;">Unsigned_32</span> := <span style="color: #ff0000;">1</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Counter;<br />
<br />
<span style="color: #00007f;">end</span> Counters;</div></td></tr></tbody></table></div>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #46aa03; font-weight:bold;">package</span> <span style="color: #46aa03; font-weight:bold;">body</span> Counters <span style="color: #00007f;">is</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">use</span> <span style="color: #46aa03; font-weight:bold;">type</span> Interfaces.<span style="color: #202020;">Unsigned_32</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-------------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Counter --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-------------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">protected</span> <span style="color: #46aa03; font-weight:bold;">body</span> Counter <span style="color: #00007f;">is</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #adadad; font-style: italic;">---------------</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #adadad; font-style: italic;">-- Decrement --</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #adadad; font-style: italic;">---------------</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">procedure</span> Decrement <span style="color: #66cc66;">&#40;</span>Is_Zero : <span style="color: #46aa03; font-weight:bold;">out</span> Boolean<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Value &nbsp; := Value - <span style="color: #ff0000;">1</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Is_Zero := Value = <span style="color: #ff0000;">0</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">end</span> Decrement;<br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #adadad; font-style: italic;">---------------</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #adadad; font-style: italic;">-- Increment --</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #adadad; font-style: italic;">---------------</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">procedure</span> Increment <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Value := Value + <span style="color: #ff0000;">1</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">end</span> Increment;<br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #adadad; font-style: italic;">------------</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #adadad; font-style: italic;">-- Is_One --</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #adadad; font-style: italic;">------------</span><br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">function</span> Is_One <span style="color: #00007f;">return</span> Boolean <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #00007f;">return</span> Value = <span style="color: #ff0000;">1</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">end</span> Is_One;<br />
<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Counter;<br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Decrement --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">function</span> Decrement <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> <span style="color: #46aa03; font-weight:bold;">access</span> Counter<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">return</span> Boolean <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp; &nbsp; Is_Zero : Boolean;<br />
<br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; Self.<span style="color: #202020;">Decrement</span> <span style="color: #66cc66;">&#40;</span>Is_Zero<span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">return</span> Is_Zero;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Decrement;<br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Increment --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Increment <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Counter<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; Self.<span style="color: #202020;">Increment</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Increment;<br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">------------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Is_One --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">------------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">function</span> Is_One <span style="color: #66cc66;">&#40;</span>Self : Counter<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">return</span> Boolean <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">return</span> Self.<span style="color: #202020;">Is_One</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Is_One;<br />
<br />
<span style="color: #00007f;">end</span> Counters;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">В этом варианте реализации для защиты текущего значения счётчика используется защищённый тип. Это пожалуй самый портируемый вариант решения, однако обладающий серьёзным недостатком &#8211; низкой эффективностью, поскольку реализация защищённых типов как правило использует механизмы межпроцессного взаимодействия.</p>
<p style="text-align: justify;">Значительно интереснее было бы использовать аппаратную поддержку операций атомарного инкремента/декремента, присутствующую в большинстве современных процессоров. Это, однако, требует включения в код ассемблерных вставок, что приводит к невозможности легкого портирования кода. Тем не менее, пользователи компилятора GNAT имеют возможность использовать встроенные функции GCC для выполнения атомарных операций инкремента/декремента. Их использование не делает код портируемым между GNAT-ом и другим компилятором, но позволяет использовать его на большом количестве современных процессоров (среди которых Alpha, IA64, PowerPC, SPARC V9, X86-64).</p>
<p style="text-align: justify;">Семейство встроенных функций GCC для инкремента именуется как __sync_add_and_fetch_X, а для декремента значения как __sync_sub_and_fetch_X, где X &#8211; размер операнда в байтах. В Ada эти операции могут быть импортированы с указанием соглашения Intrinsic:</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Sync_Add_And_Fetch<br />
&nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span>Ptr &nbsp; : <span style="color: #46aa03; font-weight:bold;">access</span> Interfaces.<span style="color: #202020;">Unsigned_32</span>;<br />
&nbsp; &nbsp; &nbsp; Value : Interfaces.<span style="color: #202020;">Unsigned_32</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">pragma</span> Import<br />
&nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span>Intrinsic, Sync_Add_And_Fetch, <span style="color: #7f007f;">&quot;__sync_add_and_fetch_4&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">function</span> Sync_Sub_And_Fetch<br />
&nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span>Ptr &nbsp; : <span style="color: #46aa03; font-weight:bold;">access</span> Interfaces.<span style="color: #202020;">Unsigned_32</span>;<br />
&nbsp; &nbsp; &nbsp; Value : Interfaces.<span style="color: #202020;">Unsigned_32</span><span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">return</span> Interfaces.<span style="color: #202020;">Unsigned_32</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">pragma</span> Import<br />
&nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span>Intrinsic, Sync_Sub_And_Fetch, <span style="color: #7f007f;">&quot;__sync_sub_and_fetch_4&quot;</span><span style="color: #66cc66;">&#41;</span>;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">Использование встроенных функций требует особого внимания к некоторым аспектам объявления и использования переменной-счётчика. Это затрагивает:</p>
<ul>
<li>
<p style="text-align: justify;">выравнивания объекта в памяти &mdash; некоторые процессоры накладывают жесткие ограничения на выравнивание данных в памяти и неспособны выполнить операции чтения/записи невыровненных данных;</p>
</li>
<li>
<p style="text-align: justify;">обеспечения доступа к значению одной неразрывной операцией &mdash; необходимо гарантировать, что процессор способен выполнять чтение/запись одной неразрывной операцией, в противном случае возможно получение некорректных данных при чтении или искажение данных при записи;</p>
</li>
<li>
<p style="text-align: justify;">предотвращения оптимизации кода сохранением значения в регистрах и последующим его использованием. ;</p>
</li>
</ul>
<p style="text-align: justify;">Стандартные средства языка Ada предоставляют портируемые способы решения этих задач:</p>
<ul>
<li>
<p style="text-align: justify;">для обеспечения корректного выравнивания объекта в памяти достаточно объявить переменную как aliased;</p>
</li>
<li>
<p style="text-align: justify;">проверка поддержки неразрывного доступа к значению и использование соответствующих операций гарантируется использованием прагмы Atomic;</p>
</li>
<li>
<p style="text-align: justify;">оптимизация кода путём сохранения ранее прочитанного значения в регистрах отключается применение прагмы Volatile;</p>
</li>
</ul>
<p style="text-align: justify;">Прежде чем показать полный код реализации полезно обратить внимание на один небольшой момент &mdash; приватный тип Counter объявлен как запись с одним компонентом для хранения значения. Это необходимо для гарантии корректного выравнивания, и снятия с пользователя необходимости контроля за выравниванием объектов Counter; а так же для обеспечения возможности начальной инициализации значения счётчика.</p>
<p style="text-align: justify;">А теперь приведём полный код реализации:</p>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #46aa03; font-weight:bold;">with</span> Interfaces;<br />
<br />
<span style="color: #46aa03; font-weight:bold;">package</span> Counters <span style="color: #00007f;">is</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> Counter <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">limited</span> <span style="color: #46aa03; font-weight:bold;">private</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Increment <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Counter<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">pragma</span> Inline <span style="color: #66cc66;">&#40;</span>Increment<span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">function</span> Decrement <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> <span style="color: #46aa03; font-weight:bold;">access</span> Counter<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">return</span> Boolean;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">pragma</span> Inline <span style="color: #66cc66;">&#40;</span>Decrement<span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">function</span> Is_One <span style="color: #66cc66;">&#40;</span>Self : Counter<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">return</span> Boolean;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">pragma</span> Inline <span style="color: #66cc66;">&#40;</span>Is_One<span style="color: #66cc66;">&#41;</span>;<br />
<br />
<span style="color: #46aa03; font-weight:bold;">private</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">type</span> Counter <span style="color: #00007f;">is</span> <span style="color: #46aa03; font-weight:bold;">record</span><br />
&nbsp; &nbsp; &nbsp; Value : <span style="color: #46aa03; font-weight:bold;">aliased</span> Interfaces.<span style="color: #202020;">Unsigned_32</span> := <span style="color: #ff0000;">1</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">pragma</span> Atomic <span style="color: #66cc66;">&#40;</span>Value<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; <span style="color: #46aa03; font-weight:bold;">pragma</span> Volatile <span style="color: #66cc66;">&#40;</span>Value<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> <span style="color: #46aa03; font-weight:bold;">record</span>;<br />
<br />
<span style="color: #00007f;">end</span> Counters;</div></td></tr></tbody></table></div>
<div class="codecolorer-container ada default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br /></div></td><td><div class="ada codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #46aa03; font-weight:bold;">package</span> <span style="color: #46aa03; font-weight:bold;">body</span> Counters <span style="color: #00007f;">is</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">use</span> <span style="color: #46aa03; font-weight:bold;">type</span> Interfaces.<span style="color: #202020;">Unsigned_32</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Sync_Add_And_Fetch<br />
&nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span>Ptr &nbsp; : <span style="color: #46aa03; font-weight:bold;">access</span> Interfaces.<span style="color: #202020;">Unsigned_32</span>;<br />
&nbsp; &nbsp; &nbsp; Value : Interfaces.<span style="color: #202020;">Unsigned_32</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">pragma</span> Import<br />
&nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span>Intrinsic, Sync_Add_And_Fetch, <span style="color: #7f007f;">&quot;__sync_add_and_fetch_4&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">function</span> Sync_Sub_And_Fetch<br />
&nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span>Ptr &nbsp; : <span style="color: #46aa03; font-weight:bold;">access</span> Interfaces.<span style="color: #202020;">Unsigned_32</span>;<br />
&nbsp; &nbsp; &nbsp; Value : Interfaces.<span style="color: #202020;">Unsigned_32</span><span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">return</span> Interfaces.<span style="color: #202020;">Unsigned_32</span>;<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">pragma</span> Import<br />
&nbsp; &nbsp; &nbsp;<span style="color: #66cc66;">&#40;</span>Intrinsic, Sync_Sub_And_Fetch, <span style="color: #7f007f;">&quot;__sync_sub_and_fetch_4&quot;</span><span style="color: #66cc66;">&#41;</span>;<br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Decrement --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">function</span> Decrement <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #0000ff;">not</span> <span style="color: #46aa03; font-weight:bold;">null</span> <span style="color: #46aa03; font-weight:bold;">access</span> Counter<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">return</span> Boolean <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">return</span> Sync_Sub_And_Fetch <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Value</span>'<span style="color: #46aa03; font-weight:bold;">Access</span>, <span style="color: #ff0000;">1</span><span style="color: #66cc66;">&#41;</span> = <span style="color: #ff0000;">0</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Decrement;<br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Increment --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">---------------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">procedure</span> Increment <span style="color: #66cc66;">&#40;</span>Self : <span style="color: #46aa03; font-weight:bold;">in</span> <span style="color: #46aa03; font-weight:bold;">out</span> Counter<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; Sync_Add_And_Fetch <span style="color: #66cc66;">&#40;</span>Self.<span style="color: #202020;">Value</span>'<span style="color: #46aa03; font-weight:bold;">Access</span>, <span style="color: #ff0000;">1</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Increment;<br />
<br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">------------</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">-- Is_One --</span><br />
&nbsp; &nbsp;<span style="color: #adadad; font-style: italic;">------------</span><br />
<br />
&nbsp; &nbsp;<span style="color: #46aa03; font-weight:bold;">function</span> Is_One <span style="color: #66cc66;">&#40;</span>Self : Counter<span style="color: #66cc66;">&#41;</span> <span style="color: #00007f;">return</span> Boolean <span style="color: #00007f;">is</span><br />
&nbsp; &nbsp;<span style="color: #00007f;">begin</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #00007f;">return</span> Self.<span style="color: #202020;">Value</span> = <span style="color: #ff0000;">1</span>;<br />
&nbsp; &nbsp;<span style="color: #00007f;">end</span> Is_One;<br />
<br />
<span style="color: #00007f;">end</span> Counters;</div></td></tr></tbody></table></div>
<p style="text-align: justify;">Приведённая реализация с использованием встроенных функций GCC будет успешно работать при использовании компилятора GNAT GPL 2009 и выше. При компиляции кода для процессора x86 в 32-битном режиме необходимо активировать режим генерации кода для процессора 80486 и выше (указав в ключ компилятора -march=i486, хотя в общем случае можно порекомендовать использовать ключ -march=i686).</p>
<p style="text-align: justify;">Для особо пытливых приводятся фрагменты кода подпрограммы Decrement для процессоров x86_64 и SPARC V9 соответственно:</p>
<div class="codecolorer-container asm default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="asm codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">counters__decrement<span style="color: #339933;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; movl &nbsp; &nbsp;$<span style="color: #339933;">-</span><span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">lock</span> xaddl &nbsp; &nbsp; &nbsp;<span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">&#40;</span><span style="color: #339933;">%</span>rdi<span style="color: #009900; font-weight: bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; cmpl &nbsp; &nbsp;$<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span><span style="color: #00007f;">eax</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">sete</span> &nbsp; &nbsp;<span style="color: #339933;">%</span><span style="color: #00007f;">al</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">ret</span></div></td></tr></tbody></table></div>
<div class="codecolorer-container asm default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td><div class="asm codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">counters__decrement<span style="color: #339933;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; lduw &nbsp; &nbsp;<span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #339933;">%</span>o0<span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span>g2<br />
<span style="color: #339933;">.</span>LL11<span style="color: #339933;">:</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">mov</span> &nbsp; &nbsp; <span style="color: #339933;">%</span>g2<span style="color: #339933;">,</span> <span style="color: #339933;">%</span>g1<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">add</span> &nbsp; &nbsp; <span style="color: #339933;">%</span>g2<span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span>g3<br />
&nbsp; &nbsp; &nbsp; &nbsp; membar &nbsp;<span style="color: #0000ff;">15</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">mov</span> &nbsp; &nbsp; <span style="color: #339933;">%</span>g3<span style="color: #339933;">,</span> <span style="color: #339933;">%</span>g4<br />
&nbsp; &nbsp; &nbsp; &nbsp; cas &nbsp; &nbsp; <span style="color: #009900; font-weight: bold;">&#91;</span><span style="color: #339933;">%</span>o0<span style="color: #009900; font-weight: bold;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span>g2<span style="color: #339933;">,</span> <span style="color: #339933;">%</span>g4<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">cmp</span> &nbsp; &nbsp; <span style="color: #339933;">%</span>g4<span style="color: #339933;">,</span> <span style="color: #339933;">%</span>g1<br />
&nbsp; &nbsp; &nbsp; &nbsp; bne<span style="color: #339933;">,</span>pt &nbsp;<span style="color: #339933;">%</span>icc<span style="color: #339933;">,</span> <span style="color: #339933;">.</span>LL11<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #00007f; font-weight: bold;">mov</span> &nbsp; &nbsp;<span style="color: #339933;">%</span>g4<span style="color: #339933;">,</span> <span style="color: #339933;">%</span>g2<br />
&nbsp; &nbsp; &nbsp; &nbsp; subcc &nbsp; <span style="color: #339933;">%</span>g0<span style="color: #339933;">,</span> <span style="color: #339933;">%</span>g3<span style="color: #339933;">,</span> <span style="color: #339933;">%</span>g0<br />
&nbsp; &nbsp; &nbsp; &nbsp; subx &nbsp; &nbsp;<span style="color: #339933;">%</span>g0<span style="color: #339933;">,</span> <span style="color: #339933;">-</span><span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #339933;">%</span>o0<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #00007f; font-weight: bold;">jmp</span> &nbsp; &nbsp; <span style="color: #339933;">%</span>o7<span style="color: #339933;">+</span><span style="color: #0000ff;">8</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #00007f; font-weight: bold;">nop</span></div></td></tr></tbody></table></div>
<p>Полный исходный текст примеров можно скачать по ссылке [download id="1"].</p>
]]></content:encoded>
			<wfw:commentRss>http://ru.ada-community.org/2010/09/10/%d0%bf%d0%be%d1%80%d1%82%d0%b8%d1%80%d1%83%d0%b5%d0%bc%d0%b0%d1%8f-%d1%80%d0%b5%d0%b0%d0%bb%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-%d0%b0%d1%82%d0%be%d0%bc%d0%b0%d1%80%d0%bd%d0%be%d0%b3%d0%be-%d1%81/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk
Page Caching using disk (enhanced)

Served from: ru.ada-community.org @ 2012-05-20 23:10:38 -->
