My favorites | Sign in
Project Home Downloads Wiki Issues Source
Checkout   Browse   Changes    
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
-----------------------------------------------------------------------
-- Util.Concurrent -- Concurrent Counters
-- Copyright (C) 2009, 2010 Stephane Carrez
-- Written by Stephane Carrez (Stephane.Carrez@gmail.com)
--
-- Licensed under the Apache License, Version 2.0 (the "License");
-- you may not use this file except in compliance with the License.
-- You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
-----------------------------------------------------------------------

-- The <b>Counters</b> package defines the <b>Counter</b> type which provides
-- atomic increment and decrement operations. It is intended to be used to
-- implement reference counting in a multi-threaded environment.
--
-- type Ref is record
-- Cnt : Counter;
-- Data : ...;
-- end record;
--
-- Object : access Ref;
-- Is_Last : Boolean;
-- begin
-- Decrement (Object.Cnt, Is_Last); -- Multi-task safe operation
-- if Is_Last then
-- Free (Object);
-- end if;
--
-- Unlike the Ada portable implementation based on protected type, this implementation
-- does not require that <b>Counter</b> be a limited type.
private with Interfaces;
package Util.Concurrent.Counters is

pragma Preelaborate;

-- ------------------------------
-- Atomic Counter
-- ------------------------------
-- The atomic <b>Counter</b> implements a simple counter that can be
-- incremented or decremented atomically.
type Counter is private;
type Counter_Access is access all Counter;

-- Increment the counter atomically.
procedure Increment (C : in out Counter);
pragma Inline_Always (Increment);

-- Increment the counter atomically and return the value before increment.
procedure Increment (C : in out Counter;
Value : out Integer);
pragma Inline_Always (Increment);

-- Decrement the counter atomically.
procedure Decrement (C : in out Counter);
pragma Inline_Always (Decrement);

-- Decrement the counter atomically and return a status.
procedure Decrement (C : in out Counter;
Is_Zero : out Boolean);
pragma Inline_Always (Decrement);

-- Get the counter value
function Value (C : in Counter) return Integer;
pragma Inline_Always (Value);

ONE : constant Counter;

private

-- This implementation works without an Ada protected type:
-- o The size of the target object is 10 times smaller.
-- o Increment and Decrement operations are 5 times faster.
-- o It works by using special instructions
type Counter is record
Value : Interfaces.Unsigned_32 := 0;
end record;

ONE : constant Counter := Counter '(Value => 1);

end Util.Concurrent.Counters;

Change log

r155 by Stephane.Carrez on Jan 30, 2011   Diff
Make sure the asm implementation is always
inline
Add an Increment procedure that returns
the previous counter value
(atomic increment and get previous value
operation)
Go to: 
Project members, sign in to write a code review

Older revisions

r96 by Stephane.Carrez on Sep 28, 2010   Diff
Add pragma Preelaborate or Pure
r52 by Stephane.Carrez on Jul 4, 2010   Diff
Inline the operations
r34 by Stephane.Carrez on Jun 25, 2010   Diff
Move the concurrent counter
implementation to an asm-x86 specific
directory
Add this directory in the library
build
All revisions of this file

File info

Size: 3106 bytes, 87 lines
Powered by Google Project Hosting