-#define IO_MAX_REFERENCES \
- (unsigned)(~0 ^ (1 << (sizeof(int)*BYTE_SIZE - 1)))
-
-#define io_reference(io) \
-MACRO_BEGIN \
- assert((io)->io_references < IO_MAX_REFERENCES); \
- (io)->io_references++; \
-MACRO_END
-
-#define io_release(io) \
-MACRO_BEGIN \
- assert((io)->io_references > 0 && \
- (io)->io_references <= IO_MAX_REFERENCES); \
- (io)->io_references--; \
-MACRO_END
+#define IO_MAX_REFERENCES \
+ (unsigned)(~0 ^ (1U << (sizeof(int)*BYTE_SIZE - 1)))
+
+static inline void
+io_reference(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);
+}
+
+
+static inline void
+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) {
+ /* Free the object */
+ io_free(io_otype((io)), (io));
+ }
+}
+
+/*
+ * Retrieve a label for use in a kernel call that takes a security
+ * label as a parameter. If necessary, io_getlabel acquires internal
+ * (not io_lock) locks, and io_unlocklabel releases them.
+ */
+
+struct label;
+extern struct label *io_getlabel(ipc_object_t obj);
+#define io_unlocklabel(obj)