I am attempting to add a system call to my linux kernel and it would be advantageous to use the built-in linked list as I am modifying the task_struct (by adding a linked list), and the task_struct already has quite a few struct list_head's in there for other purposes. For uniformity, I would like to stick with this data structure.
My issue is that I really don't fully understand how to use this structure. I see that they have "struct list_head children" for example. However, the implementation of this structure is simple a "*next" and "*last".
I've looked into examples online and every single one says, well make
struct node{
int data;
struct list_head list;
};
But wouldn't this indicate that the data structure I should be including in my task_struct should be
struct node list;
?
I don't quite understand how I would initialize the structure to contain the data I would like it to contain if I use list_head.
Essentially I want to add a linked list of system calls and tack them on to the process in the form of a linked list of char* (readable format).
For now, the semantics of obtaining the system call information is unimportant... I just need to figure out how to get the linked list working with the task_struct.
Edit: For example of what I am trying to do:
I've obtained a list of system calls performed by a function. I am keeping these in separate char* variables. I would like to add a list within the processes task_struct that keeps track of all of these system calls.
For example
Process 'abc' calls printf ~> equates to "WriteScreen" getchar ~> equates to "ReadKey"
I now have a userland piece of code that has these two strings. I call a system call that I will write (once per tag) to "tag" the process with these system calls.
After both calls, the task_struct of 'abc' has a list
abc->task_struct->tag_list
This list contains "WriteScreen" and "ReadKey".
Later I will use these tags to print a list of processes that have called WriteScreen, ReadKey, etc. The implementation of these will happen after I find out how to use the list to appropriately store the strings attached to a process.
So instead of creating a list of processes (task_struct) what you're trying to accomplish is a list per process.
This means that each process will have its own list, i.e. its own list head.
This list will store, in addition to next/prev pointers, a single piece of data, actually a string (could be the string itself or a pointer to a string elsewhere).
The list node will be therefore:
struct my_node {
struct list_head list;
char data[100]; // arbitrarily set to 100; could be also char*
}
The task_struct should be augmented with a new list head:
struct task_struct {
// many members that contains info about a process
...
struct list_head my_list;
}
Yes. You'll notice that both cases (when the process belongs to a list, and when the list belongs to the process) the member will be the same; only its use is different.
Now, when a process is created you should initialize the list head (as each process will have a new list):
struct task_struct *new_process;
INIT_LIST_HEAD(&new_process->my_list);
To insert a new node (supposing you already created it, that is, allocated memory and initialized its data):
struct my_node *node;
struct task_struct *a_process;
[... my_node initialized ...]
[... a_proccess obtained somehow ...]
list_add_tail(&node->list, &a_process->my_list);
To iterate over the elements:
struct my_node *p;
struct task_struct *a_process
// list is the member name (yes, the member name) of your list inside my_node
list_for_each_entry(p, &a_process->my_list, list) {
// do whatever you want with p
}
EDIT:
Note, however, that you have other ways to do what you are trying to do, without resorting to complex linked lists.
For instance, you could allocate a single char array and encode a list of strings by means of separating them by some char (commas, periods, and so on). This way:
"WriteScreen,ReadKey\0"
In this case you should look after your buffer limits, to never overflow it. On the other hand you do not have to take care of allocating and freeing nodes of a list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With