Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 9 Jun 2004 20:20:41 +0200
From:      Pawel Jakub Dawidek <pjd@FreeBSD.org>
To:        Bosko Milekic <bmilekic@FreeBSD.org>
Cc:        "M. Warner Losh" <imp@bsdimp.com>
Subject:   Re: cvs commit: src/sys/kern kern_proc.c
Message-ID:  <20040609182041.GV12007@darkness.comp.waw.pl>
In-Reply-To: <20040609175357.GA32787@freefall.freebsd.org>
References:  <20040609175357.GA32787@freefall.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--EDT6MSV0B3GxyNyZ
Content-Type: text/plain; charset=iso-8859-2
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Wed, Jun 09, 2004 at 05:53:57PM +0000, Bosko Milekic wrote:
+>=20
+> Pawel Jakub Dawidek wrote:
+> >But isn't you reference counting mechanism limited to only 0 and 1
+> >values?
+>=20
+>   Nope.
+>=20
+>   The cmpset does exactly this, atomically: if the refcnt is 0, set it
+>   to 1 and return non-zero, otherwise leave it as it and return 0.
+>=20
+>   Therefore, if two threads are freeing at the same time, the refcount
+>   will get dropped twice [atomically, so we don't have to worry about
+>   a missed decrement], and the threads will race on that atomic cmpset.
+>   But since the cmpset is atomic, then only one thread will get to set
+>   the refcnt to 1 and free, and the other will see that it is not zero,
+>   and so its cmpset will merely return 0 and it will be done (it won't
+>   have to be the one cleaning up/freeing the object).
+>=20
+>   The reference count, after hitting zero, cannot go back up because the
+>   object is being freed and no other references exist.  If they do, then
+>   the reference counting model is broken.
+>=20
+>   Note that in the cmpset, if the refcnt is NOT zero, all that has happe=
ned
+>   is that it was decremented by 1 and the object not freed.
+>=20
+>   Again, the code is correct.

Ok, I get it now. Even if there will be a race between two threads, i.e.:

	[ref_cnt is 2]

	thread1					thread2

	atomic_substract(obj, 1)
	[ref_cnt is 1]
						atomic_substract(obj, 1)
						[ref_cnt is 0]
	atomic_cmpset(obj, 0, 1) -> true
	[do clean up]
						atomic_cmpset(obj, 0, 1) -> false
						[skip cleanups]

(thread2 sets ref_cnt to 0, but thread1 destroys objects) we free object
only once. Cool, I like it:)

BTW. Do we assume that atomic operations are atomic on MP machines?
I read atomic(9), but I still don't know if I should use it or not for
things like those.

--=20
Pawel Jakub Dawidek                       http://www.FreeBSD.org
pjd@FreeBSD.org                           http://garage.freebsd.pl
FreeBSD committer                         Am I Evil? Yes, I Am!

--EDT6MSV0B3GxyNyZ
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (FreeBSD)

iD8DBQFAx1T5ForvXbEpPzQRAmHiAKCg1a3t7wW9MW3tkqgXDE4w7oIsNQCgkGdL
hMQNxECXIHT3uMfK30IlT/M=
=nxVM
-----END PGP SIGNATURE-----

--EDT6MSV0B3GxyNyZ--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20040609182041.GV12007>