You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by bt...@apache.org on 2020/07/19 20:14:00 UTC
[incubator-nuttx] branch master updated (4f22f74 -> aa57174)
This is an automated email from the ASF dual-hosted git repository.
btashton pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git.
from 4f22f74 syscall: Remove g_funclookup and g_funcnparms
new e7034c1 rwbuffer: Fix the wrong remaining block calculation in invalidation
new aa57174 rwbuffer: Optimize the buffer algorithm
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
drivers/rwbuffer.c | 213 ++++++++++++++++++++++++++-------------
include/nuttx/drivers/rwbuffer.h | 1 -
2 files changed, 145 insertions(+), 69 deletions(-)
[incubator-nuttx] 02/02: rwbuffer: Optimize the buffer algorithm
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btashton pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit aa57174eb9ef4b58d96a827751a5f96b54d17a30
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Tue Jul 14 17:22:02 2020 +0800
rwbuffer: Optimize the buffer algorithm
avoid the buffer flush as much as possible
Change-Id: I902f374e9540b36bd0b0c77a34cab5014a2c24fc
Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
Signed-off-by: chao.an <an...@xiaomi.com>
---
drivers/rwbuffer.c | 207 +++++++++++++++++++++++++++------------
include/nuttx/drivers/rwbuffer.h | 1 -
2 files changed, 142 insertions(+), 66 deletions(-)
diff --git a/drivers/rwbuffer.c b/drivers/rwbuffer.c
index d0d4b56..bd05adb 100644
--- a/drivers/rwbuffer.c
+++ b/drivers/rwbuffer.c
@@ -136,7 +136,6 @@ static inline void rwb_resetwrbuffer(FAR struct rwbuffer_s *rwb)
rwb->wrnblocks = 0;
rwb->wrblockstart = (off_t)-1;
- rwb->wrexpectedblock = (off_t)-1;
}
#endif
@@ -240,56 +239,160 @@ static ssize_t rwb_writebuffer(FAR struct rwbuffer_s *rwb,
off_t startblock, uint32_t nblocks,
FAR const uint8_t *wrbuffer)
{
- int ret;
+ uint32_t nwritten = nblocks;
/* Write writebuffer Logic */
rwb_wrcanceltimeout(rwb);
- /* First: Should we flush out our cache? We would do that if (1) we already
- * buffering blocks and the next block writing is not in the same sequence,
- * or (2) the number of blocks would exceed our allocated buffer capacity
- */
+ /* Is data saved in the write buffer? */
- if (((startblock != rwb->wrexpectedblock) && (rwb->wrnblocks)) ||
- ((rwb->wrnblocks + nblocks) > rwb->wrmaxblocks))
+ if (rwb->wrnblocks > 0)
{
- finfo("writebuffer miss, expected: %08x, given: %08x\n",
- rwb->wrexpectedblock, startblock);
+ off_t wrbend;
+ off_t newend;
- /* Flush the write buffer */
+ /* Now there are five cases:
+ *
+ * 1. We update the non-overlapping region
+ */
- ret = rwb->wrflush(rwb->dev, rwb->wrbuffer, rwb->wrblockstart,
- rwb->wrnblocks);
- if (ret < 0)
+ wrbend = rwb->wrblockstart + rwb->wrnblocks;
+ newend = startblock + nblocks;
+
+ if (wrbend < startblock || rwb->wrblockstart > newend)
{
- ferr("ERROR: Error writing multiple from cache: %d\n", -ret);
- return ret;
+ /* Nothing to do */;
}
- rwb_resetwrbuffer(rwb);
+ /* 2. We update the entire write buffer. */
+
+ else if (rwb->wrblockstart > startblock && wrbend < newend)
+ {
+ rwb->wrnblocks = 0;
+ }
+
+ /* We are going to update a subset of the write buffer. Three
+ * more cases to consider:
+ *
+ * 3. We update a portion in the middle of the write buffer
+ */
+
+ else if (rwb->wrblockstart <= startblock && wrbend >= newend)
+ {
+ FAR uint8_t *dest;
+ size_t offset;
+
+ /* Copy the data to the middle of write buffer */
+
+ offset = startblock - rwb->wrblockstart;
+ dest = rwb->wrbuffer + offset * rwb->blocksize;
+ memcpy(dest, wrbuffer, nblocks * rwb->blocksize);
+
+ nblocks = 0;
+ }
+
+ /* 4. We upate a portion at the end of the write buffer */
+
+ else if (wrbend >= startblock && wrbend <= newend)
+ {
+ FAR uint8_t *dest;
+ size_t offset;
+ size_t ncopy;
+
+ /* Copy the data from the updating region to the end
+ * of the write buffer.
+ */
+
+ offset = rwb->wrnblocks - (wrbend - startblock);
+ ncopy = rwb->wrmaxblocks - offset;
+ if (ncopy > nblocks)
+ {
+ ncopy = nblocks;
+ }
+
+ dest = rwb->wrbuffer + offset * rwb->blocksize;
+ memcpy(dest, wrbuffer, ncopy * rwb->blocksize);
+
+ rwb->wrnblocks = offset + ncopy;
+ wrbuffer += ncopy * rwb->blocksize;
+ startblock += ncopy;
+ nblocks -= ncopy;
+ }
+
+ /* 5. We update a portion at the beginning of the write buffer */
+
+ else /* if (rwb->wrblockstart >= startblock && wrbend >= newend) */
+ {
+ FAR uint8_t *dest;
+ FAR const uint8_t *src;
+ size_t ncopy;
+
+ DEBUGASSERT(rwb->wrblockstart >= startblock && wrbend >= newend);
+
+ /* Move the cached data to the end of the write buffer */
+
+ ncopy = rwb->wrblockstart - startblock;
+ if (ncopy > rwb->wrmaxblocks - rwb->wrnblocks)
+ {
+ ncopy = rwb->wrmaxblocks - rwb->wrnblocks;
+ }
+
+ dest = rwb->wrbuffer + ncopy * rwb->blocksize;
+ memmove(dest, rwb->wrbuffer, ncopy * rwb->blocksize);
+
+ rwb->wrblockstart -= ncopy;
+ rwb->wrnblocks += ncopy;
+
+ /* Copy the data from the updating region to the beginning
+ * of the write buffer.
+ */
+
+ ncopy = newend - rwb->wrblockstart;
+ src = wrbuffer + (nblocks - ncopy) * rwb->blocksize;
+ memcpy(rwb->wrbuffer, src, ncopy * rwb->blocksize);
+
+ nblocks -= ncopy;
+ }
}
- /* writebuffer is empty? Then initialize it */
+ /* Use the block cache unless the buffer size is bigger than block cache */
- if (rwb->wrnblocks == 0)
+ if (nblocks > rwb->wrmaxblocks)
{
- finfo("Fresh cache starting at block: 0x%08x\n", startblock);
- rwb->wrblockstart = startblock;
+ ssize_t ret = rwb->wrflush(rwb->dev, wrbuffer, startblock, nblocks);
+ if (ret < 0)
+ {
+ return ret;
+ }
}
+ else if (nblocks)
+ {
+ /* Flush the write buffer */
+
+ if (rwb->wrnblocks > 0)
+ {
+ ssize_t ret = rwb->wrflush(rwb->dev, rwb->wrbuffer,
+ rwb->wrblockstart, rwb->wrnblocks);
+ if (ret < 0)
+ {
+ return ret;
+ }
+ }
- /* Add data to cache */
+ /* Buffer the data in the write buffer */
+
+ memcpy(rwb->wrbuffer, wrbuffer, nblocks * rwb->blocksize);
+ rwb->wrblockstart = startblock;
+ rwb->wrnblocks = nblocks;
+ }
- finfo("writebuffer: copying %d bytes from %p to %p\n",
- nblocks * rwb->blocksize, wrbuffer,
- &rwb->wrbuffer[rwb->wrnblocks * rwb->blocksize]);
- memcpy(&rwb->wrbuffer[rwb->wrnblocks * rwb->blocksize],
- wrbuffer, nblocks * rwb->blocksize);
+ if (rwb->wrnblocks > 0)
+ {
+ rwb_wrstarttimeout(rwb);
+ }
- rwb->wrnblocks += nblocks;
- rwb->wrexpectedblock = rwb->wrblockstart + rwb->wrnblocks;
- rwb_wrstarttimeout(rwb);
- return nblocks;
+ return nwritten;
}
#endif
@@ -454,7 +557,7 @@ int rwb_invalidate_writebuffer(FAR struct rwbuffer_s *rwb,
/* We are going to invalidate a subset of the write buffer. Three
* more cases to consider:
*
- * 2. We invalidate a portion in the middle of the write buffer
+ * 3. We invalidate a portion in the middle of the write buffer
*/
else if (rwb->wrblockstart < startblock && wrbend > invend)
@@ -488,7 +591,7 @@ int rwb_invalidate_writebuffer(FAR struct rwbuffer_s *rwb,
}
}
- /* 3. We invalidate a portion at the end of the write buffer */
+ /* 4. We invalidate a portion at the end of the write buffer */
else if (wrbend > startblock && wrbend <= invend)
{
@@ -496,7 +599,7 @@ int rwb_invalidate_writebuffer(FAR struct rwbuffer_s *rwb,
ret = OK;
}
- /* 4. We invalidate a portion at the beginning of the write buffer */
+ /* 5. We invalidate a portion at the beginning of the write buffer */
else /* if (rwb->wrblockstart >= startblock && wrbend > invend) */
{
@@ -1005,40 +1108,14 @@ ssize_t rwb_write(FAR struct rwbuffer_s *rwb, off_t startblock,
{
finfo("startblock=%d wrbuffer=%p\n", startblock, wrbuffer);
- /* Use the block cache unless the buffer size is bigger than block
- * cache.
- */
-
- if (nblocks > rwb->wrmaxblocks)
+ ret = nxsem_wait(&rwb->wrsem);
+ if (ret < 0)
{
- /* First flush the cache */
-
- ret = nxsem_wait(&rwb->wrsem);
- if (ret < 0)
- {
- return (ssize_t)ret;
- }
-
- rwb_wrflush(rwb);
- rwb_semgive(&rwb->wrsem);
-
- /* Then transfer the data directly to the media */
-
- ret = rwb->wrflush(rwb->dev, wrbuffer, startblock, nblocks);
+ return (ssize_t)ret;
}
- else
- {
- /* Buffer the data in the write buffer */
-
- ret = nxsem_wait(&rwb->wrsem);
- if (ret < 0)
- {
- return (ssize_t)ret;
- }
- ret = rwb_writebuffer(rwb, startblock, nblocks, wrbuffer);
- rwb_semgive(&rwb->wrsem);
- }
+ ret = rwb_writebuffer(rwb, startblock, nblocks, wrbuffer);
+ rwb_semgive(&rwb->wrsem);
/* On success, return the number of blocks that we were requested to
* write. This is for compatibility with the normal return of a block
diff --git a/include/nuttx/drivers/rwbuffer.h b/include/nuttx/drivers/rwbuffer.h
index 89f09e9..9515926 100644
--- a/include/nuttx/drivers/rwbuffer.h
+++ b/include/nuttx/drivers/rwbuffer.h
@@ -144,7 +144,6 @@ struct rwbuffer_s
uint8_t *wrbuffer; /* Allocated write buffer */
uint16_t wrnblocks; /* Number of blocks in write buffer */
off_t wrblockstart; /* First block in write buffer */
- off_t wrexpectedblock; /* Next block expected */
#endif
/* This is the state of the read-ahead buffering */
[incubator-nuttx] 01/02: rwbuffer: Fix the wrong remaining block
calculation in invalidation
Posted by bt...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
btashton pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit e7034c102fade1c5aea83dfc79dac4c1050697fe
Author: Xiang Xiao <xi...@xiaomi.com>
AuthorDate: Tue Jul 14 12:08:40 2020 +0800
rwbuffer: Fix the wrong remaining block calculation in invalidation
Signed-off-by: Xiang Xiao <xi...@xiaomi.com>
Change-Id: I00e6e7332f397bcddfd44e1b3c5c514a8f07923f
---
drivers/rwbuffer.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/rwbuffer.c b/drivers/rwbuffer.c
index 6a88e03..d0d4b56 100644
--- a/drivers/rwbuffer.c
+++ b/drivers/rwbuffer.c
@@ -492,7 +492,7 @@ int rwb_invalidate_writebuffer(FAR struct rwbuffer_s *rwb,
else if (wrbend > startblock && wrbend <= invend)
{
- rwb->wrnblocks = wrbend - startblock;
+ rwb->wrnblocks -= wrbend - startblock;
ret = OK;
}
@@ -612,11 +612,11 @@ int rwb_invalidate_readahead(FAR struct rwbuffer_s *rwb,
else if (rhbend > startblock && rhbend <= invend)
{
- rwb->rhnblocks = rhbend - startblock;
+ rwb->rhnblocks -= rhbend - startblock;
ret = OK;
}
- /* 4. We invalidate a portion at the beginning of the write buffer */
+ /* 4. We invalidate a portion at the begin of the read-ahead buffer */
else /* if (rwb->rhblockstart >= startblock && rhbend > invend) */
{