-io_release(ipc_object_t io) {
- assert((io)->io_references > 0 &&
- (io)->io_references < IO_MAX_REFERENCES);
- /* If we just removed the last reference count */
- if ( 1 == OSDecrementAtomic(&((io)->io_references))) {
+io_release(ipc_object_t io)
+{
+ ipc_object_refs_t new_io_references;
+ ipc_object_refs_t old_io_references;
+
+ if ((io)->io_references == 0 ||
+ (io)->io_references >= IO_MAX_REFERENCES) {
+ panic("%s: reference count %u is invalid\n", __func__, (io)->io_references);
+ }
+
+ do {
+ old_io_references = (io)->io_references;
+ new_io_references = old_io_references - 1;
+ if (old_io_references == IO_MAX_REFERENCES) {
+ break;
+ }
+ } while (OSCompareAndSwap(old_io_references, new_io_references,
+ &((io)->io_references)) == FALSE);
+
+ /* If we just removed the last reference count */
+ if (1 == old_io_references) {