Implement producer and consumer in Linux kernel (avoid invalid wakeup)

Source: Internet
Author: User

The focus of this article is to avoid invalid wake-up of kernel threads and focus primarily on the design of consumer threads.

Therefore, in order to save trouble, here and the producers, consumers themselves, the processing process may not be rigorous.


1. Producers

A kernel thread that wakes the consumer after each product is produced, and then sleeps for 1 seconds.


2. Consumers

A kernel thread, whenever awakened, consumes goods and then goes to sleep.

There are several benefits to this design for consumer threading: Fast response and no CPU at all.

But one thing to note about this design is to avoid invalid wake-up of threads. How to implement, see the code of the consumer thread to know.


/*
* Kernel Programming test code
*
* Copyright (C) Sun Mingbao <[email protected]>
* Dual licensed under the MIT and/or GPL licenses.
*
*/

#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/proc_fs.h>
#include <linux/string.h>


Module_author ("Sun Mingbao <[email protected]>");
Module_description ("Kernel Programming Test Code");
Module_version ("1.0");
Module_license ("Dual MIT/GPL");


#define MODULE_NAME "Test"


#define Write_console (FMT, args ...) \
Do \
{ \
PRINTK (Kern_alert fmt,# #args); \
} while (0)


#define Dbg_print (FMT, args ...) \
Do \
{ \
Write_console (module_name "_dbg:%s (%d)-%s:\n" FMT "\ n", __file__,__line__,__function__,# #args); \
} while (0)




static struct task_struct *consumer_thread;
static struct task_struct *producer_thread;


Static U32 Cnt_consumer, Cnt_producer;
static int has_something_to_consume = 0;
static void Consume ()
{
Has_something_to_consume = 0;
cnt_consumer++;
}


static void Produce ()
{
Has_something_to_consume = 1;
cnt_producer++;
}


static int Consumer_thread_func (void * data)
{
while (!kthread_should_stop ())
{
if (Has_something_to_consume)
{
Consume ();
}


Set_current_state (task_interruptible);
if (Has_something_to_consume)
{
Set_current_state (task_running);
Continue
}


Schedule ();
}


if (Has_something_to_consume)
{
Consume ();
}


}


static int Producer_thread_func (void * data)
{


while (!kthread_should_stop ())
{
Produce ();
if (Consumer_thread->state & task_interruptible)
{
Wake_up_process (Consumer_thread);
}

Set_current_state (task_interruptible);
Schedule_timeout (HZ);
}


}


static int __init create_threads (void)
{
Consumer_thread=kthread_run (Consumer_thread_func, NULL, "Consumer_thread");
Producer_thread=kthread_run (Producer_thread_func, NULL, "Producer_thread");


return 0;
}


static struct Proc_dir_entry *my_proc_dir;

static int Misc_info_read_proc (char *buffer, char **start, off_t offset, int length, int *eof, void *data)
{
int ret;
static Char proc_file_contents[128];
static int proc_file_len = 0;
if (0==offset | | 0==proc_file_len)
{
proc_file_len=sprintf (proc_file_contents, "cnt_producer:%u\n", "cnt_consumer:%u\n", Cnt_producer, Cnt_consumer);
}

ret=snprintf (buffer, length, "%s", Proc_file_contents+offset);


if (Ret+offset==proc_file_len)
*eof = 1;

return ret;
}


static int __init create_my_proc_entries (void)
{
My_proc_dir = Proc_mkdir (module_name, NULL);

Create_proc_read_entry ("Misc_info"
, 0
, My_proc_dir
, Misc_info_read_proc
, NULL);


return 0;
}


static void __exit remove_my_proc_entries (void)
{
Remove_proc_entry ("Misc_info", My_proc_dir);
Remove_proc_entry (Module_name, NULL);
}


static int __init test_init (void)
{
int retval;


Dbg_print ("Start");
Retval=create_threads ();
if (retval < 0)
{
Goto EXIT;
}


Create_my_proc_entries ();

Dbg_print ("Start succeed");

EXIT:
return retval;
}




static void __exit stop_threads (void)
{
Kthread_stop (Consumer_thread);
Kthread_stop (Producer_thread);
}




static void __exit test_exit (void)
{
Dbg_print ("Quit");
Remove_my_proc_entries ();
Stop_threads ();
}


Module_init (Test_init);
Module_exit (Test_exit);



Implement producer and consumer in Linux kernel (avoid invalid wakeup)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.