From what I know until know there are two options: 1. Make a copy immediately after the call to the C function and free the allocated memory by it 2. Wrap the returned pointer into another type and register a finalizer for it (and you must return it, otherwise it will be garbage collected immediately). I have no further information about a way to inform the garbage collector about the amount of memory allocated by the foreign function.
More ideas are always welcome! And thank you for the help so far. Rémi
So is there some resolution for this question? I also ran into the problem of not being able to call a C function inside a finalizer (cudaEventDestroy), so I have exactly the same question.On Monday, 9 February 2015 11:14:40 UTC-5, Jameson wrote: I believe there is some sort of gc_counted_malloc function that you can call to inform the gc of significant memory allocations that occur outside of the Julia gc. I suspect that making the copy may actually be your best option at negligible performance cost. Sometimes, you can provide an alternative malloc to c libraries, allowing you to take ownership of the array data afterwards. I don't know if that is the case here. On Sun, Feb 8, 2015 at 5:23 PM Rémi Berson <[email protected] <javascript:>> wrote: Hi Jameson, Thank you for your answer, `primesieve_sieve` is not calling Julia code (juste somme pointer arithmetics and a delete). But it seems that call to `println` in the finalizer is causing the error, strangely. What would be the prefered way to handle memory deallocation in this case? Copying the result from the C function and immediately deleting the memory allocated by it would be the easiest way, but it will impact the performance. Is there any way to avoid that? Also, I don't know if it's the right explanation, but I have the feeling that because the GC doesn't know how much memory has been allocated by the C function, he doesn't know when deallocating memory becomes "urgent". Is there any way to inform the GC how much memory is hold by a given pointer?note, if a c functions returns a bits type (such as Ptr), it is invalid to declare it to return a struct (such as C_primesieve_array). this will soon cause failures on the x86 linux ABI. is the `primesieve_free` c-function itself attempting to execute julia code? note, that since you didn't return `primes_ptr`, it will be garbage collected (and finalized) shortly after your primes function returns On Sun Feb 08 2015 at 2:15:21 PM <[email protected] <javascript:>> wrote: Hi guys, While creating a tiny wrapper over the C/C++ primesieve <https://github.com/kimwalisch/primesieve> library, I encountered an error while trying to finalize the Ptr returned by a function. This pointer must be freed by another function from the library, so I tried to wrap it into a finalizer function but it doesn't work because of the following error: "task switch not allowed from inside gc finalizer". Could someone explain how this could be done properly? I would try to avoid the returned array if possible. Here is the code so far: | constLIB_PRIMESIEVE ="libprimesieve.so" type C_primesieve_array handle::Ptr{Int32} end functionprimes(n::Int) size =Cint[0] primes_ptr =ccall( (:primesieve_generate_primes,LIB_PRIMESIEVE), C_primesieve_array, (UInt64,UInt64,Ptr{Cint},Int), 1,n,size,3) functionprimesieve_array_finalizer(primesieve_arr::C_primesieve_array) ccall( (:primesieve_free,LIB_PRIMESIEVE), Void,(Ptr{Int32},),primesieve_arr.handle) end finalizer(primes_ptr,primesieve_array_finalizer) returnpointer_to_array(primes_ptr.handle,size[1],false) end | Thank you very much, Rémi
