How to create a generic function to take hashtable name and a struct as parameters in a kernel module? - hashtable

I'm currently writing a kernel module which uses multiple hashtables to store different structures. How would I go about implementing a single generic function which would take the hashtable name, hash key and structure to be stored as parameters and do the corresponding store operation?
Here is my hashtable and structure definition.
static DEFINE_HASHTABLE(count, 7);
struct mystruct {
int data ;
struct hlist_node my_hash_list ;
};
Here is my store code ( I seem to be getting a null pointer error if I increment temp->data directly instead of doing it my roundabout add and del way :( )
struct mystruct *temp;
struct mystruct *first;
temp = kmalloc(sizeof(struct mystruct),GFP_KERNEL);
first = kmalloc(sizeof(struct mystruct),GFP_KERNEL);
hash = command;
hash_for_each_possible(count, temp, my_hash_list,hash){
first->data=temp->data+1;
printk("Count: %d\n",first->data);
hash_add(count, &(first->my_hash_list), hash);
hash_del(&(temp->my_hash_list));
return;
}
first->data=1;
hash_add(count, &(first->my_hash_list), hash);
This is for the count hashtable and mystruct structure. Is it possible to create a kernel module function to have a placeholder pointer to any structure and kmalloc memory to that struct? Also how to pass the hashtable name as a parameter?

You cannot create a function which accepts name of the hashtable: it is prohibited by C language. So, your function may only accept a pointer to the hashtable. But because it accepts a pointer, you may no longer use macros like hash_add, which requires name.
You have 2 possibilites:
Creating function-like macro, so it can accept hashtable name, structure and other definitions.
This way is commonly used by Linux kernel, which tends to be fast. Note, that operations like hash_add, hash_for_each_possible are macros too.
Wrap hashtable into your own structure. Into the same structure you need to add all additional information about hash elements: size (for kmalloc), getter of the key from the element (for search) and setter for it(for inserter), and so on.
Something like
struct my_hashtable {
DECLARE_HASHTABLE(count, 7);
size_t obj_size;
unsigned long (*get_key)(void* obj);
void (*set_key)(void* obj, unsigned long key);
};

Related

Initialization of dynamically allocated structures using shared pointer

I dont understand why initialization of dynamically allocated structure needs to be done like this (using shared ptr)
Just to notify that I am using C++11
If we have struct like this
struct Meme {
std::string s;
Meme* p;
}
and later in code, I need to dynamically allocated memory for this structure using shared_ptr, but I need to do instant initialization of structure.
Why it is done like this?
std::shared_ptr<Meme> novi=std::make_shared<Meme>(Meme{imena.at(i),nullptr});
part that confuses me is this one :
std::make_shared<Meme>(Meme{imena.at(i),nullptr});
If we set that shared_ptr points to struct Meme, why we need to specify again that initialization list is for struct Meme, by saying
(Meme{imena.at(i),nullptr})
Why this would not work:
std::shared_ptr<Meme> novi=std::make_shared<Meme>({imena.at(i),nullptr});
Is this maybe that initialization list cannot deduct that it should like convert to struct Meme because there is no direct usage of struct Meme(even though make_shared points to struct Meme) ?
make_shared forwards arguments to constructor.
Make shared_ptr
Allocates and constructs an object of type T passing args to its constructor, and returns an object of type shared_ptr that owns and stores a pointer to it (with a use count of 1).
This calls the copy constructor of Meme from new instance you create with Meme{imena.at(i),nullptr}.
std::shared_ptr<Meme> novi=std::make_shared<Meme>(Meme{imena.at(i),nullptr});
The correct way to construct it with make_shared from forwarded arguments is to create constructor in struct:
struct Meme {
std::string s;
Meme* p;
Meme(const std::string& s, Meme* p) : s(s), p(p) {}
};
std::shared_ptr<Meme> novi = std::make_shared<Meme>(imena.at(i),nullptr);
Also you can create an instance with (default) empty constructor and then set its members:
struct Meme {
std::string s;
Meme* p = nullptr;
};
std::shared_ptr<Meme> novi = std::make_shared<Meme>;
novi->s = imena.at(i);

Pass double pointer in a struct to CUDA

I've got the following struct:
struct Param
{
double** K_RP;
};
And I wanna perform the following operations on "K_RP" in CUDA
__global__ void Test( struct Param prop)
{
int ix = threadIdx.x;
int iy = threadIdx.y;
prop.K_RP[ix][iy]=2.0;
}
If "prop" has the following form, how should I do my "cudaMalloc" and "cudaMemcpy" operations?
int main( )
{
Param prop;
Param cuda_prop;
prop.K_RP=alloc2D(Imax,Jmax);
//cudaMalloc cuda_prop ?
//cudaMemcpyH2D prop to cuda_prop ?
Test<<< (1,1), (Imax,Jmax)>>> ( cuda_prop);
//cudaMemcpyD2H cuda_prop to prop ?
return (0);
}
Questions like this get asked from time to time. If you search on the cuda tag, you'll find a variety of examples with answers. Here's one example.
In general, dynamically allocated data contained within structures or other objects requires special handling. This question/answer explains why and how to do it for the single pointer (*) case.
Handling double pointers (**) is difficult enough that most people would recommend "flattening" the storage so that it can be handled by reference with a single pointer (*). If you really want to see how the double pointer (**) method works, review this question/answer. It's not trivial.

Problems with a structure copy

I am having a compiler issue in Visual Studio 2005 using the standard C compiler when trying to do a structure copy from one location to another.
The types are defined in a file as follows:
definition.h
#define MAX 7
typedef struct{
char recordtext[18];
boolean recordvalid;
}recordtype;
typdef recordtype tabletype[MAX];
typedef struct{
tabletype table;
}global_s;
Let us pretend that a global_s "object" is instantiated and initialized somewhere and a pointer to this structure is created.
#include "definition.h"
global_s global;
global_s* pglobal = &global;
init(&pglobal);
Meanwhile, in another file (and this is where my problem is) i am trying to create a local tabletype object, and fill it with the global table member, using a get method to protect the global (lets pretend it is "static")
#include "definition.h"
extern global_s* pglobal;
tabletype t;
gettable(&t);
void gettabl (tabletype* pt)
{
*pt = pglobal->table;
}
When I go to compile, the line in the gettable function throws a compiler error "error C2106: '=': left operand must be l-value. It looks as though this should behave as a normal copy operation, and in fact if I perform a similar operation on a more basic structure I do not get the error. For example If I copy a structure only containing two integers.
Does anyone have a solid explanation as to why this operation seems to be incorrect?
(Disclaimer: I have developed this code as a scrubbed version of my actual code for example purposes so it may not be 100% correct syntactically, I will edit the question if anyone points out an issue or something needs to be clarified.)
It's the arrays in the struct; they cannot be assigned. You should define an operator=() for each of the structs, and use memcpy on the arrays, or copy them in a loop element by element.
(IF you want to get a reference to your global variable):
I am not sure, if this is correct (and the problem), but I think besides function prototypes, arrays and pointers (to arrays 1. element) are NOT exactly the same thing. And there is a difference between pointer to array and pointer to the 1. element of an array)
Maybe taking the adress of the array:
*pt = &(pglobal->table);
Anyway it might be better not to fetch the address of the whole array but the address of the first element, so that the resulting pointer can be used directly as record array (without dereferencing it)
recordtype* gettable (size_t* puLength)
{
*puLength = MAX;
return &(pglobal->table[0]);
}
(IF you want a copy of the table):
Arrays can't be copied inplace in C90, and of course you have to provide target memory. You would then define a function get table like this:
void gettable (recordtype * const targetArr)
{
size_t i = 0;
for (; i < MAX; i++) targetArr[i] = pglobal->table[i];
return;
}
an fully equivalent function prototype for gettable is:
void gettable(recordtype[] targetArr);
Arrays are provided by refernce as pointer to the first element, when it comes to function parameters. You could again ask for an pointer to the whole array, and dereference it inside gettable. But you always have to copy elementwise.
You can use memcopy to do the job as 1-liner. Modern compilers should generate equally efficent code AFAIK.

Initialising an associative array of struct values and string keys

(for the "D" programming language)
I've been struggling trying to initialise an associative array that has struct elements and should be index-able by a string. I would import it as a module from a separate file.
This is what I want to achieve (and it doesn't work --- I don't know if this is even possible):
mnemonic_info[string] mnemonic_table = [
/* name, format, opcode */
"ADD": {mnemonic_format.Format3M, 0x18},
...
/* NOTE: mnemonic_format is an enum type. */
/* mnemonic_info is a struct with a mnemonic_format and an ubyte */
];
Note that this works fine for arrays indexable by integers.
Optimally, I would like this to be evaluated at compile-time, as I won't be changing it. However, if it's not possible, I would be glad if you told me of the best way to build such an array at/before immediate run-time.
I need this because I'm writing an assembler.
I have searched SO and the internets for an answer, but could only find examples with integers, and other things I didn't understand or couldn't make to work.
I really like D so far but it seems hard to learn due to there not being many tutorials online.
Thanks!
On a side note: is it possible to use Tuples for associative array elements instead of a custom struct?
Edit
There is one way I found so far, but it's pretty ugly:
mnemonic_info[string] mnemonic_table;
static this() { // Not idea what this does.
mnemonic_info entry;
entry.format = mnemonic_format.Format3M;
entry.opcode = 0x18;
mnemonic_table["ADD"] = entry;
/* ... for all entries. */
}
In D, built-in associative array literals are always created in runtime, so initializing a global associative array by assigning it some value at declaration place is currently impossible.
As you found yourself, you can workaround that by assigning a value to associative array in module constructor.
The other problem in your code is struct initialization literals. You should prefer D-style struct initializers to C-style ones.
Example:
struct Foo {
int a;
string b;
}
Foo[string] global;
static this() {
global = [
"foo" : Foo(1, "hurr"),
"bar" : Foo(2, "durr")
];
}
void main() {
assert(global["foo"].a == 1);
}

CLI/C++: void* to System::Object

This is a similar question to this SO post, which I have been unable to use to solve my problem. I have included some code here, which will hopefully help someone to bring home the message that the other posting was getting at.
I want to write a CLI/C++ method that can take a void pointer as a parameter and return the managed object (whose type I know) that it points to. I have a managed struct:
public ref struct ManagedStruct { double a; double b;};
The method I am trying to write, which takes a void pointer to the managed struct as a parameter and returns the struct.
ManagedStruct^ VoidPointerToObject(void* data)
{
Object^ result = Marshal::PtrToStructure(IntPtr(data), Object::typeid);
return (ManagedStruct^)result;
}
The method is called here:
int main(array<System::String ^> ^args)
{
// The instance of the managed type is created:
ManagedStruct^ myData = gcnew ManagedStruct();
myData->a = 1; myData->b = 2;
// Suppose there was a void pointer that pointed to this managed struct
void* voidPtr = &myData;
//A method to return the original struct from the void pointer
Object^ result = VoidPointerToObject(voidPtr);
return 0;
}
It crashes in the VoidPointerToObject method on calling PtrToStructure , with the error: The specified structure must be blittable or have layout information
I know this is an odd thing to do, but it is a situation I have encountered a few times, especially when unmanaged code makes a callback to managed code and passes a void* as a parameter.
(original explanation below)
If you need to pass a managed handle as a void* through native code, you should use
void* voidPtr = GCHandle::ToIntPtr(GCHandle::Alloc(o)).ToPointer();
// ...
GCHandle h = GCHandle::FromIntPtr(IntPtr(voidPtr));
Object^ result = h.Target;
h.Free();
(or use the C++/CLI helper class gcroot)
Marshal::PtrToStructure works on value types.
In C++/CLI, that means value class or value struct. You are using ref struct, which is a reference type despite use of the keyword struct.
A related problem:
void* voidPtr = &myData;
doesn't point to the object, it points to the handle.
In order to create a native pointer to data on the managed heap, you need to use pinning. For this reason, conversion between void* and Object^ isn't as useful as first glance suggests.

Resources