Hi,
jhoney jhoney a écrit :
> My requirement is like this. I am calling some blocking calls. if I create one
> thread for one blocking call, another blocking call comes with is not adding to
> the task list when I used tasklet. So I am going to threads now.
>
> If I call threads from interrupt service routine, the arguments are not getting
> passed correctly to the thread. How to make interrupt service routine small and
> spaw new thread for each call.
You don't want to spawn a thread for each call. You want to add stuff in
to a global list, and then wake up the thread so that it will process
the stuff. Depending on what you need to do, you can either use a thread
or a tasklet. I think you should prefer tasklets whenever possible, but
kernel experts of the list will confirm or infirm this.
Here some sort of pseudo-code (no error checks, never compiled, may be
completely wrong):
struct job_description {
/* Here you have the values you need to process your job */
};
semaphore_t thread_sem;
struct job_description *job_list;
spinlock_t job_list_lock;
void my_thread (void *) {
while (1) {
struct job_description *job;
struct job_description *local_job_list;
/* Wait to be woken up by interrupt handler */
sem_down_interruptible (& thread_sem);
/* Get a local pointer to the list, and release the
spinlock as sooas possible, so that the interrupt
handler can add more jobs to the global list. */
spinlock_lock (& job_list_lock);
local_job_list = job_list;
job_list = NULL;
spinlock_unlock (& job_list_lock);
/* Do the job, and free the structures */
list_for_each_safe (local_job_list, job) {
/* Do what you need with the job, with the data in
the 'job' structure */
list_remove (job);
kfree (job);
}
}
}
int interrupt_handler (int num) {
struct job_description *job;
/* Fetch your info */
/* Allocate job description structure */
job = kmalloc (sizeof(struct job_description), GFP_ATOMIC);
job->... = ...
job->... = ...
/* Add job to the global list */
spinlock_lock (& job_list_lock);
list_add_tail (job_list, job);
spinlock_unlock (& job_list_lock);
/* Wake up the thread */
sem_up (& thread_sem);
}
int module_init (void) {
sem_init (& thread_sem);
spinlock_init (& job_list_lock);
kernel_thread (my_thread);
return 0;
}
Here we go.
Thomas
--
PETAZZONI Thomas - thomas.petazzoni@xxxxxxxx
http://thomas.enix.org - Jabber: thomas.petazzoni@xxxxxxxxx
KOS: http://kos.enix.org/ - SOS: http://sos.enix.org
Fingerprint : 0BE1 4CF3 CEA4 AC9D CC6E 1624 F653 CB30 98D3 F7A7
Attachment:
signature.asc
Description: OpenPGP digital signature