Here's some sample code on how to do this. You use a macro called
"kernel_thread" and in the thread you start, you have to do soe munging
of current->
Jeff
int nwfs_asynch_io_process(void *id)
{
register int i = (int)id;
current->session = 1;
current->pgrp = 1;
sprintf(current->comm, "nwfs-async%d", (int)i);
asynch_io_task[i] = current;
asynch_io_active[i]++;
asynch_threads++;
while (!exit_asynch_io[i])
{
if (!asynch_io_pending(i))
down(sem_table[i]);
if (exit_asynch_io[i])
break;
#if (DO_ASYNCH_IO)
if (asynch_signal[i])
{
if (!asynch_active[i])
{
asynch_active[i] = TRUE;
process_asynch_io(i);
asynch_active[i] = 0;
}
asynch_signal[i] = 0;
}
#endif
}
asynch_threads--;
asynch_io_active[i]--;
return 0;
}
void LRUTimer(void)
{
flush_timer.data = 0;
flush_timer.expires = jiffies + HZ; // second delay
flush_timer.function = (void (*)(ULONG))LRUTimer;
add_timer(&flush_timer);
#if (PROFILE_AIO)
seconds++;
#endif
if (lru_task != current)
{
if (!lru_signal)
{
if (!lru_active)
{
lru_signal = TRUE;
NWFSFlush();
}
}
}
#if (DEBUG_LRU_AIO)
if (delay_counter++ > 60)
{
delay_counter = 0;
displayNWFSState();
}
#endif
return;
}
struct file_system_type nwfs_type =
{
nwfs_read_super, "nwfs", 0, NULL
};
struct super_operations nwfs_sops =
{
nwfs_read_inode, // read inode
NULL, // notify change
nwfs_write_inode, // write inode
nwfs_put_inode, // put inode
nwfs_put_super, // put superblock
NULL, // write superblock
nwfs_statfs, // stat filesystem
nwfs_remount, // remount filesystem
};
int init_module(void)
{
register int status;
#if (DO_ASYNCH_IO)
register int i;
#endif
extern int nwfs_register_symbols(void);
NWFSPrint("NetWare File System NWFS v%d.%02d.%02d Copyright(c) 2000
TRG, Inc.\n",
(int)MAJOR_VERSION, (int)MINOR_VERSION, (int)BUILD_VERSION);
if ((status = register_filesystem(&nwfs_type)) == 0)
{
NWFSPrint("nwfs: initialized successfully\n");
nwfs_register_symbols();
}
if (create_driver())
NWFSPrint("nwfs: error initializing user interface\n");
InitNWFS();
remirror_active = 0;
flush_active = 0;
exit_remirror = 0;
exit_flush = 0;
NWFSPrint("starting REMIRROR process ...\n");
kernel_thread(nwfs_mirror, NULL, 0);
NWFSPrint("starting LRU process ...\n");
kernel_thread(nwfs_flush, NULL, 0);
#if (DO_ASYNCH_IO)
NWFSPrint("starting ASYNCH_CALLBACK process ...\n");
kernel_thread(nwfs_callback, NULL, 0);
NWFSPrint("starting ASYNCH_IO processes [ ");
for (i=0; i < 8; i++)
{
kernel_thread(nwfs_asynch_io_process, (void *)i, 0);
NWFSPrint("%d ", (int)i);
}
NWFSPrint("]\n");
#endif
NWFSPrint("starting LRU Timer ...\n");
init_timer(&flush_timer);
flush_timer.data = 0;
flush_timer.expires = jiffies + HZ; // second delay
flush_timer.function = (void (*)(ULONG))LRUTimer;
add_timer(&flush_timer);
NWFSVolumeScan();
ReportVolumes();
return status;
}
Sourav Ghosh wrote:
>
> Hello,
>
> Can anyone tell me how kernel threads (threads in the kernel space)
> works in linux?
> In other words, how can I schedule them like normal user-level threads?
>
> It seems to me that are NOT schedulable like user-level
> threads/processes in general since they are not
> pre-emptible at all.
> Is it right?
>
> Thanks,
> --
> Sourav
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [EMAIL PROTECTED]
> Please read the FAQ at http://www.tux.org/lkml/
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/