Пример #1
0
inline void free(void *p)
{
  /* prevent crash */
  if(p == NULL) return;

  brel(p);
}
Пример #2
0
/* bgetr
 * Reallocate a buffer.  This is a minimal implementation,
 * simply in terms of brel()  and  bget().	 It  could  be
 * enhanced to allow the buffer to grow into adjacent free
 * blocks and to avoid moving data unnecessarily.  */
void*
bgetr(
	_In_ BytePool_t *pool, 
	_In_ void *buf, 
	_In_ long size)
{
	// Variables
    void *nbuf;
    long osize;		      /* Old size of buffer */
    struct bhead *b;

    if ((nbuf = bget(pool, size)) == NULL) { /* Acquire new buffer */
	return NULL;
    }
    if (buf == NULL) {
	return nbuf;
    }
    b = BH(((char *) buf) - sizeof(struct bhead));
    osize = -b->bsize;
#ifdef BECtl
    if (osize == 0) {
	/*  Buffer acquired directly through acqfcn. */
	struct bdhead *bd;

	bd = BDH(((char *) buf) - sizeof(struct bdhead));
	osize = bd->tsize - sizeof(struct bdhead);
    } else
#endif
	osize -= sizeof(struct bhead);
    assert(osize > 0);
    V memcpy((char *) nbuf, (char *) buf, /* Copy the data */
	     (MemSize) ((size < osize) ? size : osize));
    brel(pool, buf);
    return nbuf;
}
Пример #3
0
static void raw_free(void *ptr)
{
	raw_malloc_validate_pools();

	if (ptr)
		brel(ptr);
}
Пример #4
0
void *bgetr(void *buf, bufsize size)
{
    void *nbuf;
    bufsize osize;		      /* Old size of buffer */
    struct bhead *b;

	nbuf = bget(size);
    if ((nbuf != NULL) && (buf != NULL)) { /* Acquire new buffer */
	
		b = BH(getPointerOffset(buf, -(int32_t)sizeof(struct bhead)));
		osize = -b->bsize;
#ifdef BECtl
		if (osize == 0) {
		/*  Buffer acquired directly through acqfcn. */
		struct bdhead *bd;

		bd = BDH(getPointerOffset(buf, -(int32_t)sizeof(struct bdhead)));
		osize = bd->tsize - (int32_t)sizeof(struct bdhead);
		} else{
#endif
		osize -= (int32_t)sizeof(struct bhead);
#ifdef BECtl
		}
#endif
		assert(osize > 0);
		V memcpy((int8_t *) nbuf, (int8_t *) buf, /* Copy the data */
			 (MemSize) ((size < osize) ? size : osize));
		brel(buf);
    
	}
	
	return nbuf;
}
Пример #5
0
void* BGet::bgetr(void *buf, bufsize size)
{
	void *nbuf;
	bufsize osize;		      /* Old size of buffer */
	struct bhead *b;

	if ((nbuf = bget(size)) == NULL) { /* Acquire new buffer */
		return NULL;
	}
	if (buf == NULL) {
		return nbuf;
	}
	b = BH(((char *) buf) - sizeof(struct bhead));
	osize = -b->bsize;
#ifdef BECtl
	if (osize == 0) {
		/*  Buffer acquired directly through acqfcn. */
		struct bdhead *bd;

		bd = BDH(((char *) buf) - sizeof(struct bdhead));
		osize = bd->tsize - sizeof(struct bdhead);
	} else
#endif
		osize -= sizeof(struct bhead);
	assert(osize > 0);
	V memcpy((char *) nbuf, (char *) buf, /* Copy the data */
		(MemSize) ((size < osize) ? size : osize));
	brel(buf);
	return nbuf;
}
Пример #6
0
/**
 * Read a field from a file to the IO library.
 *
 * @param ncid identifies the netCDF file
 * @param varid the variable ID to be read
 * @param ioid: the I/O description ID as passed back by
 * PIOc_InitDecomp().
 * @param arraylen: the length of the array to be read. This
 * is the length of the distrubited array. That is, the length of
 * the portion of the data that is on the processor.
 * @param array: pointer to the data to be read. This is a
 * pointer to the distributed portion of the array that is on this
 * processor.
 * @return 0 for success, error code otherwise.
 * @ingroup PIO_read_darray
 * @author Jim Edwards, Ed Hartnett
 */
int PIOc_read_darray(int ncid, int varid, int ioid, PIO_Offset arraylen,
                     void *array)
{
    iosystem_desc_t *ios;  /* Pointer to io system information. */
    file_desc_t *file;     /* Pointer to file information. */
    io_desc_t *iodesc;     /* Pointer to IO description information. */
    void *iobuf = NULL;    /* holds the data as read on the io node. */
    size_t rlen = 0;       /* the length of data in iobuf. */
    int ierr;           /* Return code. */

    /* Get the file info. */
    if ((ierr = pio_get_file(ncid, &file)))
        return pio_err(NULL, NULL, PIO_EBADID, __FILE__, __LINE__);
    ios = file->iosystem;

    /* Get the iodesc. */
    if (!(iodesc = pio_get_iodesc_from_id(ioid)))
        return pio_err(ios, file, PIO_EBADID, __FILE__, __LINE__);
    pioassert(iodesc->rearranger == PIO_REARR_BOX || iodesc->rearranger == PIO_REARR_SUBSET,
              "unknown rearranger", __FILE__, __LINE__);

    /* ??? */
    if (ios->iomaster == MPI_ROOT)
        rlen = iodesc->maxiobuflen;
    else
        rlen = iodesc->llen;

    /* Allocate a buffer for one record. */
    if (ios->ioproc && rlen > 0)
        if (!(iobuf = bget(iodesc->mpitype_size * rlen)))
            return pio_err(ios, file, PIO_ENOMEM, __FILE__, __LINE__);

    /* Call the correct darray read function based on iotype. */
    switch (file->iotype)
    {
    case PIO_IOTYPE_NETCDF:
    case PIO_IOTYPE_NETCDF4C:
        if ((ierr = pio_read_darray_nc_serial(file, iodesc, varid, iobuf)))
            return pio_err(ios, file, ierr, __FILE__, __LINE__);
        break;
    case PIO_IOTYPE_PNETCDF:
    case PIO_IOTYPE_NETCDF4P:
        if ((ierr = pio_read_darray_nc(file, iodesc, varid, iobuf)))
            return pio_err(ios, file, ierr, __FILE__, __LINE__);
        break;
    default:
        return pio_err(NULL, NULL, PIO_EBADIOTYPE, __FILE__, __LINE__);
    }

    /* Rearrange the data. */
    if ((ierr = rearrange_io2comp(ios, iodesc, iobuf, array)))
        return pio_err(ios, file, ierr, __FILE__, __LINE__);

    /* Free the buffer. */
    if (rlen > 0)
        brel(iobuf);

    return PIO_NOERR;
}
Пример #7
0
void Free(void *buf) {
    bool iflag;

    

    brel(buf);

}
Пример #8
0
//*****************************************************************************
//
//! Frees a block of memory in the SDRAM heap.
//!
//! \param pvBlock is the pointer to the block of SDRAM to free.
//!
//! This function frees a block of memory that had previously been allocated
//! using a call to ExtRAMAlloc();
//!
//! \return None.
//
//*****************************************************************************
void
ExtRAMFree(void *pvBlock)
{
    if(g_bSDRAMPresent)
    {
        brel(pvBlock);
    }
}
Пример #9
0
/* BufferPoolFree
 * Frees previously allocations made by the buffer-pool. The virtual
 * address must be the one passed back. */
OsStatus_t
BufferPoolFree(
    _In_ BufferPool_t*  Pool,
    _In_ uintptr_t*     VirtualPointer)
{
    brel(Pool->Pool, (void*)VirtualPointer);
    return OsSuccess;
}
Пример #10
0
void lp_free(laser_packet* lp)
{
	if (lp == NULL)
	{
		return;
	}

	pd_free(lp->data);
	brel(lp);
}
Пример #11
0
void pd_free(packet_data* pd)
{
	while(pd != NULL)
	{
		--pd->refs_count;
		packet_data* next = pd->next;
		if (pd->refs_count == 0)
		{
			brel(pd);
		}
		pd = next;
	}
}
Пример #12
0
/* ********************************************************************   */
void _ks_free(PFBYTE ptr, int num_elements, int size)
{
#if (DISPLAY_MALLOC)
    DEBUG_ERROR("ks_free returns: ", DINT1, ptr, 0);
#endif

#    if (defined (RTKBCPP))
        /* Was done by ks_dpmi_release_all();   */
        ARGSUSED_PVOID(ptr)
        ARGSUSED_INT(num_elements)
        ARGSUSED_INT(size)

#    elif (INCLUDE_BGET)
        ARGSUSED_INT(num_elements)
        ARGSUSED_INT(size)
        brel(ptr);

#    elif (INCLUDE_WINSOCK || INCLUDE_BSDSOCK)
        ARGSUSED_INT(num_elements);
        ARGSUSED_INT(size);
        free(ptr);

#    elif (defined(SEG_IAR))
        /* protected mode   */
        ARGSUSED_INT(num_elements);
        ARGSUSED_INT(size);
        free(ptr);

#    elif ( defined(__BORLANDC__) )   /* real mode */
        ARGSUSED_INT(num_elements);
        ARGSUSED_INT(size);
        _ffree(ptr);


#    else
        #error: ks_free needs to be implemented
#    endif
}
Пример #13
0
int pio_delete_iodesc_from_list(int ioid)
{

  io_desc_t *ciodesc, *piodesc;

  piodesc = NULL;
  //  if(abs(ioid)==518) printf("In delete from list %d\n", ioid);
  for(ciodesc=pio_iodesc_list; ciodesc != NULL; ciodesc=ciodesc->next){
    if(ciodesc->ioid == ioid){
      if(piodesc == NULL){
	pio_iodesc_list = ciodesc->next;
      }else{
	piodesc->next = ciodesc->next;
      }
      if(current_iodesc==ciodesc)
	current_iodesc=pio_iodesc_list;
      brel(ciodesc);
      return PIO_NOERR;
    }
    piodesc = ciodesc;
  }
  return PIO_EBADID;
}
Пример #14
0
void Cyc_Core_rufree(struct _ReapHandle *r, void *ptr) {
  if(ptr == NULL || r == NULL)
    return;
  brel(r->bkey, ptr);
}
Пример #15
0
void free(void *p)
{
	mutex_lock(&malloc_lock);
	brel(p);
	mutex_unlock(&malloc_lock);
}
Пример #16
0
/** Free previously allocated memory
 * @param buf Previously allocated buffer.
 */
void cmsMem_free(void *buf)
{
   UINT32 size;

   if (buf != NULL)
   {
      UINT32 *intBuf = (UINT32 *) (((UINT32) buf) - CMS_MEM_HEADER_LENGTH);

#ifdef CMS_MEM_LEAK_TRACING
      {
         AllocRecord *allocRec;
         dlist_for_each_entry(allocRec, &glbAllocRec, dlist)
            if (allocRec->bufAddr == buf)
               break;

         if ((DlistNode *) allocRec != &glbAllocRec)
         {
            dlist_unlink((struct dlist_node *) allocRec);
            free(allocRec);
         }
         else
         {
            /*
             * Buffers allocated from shared mem could have been freed by 
             * another app, so if we have an alloc record but cannot find
             * it in shared mem, ignore it.  But if the alloc record is in
             * private heap, that is an error.
             */
            if (!IS_IN_SHARED_MEM(buf))
            {
               cmsLog_error("possible double free, could not find allocRec for buf %p", buf);
            }
         }
      }
#endif

      size = intBuf[1];

      if (intBuf[1] != (intBuf[2] ^ 0xffffffff))
      {
         cmsLog_error("memory underflow detected, %d %d", intBuf[1], intBuf[2]);
         cmsAst_assert(0);
         return;
      }

#ifdef CMS_MEM_DEBUG
      {
         UINT32 allocSize, intSize, roundup4Size, i;
         UINT8 *charBuf = (UINT8 *) buf;

         allocSize = REAL_ALLOC_SIZE(intBuf[1]);
         intSize = allocSize / sizeof(UINT32);
         roundup4Size = ROUNDUP4(intBuf[1]);

         for (i=intBuf[1]; i < roundup4Size; i++)
         {
            if (charBuf[i] != (UINT8) (CMS_MEM_FOOTER_PATTERN & 0xff))
            {
               cmsLog_error("memory overflow detected at idx=%d 0x%x 0x%x 0x%x",
                            i, charBuf[i], intBuf[intSize-1], intBuf[intSize-2]);
               cmsAst_assert(0);
               return;
            }
         }
               
         if ((intBuf[intSize - 1] != CMS_MEM_FOOTER_PATTERN) ||
             (intBuf[intSize - 2] != CMS_MEM_FOOTER_PATTERN))
         {
            cmsLog_error("memory overflow detected, 0x%x 0x%x",
                         intBuf[intSize - 1], intBuf[intSize - 2]);
            cmsAst_assert(0);
            return;
         }

#ifdef CMS_MEM_POISON_ALLOC_FREE
         /*
          * write garbage into buffer which is about to be freed to detect
          * users of freed buffers.
          */
         memset(intBuf, CMS_MEM_FREE_PATTERN, allocSize);
#endif
      }

#endif  /* CMS_MEM_DEBUG */


      buf = intBuf;  /* buf points to real start of buffer */


#ifdef MDM_SHARED_MEM
      if (IS_IN_SHARED_MEM(buf))
      {
         brel(buf);
      }
      else
#endif
      {
         oal_free(buf);
         mStats.bytesAllocd -= size;
         mStats.numFrees++;
      }
   }
Пример #17
0
/**
 * Write one or more arrays with the same IO decomposition to the
 * file.
 *
 * This funciton is similar to PIOc_write_darray(), but allows the
 * caller to use their own data buffering (instead of using the
 * buffering implemented in PIOc_write_darray()).
 *
 * When the user calls PIOc_write_darray() one or more times, then
 * PIO_write_darray_multi() will be called when the buffer is flushed.
 *
 * Internally, this function will:
 * <ul>
 * <li>Find info about file, decomposition, and variable.
 * <li>Do a special flush for pnetcdf if needed.
 * <li>Allocates a buffer big enough to hold all the data in the
 * multi-buffer, for all tasks.
 * <li>Calls rearrange_comp2io() to move data from compute to IO
 * tasks.
 * <li>For parallel iotypes (pnetcdf and netCDF-4 parallel) call
 * pio_write_darray_multi_nc().
 * <li>For serial iotypes (netcdf classic and netCDF-4 serial) call
 * write_darray_multi_serial().
 * <li>For subset rearranger, create holegrid to write missing
 * data. Then call pio_write_darray_multi_nc() or
 * write_darray_multi_serial() to write the holegrid.
 * <li>Special buffer flush for pnetcdf.
 * </ul>
 *
 * @param ncid identifies the netCDF file.
 * @param varids an array of length nvars containing the variable ids to
 * be written.
 * @param ioid the I/O description ID as passed back by
 * PIOc_InitDecomp().
 * @param nvars the number of variables to be written with this
 * call.
 * @param arraylen the length of the array to be written. This is the
 * length of the distrubited array. That is, the length of the portion
 * of the data that is on the processor. The same arraylen is used for
 * all variables in the call.
 * @param array pointer to the data to be written. This is a pointer
 * to an array of arrays with the distributed portion of the array
 * that is on this processor. There are nvars arrays of data, and each
 * array of data contains one record worth of data for that variable.
 * @param frame an array of length nvars with the frame or record
 * dimension for each of the nvars variables in IOBUF. NULL if this
 * iodesc contains non-record vars.
 * @param fillvalue pointer an array (of length nvars) of pointers to
 * the fill value to be used for missing data.
 * @param flushtodisk non-zero to cause buffers to be flushed to disk.
 * @return 0 for success, error code otherwise.
 * @ingroup PIO_write_darray
 * @author Jim Edwards, Ed Hartnett
 */
int PIOc_write_darray_multi(int ncid, const int *varids, int ioid, int nvars,
                            PIO_Offset arraylen, void *array, const int *frame,
                            void **fillvalue, bool flushtodisk)
{
    iosystem_desc_t *ios;  /* Pointer to io system information. */
    file_desc_t *file;     /* Pointer to file information. */
    io_desc_t *iodesc;     /* Pointer to IO description information. */
    int rlen;              /* Total data buffer size. */
    var_desc_t *vdesc0;    /* First entry in array of var_desc structure for each var. */
    int fndims;            /* Number of dims in the var in the file. */
    int mpierr = MPI_SUCCESS, mpierr2;  /* Return code from MPI function calls. */
    int ierr;              /* Return code. */

    /* Get the file info. */
    if ((ierr = pio_get_file(ncid, &file)))
        return pio_err(NULL, NULL, PIO_EBADID, __FILE__, __LINE__);
    ios = file->iosystem;

    /* Check inputs. */
    if (nvars <= 0 || !varids)
        return pio_err(ios, file, PIO_EINVAL, __FILE__, __LINE__);

    LOG((1, "PIOc_write_darray_multi ncid = %d ioid = %d nvars = %d arraylen = %ld "
         "flushtodisk = %d",
         ncid, ioid, nvars, arraylen, flushtodisk));

    /* Check that we can write to this file. */
    if (!file->writable)
        return pio_err(ios, file, PIO_EPERM, __FILE__, __LINE__);

    /* Get iodesc. */
    if (!(iodesc = pio_get_iodesc_from_id(ioid)))
        return pio_err(ios, file, PIO_EBADID, __FILE__, __LINE__);
    pioassert(iodesc->rearranger == PIO_REARR_BOX || iodesc->rearranger == PIO_REARR_SUBSET,
              "unknown rearranger", __FILE__, __LINE__);

    /* Check the types of all the vars. They must match the type of
     * the decomposition. */
    for (int v = 0; v < nvars; v++)
    {
        var_desc_t *vdesc;
        if ((ierr = get_var_desc(varids[v], &file->varlist, &vdesc)))
            return pio_err(ios, file, ierr, __FILE__, __LINE__);
        if (vdesc->pio_type != iodesc->piotype)
            return pio_err(ios, file, PIO_EINVAL, __FILE__, __LINE__);
    }

    /* Get a pointer to the variable info for the first variable. */
    if ((ierr = get_var_desc(varids[0], &file->varlist, &vdesc0)))
        return pio_err(ios, file, ierr, __FILE__, __LINE__);

    /* Run these on all tasks if async is not in use, but only on
     * non-IO tasks if async is in use. */
    if (!ios->async || !ios->ioproc)
    {
        /* Get the number of dims for this var. */
        LOG((3, "about to call PIOc_inq_varndims varids[0] = %d", varids[0]));
        if ((ierr = PIOc_inq_varndims(file->pio_ncid, varids[0], &fndims)))
            return check_netcdf(file, ierr, __FILE__, __LINE__);
        LOG((3, "called PIOc_inq_varndims varids[0] = %d fndims = %d", varids[0], fndims));
    }

    /* If async is in use, and this is not an IO task, bcast the parameters. */
    if (ios->async)
    {
        if (!ios->ioproc)
        {
            int msg = PIO_MSG_WRITEDARRAYMULTI;
            char frame_present = frame ? true : false;         /* Is frame non-NULL? */
            char fillvalue_present = fillvalue ? true : false; /* Is fillvalue non-NULL? */
            int flushtodisk_int = flushtodisk; /* Need this to be int not boolean. */

            if (ios->compmaster == MPI_ROOT)
                mpierr = MPI_Send(&msg, 1, MPI_INT, ios->ioroot, 1, ios->union_comm);

            /* Send the function parameters and associated informaiton
             * to the msg handler. */
            if (!mpierr)
                mpierr = MPI_Bcast(&ncid, 1, MPI_INT, ios->compmaster, ios->intercomm);
            if (!mpierr)
                mpierr = MPI_Bcast(&nvars, 1, MPI_INT, ios->compmaster, ios->intercomm);
            if (!mpierr)
                mpierr = MPI_Bcast((void *)varids, nvars, MPI_INT, ios->compmaster, ios->intercomm);
            if (!mpierr)
                mpierr = MPI_Bcast(&ioid, 1, MPI_INT, ios->compmaster, ios->intercomm);
            if (!mpierr)
                mpierr = MPI_Bcast(&arraylen, 1, MPI_OFFSET, ios->compmaster, ios->intercomm);
            if (!mpierr)
                mpierr = MPI_Bcast(array, arraylen * iodesc->piotype_size, MPI_CHAR, ios->compmaster,
                                   ios->intercomm);
            if (!mpierr)
                mpierr = MPI_Bcast(&frame_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm);
            if (!mpierr && frame_present)
                mpierr = MPI_Bcast((void *)frame, nvars, MPI_INT, ios->compmaster, ios->intercomm);
            if (!mpierr)
                mpierr = MPI_Bcast(&fillvalue_present, 1, MPI_CHAR, ios->compmaster, ios->intercomm);
            if (!mpierr && fillvalue_present)
                mpierr = MPI_Bcast((void *)fillvalue, nvars * iodesc->piotype_size, MPI_CHAR,
                                   ios->compmaster, ios->intercomm);
            if (!mpierr)
                mpierr = MPI_Bcast(&flushtodisk_int, 1, MPI_INT, ios->compmaster, ios->intercomm);
            LOG((2, "PIOc_write_darray_multi file->pio_ncid = %d nvars = %d ioid = %d arraylen = %d "
                 "frame_present = %d fillvalue_present = %d flushtodisk = %d", file->pio_ncid, nvars,
                 ioid, arraylen, frame_present, fillvalue_present, flushtodisk));
        }

        /* Handle MPI errors. */
        if ((mpierr2 = MPI_Bcast(&mpierr, 1, MPI_INT, ios->comproot, ios->my_comm)))
            return check_mpi(file, mpierr2, __FILE__, __LINE__);
        if (mpierr)
            return check_mpi(file, mpierr, __FILE__, __LINE__);

        /* Share results known only on computation tasks with IO tasks. */
        if ((mpierr = MPI_Bcast(&fndims, 1, MPI_INT, ios->comproot, ios->my_comm)))
            check_mpi(file, mpierr, __FILE__, __LINE__);
        LOG((3, "shared fndims = %d", fndims));
    }

    /* if the buffer is already in use in pnetcdf we need to flush first */
    if (file->iotype == PIO_IOTYPE_PNETCDF && file->iobuf)
        if ((ierr = flush_output_buffer(file, 1, 0)))
            return pio_err(ios, file, ierr, __FILE__, __LINE__);

    pioassert(!file->iobuf, "buffer overwrite",__FILE__, __LINE__);

    /* Determine total size of aggregated data (all vars/records).
     * For netcdf serial writes we collect the data on io nodes and
     * then move that data one node at a time to the io master node
     * and write (or read). The buffer size on io task 0 must be as
     * large as the largest used to accommodate this serial io
     * method.  */
    rlen = 0;
    if (iodesc->llen > 0)
        rlen = iodesc->maxiobuflen * nvars;

    /* Allocate iobuf. */
    if (rlen > 0)
    {
        /* Allocate memory for the buffer for all vars/records. */
        if (!(file->iobuf = bget(iodesc->mpitype_size * (size_t)rlen)))
            return pio_err(ios, file, PIO_ENOMEM, __FILE__, __LINE__);
        LOG((3, "allocated %lld bytes for variable buffer", (size_t)rlen * iodesc->mpitype_size));

        /* If fill values are desired, and we're using the BOX
         * rearranger, insert fill values. */
        if (iodesc->needsfill && iodesc->rearranger == PIO_REARR_BOX)
        {
            LOG((3, "inerting fill values iodesc->maxiobuflen = %d", iodesc->maxiobuflen));
            for (int nv = 0; nv < nvars; nv++)
                for (int i = 0; i < iodesc->maxiobuflen; i++)
                    memcpy(&((char *)file->iobuf)[iodesc->mpitype_size * (i + nv * iodesc->maxiobuflen)],
                           &((char *)fillvalue)[nv * iodesc->mpitype_size], iodesc->mpitype_size);
        }
    }
    else if (file->iotype == PIO_IOTYPE_PNETCDF && ios->ioproc)
    {
	/* this assures that iobuf is allocated on all iotasks thus
           assuring that the flush_output_buffer call above is called
           collectively (from all iotasks) */
        if (!(file->iobuf = bget(1)))
            return pio_err(ios, file, PIO_ENOMEM, __FILE__, __LINE__);
        LOG((3, "allocated token for variable buffer"));
    }

    /* Move data from compute to IO tasks. */
    if ((ierr = rearrange_comp2io(ios, iodesc, array, file->iobuf, nvars)))
        return pio_err(ios, file, ierr, __FILE__, __LINE__);

    /* Write the darray based on the iotype. */
    LOG((2, "about to write darray for iotype = %d", file->iotype));
    switch (file->iotype)
    {
    case PIO_IOTYPE_NETCDF4P:
    case PIO_IOTYPE_PNETCDF:
        if ((ierr = write_darray_multi_par(file, nvars, fndims, varids, iodesc,
                                           DARRAY_DATA, frame)))
            return pio_err(ios, file, ierr, __FILE__, __LINE__);
        break;
    case PIO_IOTYPE_NETCDF4C:
    case PIO_IOTYPE_NETCDF:
        if ((ierr = write_darray_multi_serial(file, nvars, fndims, varids, iodesc,
                                              DARRAY_DATA, frame)))
            return pio_err(ios, file, ierr, __FILE__, __LINE__);

        break;
    default:
        return pio_err(NULL, NULL, PIO_EBADIOTYPE, __FILE__, __LINE__);
    }

    /* For PNETCDF the iobuf is freed in flush_output_buffer() */
    if (file->iotype != PIO_IOTYPE_PNETCDF)
    {
        /* Release resources. */
        if (file->iobuf)
        {
	    LOG((3,"freeing variable buffer in pio_darray"));
            brel(file->iobuf);
            file->iobuf = NULL;
        }
    }

    /* The box rearranger will always have data (it could be fill
     * data) to fill the entire array - that is the aggregate start
     * and count values will completely describe one unlimited
     * dimension unit of the array. For the subset method this is not
     * necessarily the case, areas of missing data may never be
     * written. In order to make sure that these areas are given the
     * missing value a 'holegrid' is used to describe the missing
     * points. This is generally faster than the netcdf method of
     * filling the entire array with missing values before overwriting
     * those values later. */
    if (iodesc->rearranger == PIO_REARR_SUBSET && iodesc->needsfill)
    {
        LOG((2, "nvars = %d holegridsize = %ld iodesc->needsfill = %d\n", nvars,
             iodesc->holegridsize, iodesc->needsfill));

	pioassert(!vdesc0->fillbuf, "buffer overwrite",__FILE__, __LINE__);

        /* Get a buffer. */
	if (ios->io_rank == 0)
	    vdesc0->fillbuf = bget(iodesc->maxholegridsize * iodesc->mpitype_size * nvars);
	else if (iodesc->holegridsize > 0)
	    vdesc0->fillbuf = bget(iodesc->holegridsize * iodesc->mpitype_size * nvars);

        /* copying the fill value into the data buffer for the box
         * rearranger. This will be overwritten with data where
         * provided. */
        for (int nv = 0; nv < nvars; nv++)
            for (int i = 0; i < iodesc->holegridsize; i++)
                memcpy(&((char *)vdesc0->fillbuf)[iodesc->mpitype_size * (i + nv * iodesc->holegridsize)],
                       &((char *)fillvalue)[iodesc->mpitype_size * nv], iodesc->mpitype_size);

        /* Write the darray based on the iotype. */
        switch (file->iotype)
        {
        case PIO_IOTYPE_PNETCDF:
        case PIO_IOTYPE_NETCDF4P:
            if ((ierr = write_darray_multi_par(file, nvars, fndims, varids, iodesc,
                                               DARRAY_FILL, frame)))
                return pio_err(ios, file, ierr, __FILE__, __LINE__);
            break;
        case PIO_IOTYPE_NETCDF4C:
        case PIO_IOTYPE_NETCDF:
            if ((ierr = write_darray_multi_serial(file, nvars, fndims, varids, iodesc,
                                                  DARRAY_FILL, frame)))
                return pio_err(ios, file, ierr, __FILE__, __LINE__);
            break;
        default:
            return pio_err(ios, file, PIO_EBADIOTYPE, __FILE__, __LINE__);
        }

        /* For PNETCDF fillbuf is freed in flush_output_buffer() */
        if (file->iotype != PIO_IOTYPE_PNETCDF)
        {
            /* Free resources. */
            if (vdesc0->fillbuf)
            {
                brel(vdesc0->fillbuf);
                vdesc0->fillbuf = NULL;
            }
        }
    }

    /* Flush data to disk for pnetcdf. */
    if (ios->ioproc && file->iotype == PIO_IOTYPE_PNETCDF)
        if ((ierr = flush_output_buffer(file, flushtodisk, 0)))
            return pio_err(ios, file, ierr, __FILE__, __LINE__);

    return PIO_NOERR;
}
Пример #18
0
/**
* @name    PIOc_sync
*/
int PIOc_sync (int ncid)
{
  int ierr;
  int msg;
  int mpierr;
  iosystem_desc_t *ios;
  file_desc_t *file;
  wmulti_buffer *wmb, *twmb;

  ierr = PIO_NOERR;

  file = pio_get_file_from_id(ncid);
  if(file == NULL)
    return PIO_EBADID;
  ios = file->iosystem;
  msg = PIO_MSG_SYNC;

  if(ios->async_interface && ! ios->ioproc){
    if(ios->compmaster)
      mpierr = MPI_Send(&msg, 1,MPI_INT, ios->ioroot, 1, ios->union_comm);
    mpierr = MPI_Bcast(&(file->fh),1, MPI_INT, 0, ios->intercomm);
  }

  if((file->mode & PIO_WRITE)){
    //  cn_buffer_report( *ios, true);
    wmb = &(file->buffer);
    while(wmb != NULL){
      //    printf("%s %d %d %d\n",__FILE__,__LINE__,wmb->ioid, wmb->validvars);
      if(wmb->validvars>0){
	flush_buffer(ncid, wmb, true);
      }
      twmb = wmb;
      wmb = wmb->next;
      if(twmb == &(file->buffer)){
	twmb->ioid=-1;
	twmb->next=NULL;
      }else{
	brel(twmb);
      }
    }
    flush_output_buffer(file, true, 0);

    if(ios->ioproc){
      switch(file->iotype){
#ifdef _NETCDF
#ifdef _NETCDF4
      case PIO_IOTYPE_NETCDF4P:
	ierr = nc_sync(file->fh);;
	break;
      case PIO_IOTYPE_NETCDF4C:
#endif
      case PIO_IOTYPE_NETCDF:
	if(ios->io_rank==0){
	  ierr = nc_sync(file->fh);;
	}
	break;
#endif
#ifdef _PNETCDF
      case PIO_IOTYPE_PNETCDF:
	ierr = ncmpi_sync(file->fh);;
	break;
#endif
      default:
	ierr = iotype_error(file->iotype,__FILE__,__LINE__);
      }
    }

    ierr = check_netcdf(file, ierr, __FILE__,__LINE__);
  }
  return ierr;
}