Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / core / refcnt.c
1 /*
2  * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19
20 FILE_LICENCE ( GPL2_OR_LATER );
21
22 #include <stdlib.h>
23 #include <ipxe/refcnt.h>
24
25 /** @file
26  *
27  * Reference counting
28  *
29  */
30
31 /**
32  * Increment reference count
33  *
34  * @v refcnt            Reference counter, or NULL
35  *
36  * If @c refcnt is NULL, no action is taken.
37  */
38 void ref_increment ( struct refcnt *refcnt ) {
39
40         if ( refcnt ) {
41                 refcnt->count++;
42                 DBGC2 ( refcnt, "REFCNT %p incremented to %d\n",
43                         refcnt, refcnt->count );
44         }
45 }
46
47 /**
48  * Decrement reference count
49  *
50  * @v refcnt            Reference counter, or NULL
51  *
52  * If the reference count decreases below zero, the object's free()
53  * method will be called.
54  *
55  * If @c refcnt is NULL, no action is taken.
56  */
57 void ref_decrement ( struct refcnt *refcnt ) {
58
59         if ( ! refcnt )
60                 return;
61
62         refcnt->count--;
63         DBGC2 ( refcnt, "REFCNT %p decremented to %d\n",
64                 refcnt, refcnt->count );
65
66         if ( refcnt->count >= 0 )
67                 return;
68
69         if ( refcnt->count < -1 ) {
70                 DBGC ( refcnt, "REFCNT %p decremented too far (%d)!\n",
71                        refcnt, refcnt->count );
72                 /* Avoid multiple calls to free(), which typically
73                  * result in memory corruption that is very hard to
74                  * track down.
75                  */
76                 return;
77         }
78
79         if ( refcnt->free ) {
80                 DBGC ( refcnt, "REFCNT %p being freed via method %p\n",
81                        refcnt, refcnt->free );
82                 refcnt->free ( refcnt );
83         } else {
84                 DBGC ( refcnt, "REFCNT %p being freed\n", refcnt );
85                 free ( refcnt );
86         }
87 }
88
89 /**
90  * Do not free reference-counted object
91  *
92  * @v refcnt            Reference counter
93  *
94  * This is meant for initializing a reference counter structure in a
95  * statically allocated object.
96  */
97 void ref_no_free ( struct refcnt *refcnt __unused ) {
98         /* Do nothing */
99 }