nuttx/mm/iob/iob_contig.c

121 lines
3.3 KiB
C
Raw Normal View History

2014-06-07 19:05:31 +02:00
/****************************************************************************
* mm/iob/iob_contig.c
2014-06-07 19:05:31 +02:00
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
2014-06-07 19:05:31 +02:00
*
* http://www.apache.org/licenses/LICENSE-2.0
2014-06-07 19:05:31 +02:00
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
2014-06-07 19:05:31 +02:00
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <string.h>
#include <nuttx/mm/iob.h>
2014-06-07 19:05:31 +02:00
#include "iob.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef MIN
# define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: iob_contig
*
* Description:
* Merge an iob chain into a continuous space, thereby reducing iob
* consumption
2014-06-07 19:05:31 +02:00
*
****************************************************************************/
FAR struct iob_s *iob_contig(FAR struct iob_s *iob)
2014-06-07 19:05:31 +02:00
{
FAR struct iob_s *head;
2014-06-07 19:05:31 +02:00
FAR struct iob_s *next;
unsigned int ncopy;
/* Trim empty iob header */
2014-06-07 19:05:31 +02:00
while (iob != NULL && iob->io_len == 0)
2014-06-07 19:05:31 +02:00
{
iob = iob_free(iob);
}
2014-06-07 19:05:31 +02:00
if (iob == NULL)
{
return NULL;
2014-06-07 19:05:31 +02:00
}
/* Remember the chain header */
head = iob;
2014-06-07 19:05:31 +02:00
while (iob != NULL && iob->io_flink != NULL)
2014-06-07 19:05:31 +02:00
{
next = iob->io_flink;
2014-06-07 19:05:31 +02:00
/* Skip and free the empty next node */
if (next->io_len == 0)
2014-06-07 19:05:31 +02:00
{
next = iob_free(next);
iob->io_flink = next;
continue;
2014-06-07 19:05:31 +02:00
}
/* Skip filled node */
2014-06-07 19:05:31 +02:00
if (iob->io_len == CONFIG_IOB_BUFSIZE)
2014-06-07 19:05:31 +02:00
{
iob = iob->io_flink;
continue;
}
2014-06-07 19:05:31 +02:00
/* Eliminate any leading offset */
2014-06-07 19:05:31 +02:00
if (iob->io_offset > 0)
{
memcpy(iob->io_data, &iob->io_data[iob->io_offset], iob->io_len);
iob->io_offset = 0;
2014-06-07 19:05:31 +02:00
}
/* Copy what we need or what we can from the next buffer */
2014-06-07 19:05:31 +02:00
ncopy = CONFIG_IOB_BUFSIZE - iob->io_len;
ncopy = MIN(ncopy, next->io_len);
memcpy(&iob->io_data[iob->io_len],
&next->io_data[next->io_offset], ncopy);
2014-06-07 19:05:31 +02:00
/* Adjust counts and offsets */
2014-06-07 19:05:31 +02:00
iob->io_len += ncopy;
next->io_offset += ncopy;
next->io_len -= ncopy;
2014-06-07 19:05:31 +02:00
}
return head;
2014-06-07 19:05:31 +02:00
}