+/*
+ * This represents an existing Posix shared memory object.
+ *
+ * It comes into existence with a shm_open(...O_CREAT...)
+ * call and goes away only after it has been shm_unlink()ed
+ * and the last remaining shm_open() file reference is closed.
+ *
+ * To keep track of that lifetime, pshm_usecount is used as a reference
+ * counter. It's incremented for every successful shm_open() and
+ * one extra time for the shm_unlink() to release. Internally
+ * you can temporarily use an additional reference whenever the
+ * subsystem lock has to be dropped for other reasons.
+ */
+typedef struct internal_pshminfo {
+ struct pshminfo pshm_hdr;
+ SLIST_HEAD(pshm_mobjhead, pshm_mobj) pshm_mobjs;
+ RB_ENTRY(internal_pshminfo) pshm_links; /* links for red/black tree */
+} pshm_info_t;
+#define pshm_flags pshm_hdr.pshm_flags
+#define pshm_usecount pshm_hdr.pshm_usecount
+#define pshm_length pshm_hdr.pshm_length
+#define pshm_mode pshm_hdr.pshm_mode
+#define pshm_uid pshm_hdr.pshm_uid
+#define pshm_gid pshm_hdr.pshm_gid
+#define pshm_label pshm_hdr.pshm_label
+
+/* Values for pshm_flags that are still used */
+#define PSHM_ALLOCATED 0x004 /* backing storage is allocated */
+#define PSHM_MAPPED 0x008 /* mapped at least once */
+#define PSHM_INUSE 0x010 /* mapped at least once */
+#define PSHM_REMOVED 0x020 /* no longer in the name cache due to shm_unlink() */
+#define PSHM_ALLOCATING 0x100 /* storage is being allocated */
+
+/*
+ * These handle reference counting pshm_info_t structs using pshm_usecount.
+ */
+static int pshm_ref(pshm_info_t *pinfo);
+static void pshm_deref(pshm_info_t *pinfo);
+#define PSHM_MAXCOUNT UINT_MAX
+
+/*
+ * For every shm_open, we get a new one of these.
+ * The only reason we don't just use pshm_info directly is that
+ * you can query the mapped memory objects via proc_pidinfo to
+ * query the mapped address. Note that even this is a hack. If
+ * you mmap() the same fd multiple times, we only save/report
+ * one address.
+ */
+typedef struct pshmnode {
+ off_t mapp_addr;
+ pshm_info_t *pinfo;
+} pshmnode_t;