diff options
author | rwatson <rwatson@FreeBSD.org> | 2004-07-11 22:59:32 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2004-07-11 22:59:32 +0000 |
commit | 00ad513356e32de3b6b1649ee5bd75af5628a67e (patch) | |
tree | 4d3db025ee80589c525c30cbaa8cce341b81142d /sys/kern | |
parent | 14f8256a24a464c5e6ceaf09c4c9d0186408ab21 (diff) | |
download | FreeBSD-src-00ad513356e32de3b6b1649ee5bd75af5628a67e.zip FreeBSD-src-00ad513356e32de3b6b1649ee5bd75af5628a67e.tar.gz |
Add sockbuf_pushsync(), an inline function that, following a change to
the head of the mbuf chains in a socket buffer, re-synchronizes the
cache pointers used to optimize socket buffer appends. This will be
used by soreceive() before dropping socket buffer mutexes to make sure
a consistent version of the socket buffer is visible to other threads.
While here, update copyright to account for substantial rewrite of much
socket code required for fine-grained locking.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/uipc_socket.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 160c89e..065dd11 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1,4 +1,6 @@ /* + * Copyright (c) 2004 The FreeBSD Foundation + * Copyright (c) 2004 Robert Watson * Copyright (c) 1982, 1986, 1988, 1990, 1993 * The Regents of the University of California. All rights reserved. * @@ -892,6 +894,42 @@ bad: } /* + * Following replacement or removal of the first mbuf on the first mbuf chain + * of a socket buffer, push necessary state changes back into the socket + * buffer so that other consumers see the values consistently. 'nextrecord' + * is the callers locally stored value of the original value of + * sb->sb_mb->m_nextpkt which must be restored when the lead mbuf changes. + * NOTE: 'nextrecord' may be NULL. + */ +static __inline void +sockbuf_pushsync(struct sockbuf *sb, struct mbuf *nextrecord) +{ + + SOCKBUF_LOCK_ASSERT(sb); + /* + * First, update for the new value of nextrecord. If necessary, make + * it the first record. + */ + if (sb->sb_mb != NULL) + sb->sb_mb->m_nextpkt = nextrecord; + else + sb->sb_mb = nextrecord; + + /* + * Now update any dependent socket buffer fields to reflect the new + * state. This is an expanded inline of SB_EMPTY_FIXUP(), with the + * addition of a second clause that takes care of the case where + * sb_mb has been updated, but remains the last record. + */ + if (sb->sb_mb == NULL) { + sb->sb_mbtail = NULL; + sb->sb_lastrecord = NULL; + } else if (sb->sb_mb->m_nextpkt == NULL) + sb->sb_lastrecord = sb->sb_mb; +} + + +/* * Implement receive operations on a socket. * We depend on the way that records are added to the sockbuf * by sbappend*. In particular, each record (mbufs linked through m_next) |