+
+int
+tcp_lock(so, refcount, lr)
+ struct socket *so;
+ int refcount;
+ int lr;
+{
+ int lr_saved;
+ if (lr == 0)
+ lr_saved = (unsigned int) __builtin_return_address(0);
+ else lr_saved = lr;
+
+ if (so->so_pcb) {
+ lck_mtx_lock(((struct inpcb *)so->so_pcb)->inpcb_mtx);
+ }
+ else {
+ panic("tcp_lock: so=%p NO PCB! lr=%x\n", so, lr_saved);
+ lck_mtx_lock(so->so_proto->pr_domain->dom_mtx);
+ }
+
+ if (so->so_usecount < 0)
+ panic("tcp_lock: so=%p so_pcb=%p lr=%x ref=%x\n",
+ so, so->so_pcb, lr_saved, so->so_usecount);
+
+ if (refcount)
+ so->so_usecount++;
+ so->lock_lr[so->next_lock_lr] = (u_int32_t)lr_saved;
+ so->next_lock_lr = (so->next_lock_lr+1) % SO_LCKDBG_MAX;
+ return (0);
+}
+
+int
+tcp_unlock(so, refcount, lr)
+ struct socket *so;
+ int refcount;
+ int lr;
+{
+ int lr_saved;
+ if (lr == 0)
+ lr_saved = (unsigned int) __builtin_return_address(0);
+ else lr_saved = lr;
+
+#ifdef MORE_TCPLOCK_DEBUG
+ printf("tcp_unlock: so=%p sopcb=%x lock=%x ref=%x lr=%x\n",
+ so, so->so_pcb, ((struct inpcb *)so->so_pcb)->inpcb_mtx, so->so_usecount, lr_saved);
+#endif
+ if (refcount)
+ so->so_usecount--;
+
+ if (so->so_usecount < 0)
+ panic("tcp_unlock: so=%p usecount=%x\n", so, so->so_usecount);
+ if (so->so_pcb == NULL)
+ panic("tcp_unlock: so=%p NO PCB usecount=%x lr=%x\n", so, so->so_usecount, lr_saved);
+ else {
+ lck_mtx_assert(((struct inpcb *)so->so_pcb)->inpcb_mtx, LCK_MTX_ASSERT_OWNED);
+ so->unlock_lr[so->next_unlock_lr] = (u_int32_t)lr_saved;
+ so->next_unlock_lr = (so->next_unlock_lr+1) % SO_LCKDBG_MAX;
+ lck_mtx_unlock(((struct inpcb *)so->so_pcb)->inpcb_mtx);
+ }
+ return (0);
+}
+
+lck_mtx_t *
+tcp_getlock(
+ struct socket *so,
+ __unused int locktype)
+{
+ struct inpcb *inp = sotoinpcb(so);
+
+ if (so->so_pcb) {
+ if (so->so_usecount < 0)
+ panic("tcp_getlock: so=%p usecount=%x\n", so, so->so_usecount);
+ return(inp->inpcb_mtx);
+ }
+ else {
+ panic("tcp_getlock: so=%p NULL so_pcb\n", so);
+ return (so->so_proto->pr_domain->dom_mtx);
+ }
+}
+long
+tcp_sbspace(struct tcpcb *tp)
+{
+ struct sockbuf *sb = &tp->t_inpcb->inp_socket->so_rcv;
+ long space, newspace;
+
+ space = ((long) lmin((sb->sb_hiwat - sb->sb_cc),
+ (sb->sb_mbmax - sb->sb_mbcnt)));
+
+#if TRAFFIC_MGT
+ if (tp->t_inpcb->inp_socket->so_traffic_mgt_flags & TRAFFIC_MGT_SO_BACKGROUND) {
+ if (tcp_background_io_enabled &&
+ tp->t_inpcb->inp_socket->so_traffic_mgt_flags & TRAFFIC_MGT_SO_BG_SUPPRESSED) {
+ tp->t_flags |= TF_RXWIN0SENT;
+ return 0; /* Triggers TCP window closing by responding there is no space */
+ }
+ }
+#endif /* TRAFFIC_MGT */
+
+ /* Avoid inscreasing window size if the current window
+ * is already very low, we could be in "persist" mode and
+ * we could break some apps (see rdar://5409343)
+ */
+
+ if (space < tp->t_maxseg)
+ return space;
+
+ /* Clip window size for slower link */
+
+ if (((tp->t_flags & TF_SLOWLINK) != 0) && slowlink_wsize > 0 )
+ return lmin(space, slowlink_wsize);
+
+ /*
+ * Check for ressources constraints before over-ajusting the amount of space we can
+ * advertise in the TCP window size updates.
+ */
+
+ if (sbspace_factor && (tp->t_inpcb->inp_pcbinfo->ipi_count < tcp_sockthreshold) &&
+ (total_mb_cnt / 8) < (mbstat.m_clusters / sbspace_factor)) {
+ if (space < (long)(sb->sb_maxused - sb->sb_cc)) {/* make sure we don't constrain the window if we have enough ressources */
+ space = (long) lmax((sb->sb_maxused - sb->sb_cc), tp->rcv_maxbyps);
+ }
+ newspace = (long) lmax(((long)sb->sb_maxused - sb->sb_cc), (long)tp->rcv_maxbyps);
+
+ if (newspace > space)
+ space = newspace;
+ }
+ return space;
+}
+/* DSEP Review Done pl-20051213-v02 @3253,@3391,@3400 */