-LIST_HEAD(psemhashhead, psemcache) *psemhashtbl; /* Hash Table */
-u_long psemhash; /* size of hash table - 1 */
-long psemnument; /* number of cache entries allocated */
-struct psemstats psemstats; /* cache effectiveness statistics */
-
-static int psem_cache_search __P((struct pseminfo **,
- struct psemname *, struct psemcache **));
-
-static int psem_read __P((struct file *fp, struct uio *uio,
- struct ucred *cred, int flags, struct proc *p));
-static int psem_write __P((struct file *fp, struct uio *uio,
- struct ucred *cred, int flags, struct proc *p));
-static int psem_ioctl __P((struct file *fp, u_long com,
- caddr_t data, struct proc *p));
-static int psem_select __P((struct file *fp, int which, void *wql,
- struct proc *p));
-static int psem_closefile __P((struct file *fp, struct proc *p));
-
-struct fileops psemops =
- { psem_read, psem_write, psem_ioctl, psem_select, psem_closefile };
+LIST_HEAD(psemhashhead, psemcache) * psemhashtbl; /* Hash Table */
+u_long psemhash; /* size of hash table - 1 */
+long psemnument; /* number of cache entries allocated */
+long posix_sem_max = 10000; /* tunable for max POSIX semaphores */
+ /* 10000 limits to ~1M of memory */
+SYSCTL_NODE(_kern, KERN_POSIX, posix, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "Posix");
+SYSCTL_NODE(_kern_posix, OID_AUTO, sem, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "Semaphores");
+SYSCTL_LONG(_kern_posix_sem, OID_AUTO, max, CTLFLAG_RW | CTLFLAG_LOCKED, &posix_sem_max, "max");
+
+struct psemstats psemstats; /* cache effectiveness statistics */
+
+static int psem_access(struct pseminfo *pinfo, int mode, kauth_cred_t cred);
+static int psem_cache_search(struct pseminfo **,
+ struct psemname *, struct psemcache **);
+static int psem_delete(struct pseminfo * pinfo);
+
+static int psem_closefile(struct fileglob *fp, vfs_context_t ctx);
+static int psem_unlink_internal(struct pseminfo *pinfo, struct psemcache *pcache);
+
+static const struct fileops psemops = {
+ .fo_type = DTYPE_PSXSEM,
+ .fo_read = fo_no_read,
+ .fo_write = fo_no_write,
+ .fo_ioctl = fo_no_ioctl,
+ .fo_select = fo_no_select,
+ .fo_close = psem_closefile,
+ .fo_drain = fo_no_drain,
+ .fo_kqfilter = fo_no_kqfilter,
+};
+
+static lck_grp_t *psx_sem_subsys_lck_grp;
+static lck_grp_attr_t *psx_sem_subsys_lck_grp_attr;
+static lck_attr_t *psx_sem_subsys_lck_attr;
+static lck_mtx_t psx_sem_subsys_mutex;
+
+#define PSEM_SUBSYS_LOCK() lck_mtx_lock(& psx_sem_subsys_mutex)
+#define PSEM_SUBSYS_UNLOCK() lck_mtx_unlock(& psx_sem_subsys_mutex)
+#define PSEM_SUBSYS_ASSERT_HELD() LCK_MTX_ASSERT(&psx_sem_subsys_mutex, LCK_MTX_ASSERT_OWNED)
+
+
+static int psem_cache_add(struct pseminfo *psemp, struct psemname *pnp, struct psemcache *pcp);
+static void psem_cache_delete(struct psemcache *pcp);
+int psem_cache_purge_all(proc_t);
+
+
+/* Initialize the mutex governing access to the posix sem subsystem */
+__private_extern__ void
+psem_lock_init( void )
+{
+ psx_sem_subsys_lck_grp_attr = lck_grp_attr_alloc_init();
+
+ psx_sem_subsys_lck_grp = lck_grp_alloc_init("posix shared memory", psx_sem_subsys_lck_grp_attr);
+
+ psx_sem_subsys_lck_attr = lck_attr_alloc_init();
+ lck_mtx_init(&psx_sem_subsys_mutex, psx_sem_subsys_lck_grp, psx_sem_subsys_lck_attr);
+}