How to allocate heap in kernel space for an array of fix-sized arrays of characters? - kernel-module

I know that in kernel space one usually uses ExAllocatePoolWithTag function, but I don't know how to allocate memory for a dynamically-sized array of fixed-sized arrays of chars (kind of 2x2 matrix of which the number of lines could dynamically increase).

You can use Lookaside lists for allocating fixed-size buffers (in your case fixed-sized arrays of chars) dynamically.
You can read more about it on MSDN, the documentation for it is very well written:
https://learn.microsoft.com/en-us/windows-hardware/drivers/kernel/using-lookaside-lists

Related

When allocating dynamic array in C, is there a general rule to how much memory to allocate when the amount of memory that will be utilized is unknown?

When allocating a dynamic array in C, is there any general rule on how much memory to allocate when the amount of memory that will be utilized is unknown?
For example, when dynamic memory allocation is for a string command line argument with no character limitation.
The task of (re)allocating memory is often resource-expensive and shouldn't be done often. The general rule, as used by for example a lot of C++ library container classes:
At start, allocate n * [system alignment] bytes.
When the input no longer fits the allocated segment, re-allocate it with twice the previous size. Repeat each time you run out of memory.
That is, exponentially increase the amount of allocated memory.

C efficient way to manage function temporary dynamic memory

I'm making an Nondeterministic Finite Automata (NFA). An NFA has a set of states, I need four array with the same size(number of states in the NFA) to record temporary information about states during the simulation of the NFA.
However, different NFAs has different number of states, thus the size of arrays varies with different NFAs.
Using C I have come up with three ways to deal with the memory allocation:
Use a very big fix-sized array.
malloc memroy dynamically every time the function is called, and before the function finishes, free the allocated memory
Use malloc but not allocate memory on every function call, use four static pointer variables, and one static int arraySize to record allocated array size, for the first time when the function is called, allocate arrays of size NFA->numStates and assign to each of the static pointers, assign NFA->numStates to static int arraySize; for the second time, if NFA->numStates is less than or equal to arraySize, no memory allocation; if NFA->numStates is greater than arraySize, free previous memory and realloc arrays of size NFA->numStates.
Method 1 uses fix-sized array, which means when the input NFA->numStates is greater than the hard-coded array size, the function will not work.
Method 2 is adaptable, but need to allocate memory every time the function is called, not so efficient ?
Method 3 is adaptable too, but is complicated, and is not thread safe ?
Suggestions or other alternatives ?
How about option 2 but with alloca(), i.e. allocate on the stack? It's much (much) faster than malloc(), and automatically de-allocates when you leave the scope which sounds like what you want.
Of course, it's not standard or portable, so it might not be applicable for you.
Failing that, a big fixed-size array seems easy enough and doesn't use more memory.
Variable-Length Arrays (VLAs) have been available since C99. I'd be impressed if you are still working with an implementation that does not support such a thing. VLAs work like regular arrays, except that the size you use to declare them is determined at runtime. That seems to be what you're looking for.
As you are dealing with arrays of arbitrary size I suggest you to implement simple linked list structure that at initialization will hold an array of predefined size and can be extended to hold additional chunks of memory. This will be an abstraction over contiguous memory space. You just need to store the current size of this structure in parent container.
#include <stddef.h>
struct contmem
{
size_t size;
struct memchunk
{
void *data;
struct memchunk *next, *prev;
} head;
}
So, you can extend this structure when you have to and store information by iterating over elements of linked list. This is similar to what happens inside lists from standard C++ library and differs from straight memory reallocation.

Array of pointer in CUDA

Is it possible to pass an array of pointers to a cuda kernel?
i am looking for something like this:
__global__ void Kernel(int **arr)
{
int *temp = arr[blockDim.x];
temp[blockIdx.x] = blockIdx.x;
}
How can i allocate cuda memory for such structure?
Memory allocation for such array is not a problem, you'll do this by cudaMalloc(sizeof(void*)*SIZE). However, writing correct values into it is main problem. Only way to change values in device memory from host function is actually copying information from host memory to device memory (cudaMemcpy() or cudaMemcpyToSymbol()). Thus, to write device pointers into device memory, we must have pointer to device memory in host memory, which I don't think is possible. (pointer which is stored in host variables allocated by cudaMalloc() isn't actual pointer in device memory). So, the only way to write correct values in the array is from kernel, which makes array of pointers unconvenient.
I suggest using indexes instead of pointers, it is much better. Basically if in your array of indexes you have written {4,3,0,1,2} it means that first element points to some array in index 4, second one - to the 3rd element and so on. If you want to point multiple arrays, you should make indexing by some rule, in which you will fill the array of indexes and in which you will access memory from kernel.
I'm doing some image processing work in CUDA currently, and I recommend that you just allocate a linear memory buffer and use an indexing scheme rather than dealing with arrays of pointers. It's way, way simpler in my experience. My 2c.

Does memcpy work for large arrays in structures?

I have a structure that has a dynamic array in it. I have defined two of these structures.
I fill the array in the first structure, then use a line like
memcpy(R->v, A->v, A->n*sizeof(double)
where v is the array that has been dynamically allocated, and n is the number of entries.
R and A are the same type if that matters.
The problem is, the values are not being properyl copied into R. Any idea why? When I try to debug this in totalview, memcpy goes into a function called "very_huge_loop", but no exception or anything is thrown.
the array is approx 188k doubles in length.
Thanks
It could be memory alignment. Some architectures do not like multi-byte values like double to start on any arbitrary byte address. When you allocate the array memory, you might want to use a function like memalign() instead of malloc(). If you are using new double[n] then it should already be aligned correctly.

How can I concatenate two arrays in C?

How do I concatenate two arrays to get a single array containing the elements of both original arrays?
Arrays in C simply are a contiguous area of memory, with a pointer to their start*. So merging them involves:
Find the length of the arrays A and B, (you will probably need to know the number of elements and the sizeof each element)
Allocating (malloc) a new array C that is the size of A + B.
Copy (memcpy) the memory from A to C,
Copy the memory from B to C + the length of A (see 1).
You might want also to de-allocate (free) the memory of A and B.
Note that this is an expensive operation, but this is the basic theory. If you are using a library that provides some abstraction, you might be better off. If A and B are more complicated then a simple array (e.g. sorted arrays), you will need to do smarter copying then steps 3 and 4 (see: how do i merge two arrays having different values into one array).
Although for the purpose of this question, the pointer explanation will suffice, strictly speaking (and for pacifying the commenter below): C has the concept of an array, that can be used without the syntax of pointers. Implementation wise, however, a C array and a contiguous area of memory, with a pointer are close enough they can be, and often are, used interchangeably.

Resources