Re: [HACKERS] What is the posix_memalign() equivalent for the PostgreSQL?

2016-09-02 Thread Anderson Carniel
The unexpected errors are problems to free the memory that was previously
allocated with posix_memalign. After a number of memory allocation and free
calls, the next free call crashes the system.

On the other hand, if I replace the posix_memalign and the free calls for
the following malloc/free aligned implementations, it works.


void *malloc_aligned(size_t alignment, size_t bytes) {
void *mallocPtr;//Initial pointer returned from malloc
void *newMallocPtr;//New pointer after adjustment
void *alignedPtr;
size_t alignMask;//Need this to get the aligned address
size_t totalBytes = 0;

/* Make sure alignment is power of 2 and it is not zero
 * because zero is not power of 2 */
if ( !(!(alignment & (alignment-1)) && alignment) )
return NULL;

/* We need to allocate extra memory to make sure the allocated
 * memory will be aligned and need sizeof(size_t) bytes more for
 * storing the value of the bytes we padded.
 */
   totalBytes = bytes + alignment + sizeof(size_t);

mallocPtr = palloc(totalBytes);

if (NULL == mallocPtr)
return NULL;

newMallocPtr = (void*)((char*)mallocPtr + sizeof(size_t));

alignMask = ~(alignment - 1);

/* Value of alignedPtr should be multiple of alignment */
alignedPtr = (void *)(((size_t)newMallocPtr + alignment) & alignMask);

/* Store the extra bytes info right before alignedPtr */
*((size_t*)alignedPtr - 1) = (size_t)alignedPtr - (size_t)mallocPtr;

return alignedPtr;
}

void free_aligned(void *raw_data) {
void *mallocPtr;//Initial malloc pointer
size_t extraBytes;

if (NULL == raw_data)
return;

/* Retrieve the extra padded byte info */
extraBytes = *((size_t*)raw_data - 1);

/* Get initial malloc ptr */
mallocPtr = (void*) ((size_t)raw_data - extraBytes);

pfree(mallocPtr);
}

Please note that I am using in these functions, the palloc and pfree
instead of malloc and free respectively. But the problem is that the
free_aligned function is not indeed freeing the allocated memory. Thus, I
would like to know if the PostgreSQL provides a memory function that
allocates aligned memory. If not, according to your experience, is there a
significance difference between the performance of the O_DIRECT or not?

Thank you,
Anderson

2016-09-02 7:24 GMT-03:00 Craig Ringer <cr...@2ndquadrant.com>:

> On 2 September 2016 at 01:12, Anderson Carniel <accarn...@gmail.com>
> wrote:
> > Dear all,
> >
> > I am developing an extension for the PostgreSQL that write/read some
> > external files from the PostgreSQL. In order to write/read, I am using
> the
> > O_DIRECT flag and using the posix_memalign to allocate memory. I would
> like
> > to know if the postgresql internal library provides an equivalent
> function
> > for the posix_memalign since I am getting unexpected errors.
>
> "unexpected errors". Details please?
>
> If you're trying to allocate aligned memory, I believe PostgreSQL
> typically uses the TYPEALIGN macros (see c.h) but I'm painfully
> clueless in the area, so ... yeah. Don't trust me.
>
> I was a bit surprised not to see a MemoryContextAlloc or palloc
> variant that returns memory aligned to a given boundary.
>
> > All my
> > allocations are in the TopMemoryContext since I am working with several
> > buffers that must be alive while the PostgreSQL Server is activated.
>
> You can't posix_memalign into TopMemoryContext. Such memory is outside
> the memory context system, like memory directly malloc()'d.
>
> --
>  Craig Ringer   http://www.2ndQuadrant.com/
>  PostgreSQL Development, 24x7 Support, Training & Services
>


[HACKERS] What is the posix_memalign() equivalent for the PostgreSQL?

2016-09-01 Thread Anderson Carniel
Dear all,

I am developing an extension for the PostgreSQL that write/read some
external files from the PostgreSQL. In order to write/read, I am using the
O_DIRECT flag and using the posix_memalign to allocate memory. I would like
to know if the postgresql internal library provides an equivalent function
for the posix_memalign since I am getting unexpected errors. All my
allocations are in the TopMemoryContext since I am working with several
buffers that must be alive while the PostgreSQL Server is activated.

Thanks in advance,
Anderson


Re: [HACKERS] Losing memory references - SRF + SPI

2016-05-14 Thread Anderson Carniel
Thank you very much Joe.

I have followed the crosstab() implementation and understood the idea of
per query memory context. Now, I am using a unique SPI instance (which I
perform several sql queries), process the result, transform my result into
a tuplestore, close the SPI and done. It works perfectly.

I have a curiosity with regard to the tuplestore: is there a problem with
performance if my tuplestore form a big table with million of tuples? Other
question is regarding to SPI: is there a problem to use only  one instance
of SPI (for instance, if multiple users call the same function)?

Thank you again,
Anderson Carniel

2016-05-14 12:19 GMT-03:00 Joe Conway <m...@joeconway.com>:

> On 05/13/2016 09:35 PM, Anderson Carniel wrote:
> > I am writing a function that returns a set of tuples by using also the
> > PostGIS. Thuis, I am using SRF too. It successfully returns the expected
> > result when it has at most 4 tuples. However, this is not the case when
> > more than 4 tuples have to be returned. When I debug the code, I found
> > that the problem is in my function that transforms a cstring after a
> > SPI_connection. It seems that this cstring is not valid anymore in the
> > moment of this conversion (see my comment below). I know that the SPI
> > uses different contexts when it init and finish its process. But, I
> > don't understand why I have this problem here. Please, note that I tried
> > to copy the values of the whole tuple, but I have the same problem:
> > system crash after the forth call of the function. Also note that I call
> > this function only in the init call of the SRF. Please I would
> > appreciate any suggestion and help.
>
> You probably need to allocate your returned values in a per query memory
> context. Take a look at how it is done in, for example, crosstab() in
> contrib/tablefunc.
>
> HTH,
>
> Joe
>
> --
> Crunchy Data - http://crunchydata.com
> PostgreSQL Support for Secure Enterprises
> Consulting, Training, & Open Source Development
>
>


[HACKERS] Losing memory references - SRF + SPI

2016-05-13 Thread Anderson Carniel
I am writing a function that returns a set of tuples by using also the
PostGIS. Thuis, I am using SRF too. It successfully returns the expected
result when it has at most 4 tuples. However, this is not the case when
more than 4 tuples have to be returned. When I debug the code, I found that
the problem is in my function that transforms a cstring after a
SPI_connection. It seems that this cstring is not valid anymore in the
moment of this conversion (see my comment below). I know that the SPI uses
different contexts when it init and finish its process. But, I don't
understand why I have this problem here. Please, note that I tried to copy
the values of the whole tuple, but I have the same problem: system crash
after the forth call of the function. Also note that I call this function
only in the init call of the SRF. Please I would appreciate any suggestion
and help.

--- code of the problematic function here ---

LWGEOM *retrieve_geom_from_postgis(int row_id) {
char query[100];
int err;
char *wkt;
int srid;
LWGEOM *lwgeom = NULL;
HeapTuple cop;
bool null;
TupleDesc tupdesc;

//refin is a prepared select command that returns 2 columns
sprintf(query, "EXECUTE refinplan(%d);", row_id);

if (SPI_OK_CONNECT != SPI_connect()) {
SPI_finish();
_DEBUG(ERROR, "retrieve_geom_from_postgis: could not connect to SPI
manager");
return NULL;
}
err = SPI_execute(query, false, 1);
if (err < 0) {
SPI_finish();
_DEBUG(ERROR, "retrieve_geom_from_postgis: could not execute the
EXECUTE command");
return NULL;
}

if (SPI_processed <= 0) {
SPI_finish();
_DEBUGF(ERROR, "the row_id (%d) does not exist in the table",
row_id)
return NULL;
}
cop = SPI_copytuple(SPI_tuptable->vals[0]);
tupdesc = SPI_tuptable->tupdesc;

/* disconnect from SPI */
SPI_finish();

wkt = text2cstring(DatumGetTextP(heap_getattr(cop, 1, tupdesc, )));
srid = DatumGetInt32(heap_getattr(cop, 2, tupdesc, ));

lwgeom = lwgeom_from_wkt(wkt, LW_PARSER_CHECK_NONE); //error here...
only after the forth call
lwgeom_set_srid(lwgeom, srid);

lwfree(wkt);

return lwgeom;
}