xref: /haiku/src/add-ons/kernel/file_systems/packagefs/util/InlineReferenceable.h (revision 9a6a20d4689307142a7ed26a1437ba47e244e73f)
1 /*
2  * Copyright 2024, Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  */
5 #ifndef INLINE_REFERENCEABLE_H
6 #define INLINE_REFERENCEABLE_H
7 
8 
9 #include <SupportDefs.h>
10 #include <kernel/debug.h>
11 
12 
13 /*! This class should behave very similarly to BReferenceable, but
14  * whereas sizeof(BReferenceable) == (sizeof(void*) * 2), this class
15  * is only sizeof(int32) == 4. */
16 class InlineReferenceable {
17 public:
18 	inline InlineReferenceable()
19 		:
20 		fReferenceCount(1)
21 	{
22 	}
23 
24 	inline ~InlineReferenceable()
25 	{
26 		ASSERT(fReferenceCount == 0 || fReferenceCount == 1);
27 	}
28 
29 	inline int32
30 	AcquireReference()
31 	{
32 		const int32 previousCount = atomic_add(&fReferenceCount, 1);
33 		ASSERT(previousCount > 0);
34 		return previousCount;
35 	}
36 
37 	inline int32
38 	ReleaseReference()
39 	{
40 		const int32 previousCount = atomic_add(&fReferenceCount, -1);
41 		ASSERT(previousCount > 0);
42 		return previousCount;
43 	}
44 
45 	inline int32
46 	CountReferences()
47 	{
48 		return atomic_get(&fReferenceCount);
49 	}
50 
51 private:
52 	int32	fReferenceCount;
53 };
54 
55 
56 #define DEFINE_INLINE_REFERENCEABLE_METHODS(CLASS, InlineReferenceable) \
57 	void CLASS::AcquireReference()	{ InlineReferenceable.AcquireReference(); } \
58 	void CLASS::ReleaseReference()	{ if (InlineReferenceable.ReleaseReference() == 1) delete this; } \
59 	int32 CLASS::CountReferences()	{ return InlineReferenceable.CountReferences(); }
60 
61 
62 #endif	// INLINE_REFERENCEABLE_H
63