Правильный способ использования потоков ядра в freebsd (+ работа в сети) - PullRequest
0 голосов
/ 04 июля 2011

У меня есть задание на создание поддержки распределенного взаимного исключения с использованием алгоритма Реймонда в freebsd.

Для этого требуется, чтобы поток ядра всегда прослушивал через порт udp сообщения от других систем и действовал соответствующим образом.

Я создаю поток, используя thread_create, но внутри каждого вызова socreate возникает паника ядра. Какой лучший способ сделать то, что я делаю? Я не смог найти хороших руководств по работе с ядром в freebsd.

С другой стороны, возможно, переменная mainproc установлена ​​неправильно. Как узнать ток struct proc* или struct thread*?

Мой текущий код такой:

static struct proc *mainproc;
static int val;
static int main_thread_finish;

static struct socket *listenso;
static struct sockaddr_in listenadr;

static void main_thread(void* data)
{
    static int res;
    printf("In thread\n");
    res = socreate(AF_INET, &listenso, SOCK_DGRAM, IPPROTO_UDP, mainproc->p_ucred, mainproc->p_singlethread);
    printf("socreate res: %d\n", res);

    listenadr.sin_family = AF_INET;
    listenadr.sin_port = htons(1234);
    listenadr.sin_addr.s_addr = 0;
    res = sobind(listenso, (struct sockaddr*)&listenadr, mainproc->p_singlethread);
    printf("bind res: %d\n", res);

    while(!main_thread_finish)
    {
            pause("DUMMY", hz);
    }
    printf("kthread exiting...\n");
   kthread_exit();
}

static int
raymond_module_load(struct module *module, int cmd, void *arg)
{
    int error = 0;

    switch (cmd) {
    case MOD_LOAD :
            val = 12345;
            main_thread_finish = 0;
            kproc_create(main_thread, NULL, &mainproc, 0, 0, "raymond_main_thread");
            printf("Module loaded - kthread created\n");
            break;
    case MOD_UNLOAD :
            main_thread_finish = 1;
            printf("Waiting for thread to exit...\n");
            pause("TWAIT", 3*hz);
            printf("Module unload...\n");
            break;
    default :
            error = EOPNOTSUPP;
            break;
    }
    return (error);
}

static moduledata_t raymond_module_data = {
    .name = "raymond_module",
    .evhand = raymond_module_load,
    .priv = NULL };

DECLARE_MODULE(raymond_module, raymond_module_data, SI_SUB_KLD, SI_ORDER_ANY);

Ответы [ 2 ]

1 голос
/ 12 июля 2011

Звонок на socreate паникует, потому что mainproc->p_singlethread - это NULL. Эта переменная не является потоком, связанным с процессом, но используется для обеспечения «однопоточности» внутри процесса (подробнее см. Функцию thread_single() в sys/kern/kern_thread.c).

Вероятно, вы хотели использовать curthread

res = socreate(AF_INET, &listenso, SOCK_DGRAM, IPPROTO_UDP,
            curthread->td_ucred, curthread);
...
res = sobind(listenso, (struct sockaddr*)&listenadr, curthread);
1 голос
/ 04 июля 2011

Рассмотрите возможность использования netgraph, он готов к использованию модуля ng_ksocket.

...