?? ospf_system.c
字號:
/* allow timer task to run */ semGive (ospf.timer_task_sem_id); /* allow hello task to run */ semGive (ospf.hello_task_sem_id); } /******************************************************************************* ospf_timer_task_entry_point - ospf timer task entry point** This function creates and starts the OSPF watchdog. It creates the OSPF * timer semaphore. It then forever pends on the OSPF timer semaphore and* calls ospf_router_timer() every time it gets the semaphore.** RETURNS: ERROR is the watchdog timer could not be created or started or if * OSPF timer semaphore could not be created.** NOMANUAL*/STATUS ospf_timer_task_entry_point () { STATUS status; /* create watchdog timer to give timer semaphore once every second */ ospf.watchdog = wdCreate(); if (ospf.watchdog == NULL) { printf ("ospf_timer_task_entry_point: could not create OSPF \n"); printf ("watchdog, exiting\n"); return ERROR; } /* create the timer semaphore */ ospf.timer_task_sem_id = semBCreate (0, SEM_EMPTY); if (ospf.timer_task_sem_id == NULL) { printf("ospf_timer_entry_point: could not create timer semaphore, "); printf("exiting\n"); return ERROR; } /* set task initialization state to complete */ ospf.ospf_tasks[OSPF_TASK_TIMER].task_state = OSPF_TASK_STATE_INIT_COMPLETE; /* take the startup synchronization semaphore */ status = semTake (ospf_startup_sem_id, WAIT_FOREVER); if (status == ERROR) { printf("ospf_timer_entry_point: could not take startup "); printf("semaphore, exiting\n"); return ERROR; } /* start the watch dog timer with 1 second granularity */ status = wdStart ( ospf.watchdog, sysClkRateGet (), (FUNCPTR) ospf_1sec_timer_isr, 0); if (status == ERROR) { printf("ospf_timer_entry_point: could not start watchdog timer, "); printf("exiting\n"); return ERROR; } /* * Forever pend on the OSPF timer semaphore. Every time when get the * semahore, call ospf_router_timer(). The semaphore is given every * second by the watchdog interupt routine ospf_1sec_timer_isr(). */ while (TRUE) { semTake (ospf.timer_task_sem_id, WAIT_FOREVER); ospf_router_timer (); } }/******************************************************************************* ospf_hello_timer_task_entry_point - OSPF hello timer task entry point** This is the start function of OSPF timer task. * Pseudocode:* initialize * synchronize with the other OSPF tasks having completed initialization * start timer task activities: infinite loop waiting (semaphore pended) * to execute timer activities when triggered from timer ISR* * OSPFV3 timer initialization:* Purpose = cause OSPFv3 timer function to run every second, but at task level * not at interrupt level (like if using rwos_dispatcher) and without continuous * processing even when idle. * This is achieved by making the OSPFv3 timer task pend on a sempahore* ospfv3.timer_semaphore_id, which is given from a watchdog timer ISR * that runs precisely every second.* This function ospfv3_create_tasks also creates the watchdog timer for* the OSPFv3 timer task ospfv3.watchdog, which ISR does minimal processing: * just give a semaphore. OSPFV3 timer task pends on the semaphore while idle* * Inifinite loop serving timer ISRs at task level*/void ospf_hello_timer_task_entry_point () { /* create the timer semaphore */ ospf.hello_task_sem_id = semBCreate (0, SEM_EMPTY); if (ospf.hello_task_sem_id == NULL) { printf ("ospf_hello_timer_task_entry_point: ERROR: "); printf ("Could not create hello timer semaphore, exiting\n"); return; } /* set task initialization state to complete */ ospf.ospf_tasks[OSPF_TASK_HELLO_TIMER].task_state = OSPF_TASK_STATE_INIT_COMPLETE; /* take the startup synchronization semaphore */ semTake (ospf_startup_sem_id, WAIT_FOREVER); while (TRUE) { /* * Pend here instead of consuming CPU until watchdog timer interrupt * gives semaphore */ semTake (ospf.hello_task_sem_id, WAIT_FOREVER); ospf_hello_timer (); } }/****************************************************************************** * ospf_input_task_entry_point - ospf input task entry point* * This is the start function of OSPF input task. * Pseudocode:* initialize * synchronize with the other OSPF tasks having completed initialization * start input task activities: infinite loop waiting (socket pended) * to handle PDUs and interface events received via socket from router stack*/void ospf_input_task_entry_point () { /* any initialization goes here */ ospf.ospf_tasks[OSPF_TASK_INPUT].task_state = OSPF_TASK_STATE_INIT_COMPLETE; /* pend on startup semaphore */ semTake (ospf_startup_sem_id, WAIT_FOREVER); /* now start actual function */ ospf_vx_ip_receive_socket_input(); } /****************************************************************************** ospf_create_tasks - create OSPF tasks** This function creates all the OSPF tasks, synchronizes their startup * to the point where all of them have finished their initialization. The * OSPF tasks are: timer, spf, input, rtm and mapi.** MAPI task creation is a special case: it must be created before OSPF is * created. This is an RFC requirement, It must be able to configure an OSPF* instance even if the OSPF instance is not yet created.** RTM task creation is a special case: it must have identical behaviour * for all tasks using the routing table manager (RTM). Therefore, it must use* the task creation mechanism predefined for RTM tasks. The OSPF RTM task is * spawned with protocol_rtm_run_instance() as entry point function, and with * ospf_export_route_from_rtm() as handler of route update messages and* ospf_sysctl_input() as handler of interface state change messages.* * OSPF task synchonization at startup:** OSPF tasks synchronization at startup is achieved using a semaphore * ospf.startup_sem_id and shared memory ospf_tasks.task_state. ** This function is called at init time from ospfInitialize().** Task executing "ospfv3_create_tasks" creates all OSPF tasks with their * status: OSPFV3_TASK_STATE_CREATED. * Then it waits until all of the tasks have completed initialization and * transitioned to state OSPFV3_TASK_STATE_INIT_COMPLETE.* When all tasks have transitioned to OSPFV3_TASK_STATE_INIT_COMPLETE, * this task unblocks all OSPF tasks synchronously by * flushing semaphore ospf_startup_sem_id* * Every OSPF task created executes its initialization, then transitions * from state OSPFV3_TASK_STATE_CREATED * to state OSPFV3_TASK_STATE_INIT_COMPLETE* and blocks on taking semaphore ospfv3.startup_sem_id.** RETURNS: OK if successfull creation and synchronization of OSPF tasks*/STATUS ospf_create_tasks () { OSPF_TASKS task; int delay; /* * Create task creation semaphore, to synchronize startup of all OSPF tasks */ ospf_startup_sem_id = semBCreate ( SEM_Q_PRIORITY | SEM_Q_FIFO, SEM_EMPTY); if (ospf_startup_sem_id == NULL) { printf ("ospf_create_tasks: ERROR: "); printf ("Could not create startup semaphore, exiting\n"); return ERROR; } /* create OSPF tasks */ /* task configuration */ ospf.ospf_tasks[OSPF_TASK_TIMER].task_priority = OSPF_TIMER_TASK_PRIORITY; ospf.ospf_tasks[OSPF_TASK_TIMER].task_stack_size = OSPF_TIMER_TASK_STACK_SIZE; ospf.ospf_tasks[OSPF_TASK_TIMER].task_id = 0; ospf.ospf_tasks[OSPF_TASK_TIMER].task_state = OSPF_TASK_STATE_NOT_CREATED; ospf.ospf_tasks[OSPF_TASK_TIMER].task_start_func = (FUNCPTR) ospf_timer_task_entry_point; strncpy(ospf.ospf_tasks[OSPF_TASK_TIMER].task_name, "tOspfTimer", OSPF_TASK_NAME_SIZE); ospf.ospf_tasks[OSPF_TASK_HELLO_TIMER].task_priority = OSPF_HELLO_TIMER_TASK_PRIORITY; ospf.ospf_tasks[OSPF_TASK_HELLO_TIMER].task_stack_size = OSPF_HELLO_TIMER_TASK_STACK_SIZE; ospf.ospf_tasks[OSPF_TASK_HELLO_TIMER].task_id = 0; ospf.ospf_tasks[OSPF_TASK_HELLO_TIMER].task_state = OSPF_TASK_STATE_NOT_CREATED; ospf.ospf_tasks[OSPF_TASK_HELLO_TIMER].task_start_func = (FUNCPTR) ospf_hello_timer_task_entry_point; strncpy(ospf.ospf_tasks[OSPF_TASK_HELLO_TIMER].task_name, "tOspfHello", OSPF_TASK_NAME_SIZE); ospf.ospf_tasks[OSPF_TASK_INPUT].task_priority = OSPF_INPUT_TASK_PRIORITY; ospf.ospf_tasks[OSPF_TASK_INPUT].task_stack_size = OSPF_INPUT_TASK_STACK_SIZE; ospf.ospf_tasks[OSPF_TASK_INPUT].task_id = 0; ospf.ospf_tasks[OSPF_TASK_INPUT].task_state = OSPF_TASK_STATE_NOT_CREATED; ospf.ospf_tasks[OSPF_TASK_INPUT].task_start_func = (FUNCPTR) ospf_input_task_entry_point; strncpy(ospf.ospf_tasks[OSPF_TASK_INPUT].task_name, "tOspfInput", OSPF_TASK_NAME_SIZE); /* create all OSPF tasks */ for (task = OSPF_TASK_TIMER; task < OSPF_NUM_TASKS; task++) { if (task == OSPF_TASK_RTM) { /* * RTM task creation is special case, it must have identical * behaviour for all tasks using RTM (OSPF is just one of them). * Use the task creation predefined for RTM tasks. * The OSPFv3 RTM task is spawned with * protocol_rtm_run_instance() as entry point function, also with * ospf_export_route_from_rtm() as handler of route update messages * and ospfv3_sysctl_input() as handler of interface state change * messages */ if (ospf_register_with_rtm() != PASS) { return ERROR; } ospf.ospf_tasks[OSPF_TASK_RTM].task_state = OSPF_TASK_STATE_INIT_COMPLETE; } else { /* * NOTE: task state must be set before taskSpawn(). Otherwise * task state may get over-written. This happens when * ospf_create_tasks() is called from a low priority task, e.g. * tSnmpd. */ ospf.ospf_tasks[task].task_state = OSPF_TASK_STATE_CREATED; ospf.ospf_tasks[task].task_id = taskSpawn ( ospf.ospf_tasks[task].task_name, ospf.ospf_tasks[task].task_priority, 0, ospf.ospf_tasks[task].task_stack_size, ospf.ospf_tasks[task].task_start_func, 0,0,0,0,0,0,0,0,0,0); if (ospf.ospf_tasks[task].task_id == ERROR) { printf ( "Could not create %s task.\n\r", ospf.ospf_tasks[task].task_name); return ERROR; } /* * Give newly created tasks a chance to run - this is needed when * ospf_create_tasks() is called from a high priority task, e.g * the shell task. */ taskDelay (sysClkRateGet()); } } /* for */ /* * Synchronization point: wait for all tasks to complete initialization. * Must yield processor though, as we are running in Shell task at * priority 1 higher than all other OSPF tasks, they can not execute unless * we suspend this shell task for a while. Up to 10 seconds, verify every * second if the OSPF tasks have finished initialization */ for (delay = 0; delay < 10; delay++) { if ((ospf.ospf_tasks[OSPF_TASK_TIMER].task_state == OSPF_TASK_STATE_INIT_COMPLETE) && (ospf.ospf_tasks[OSPF_TASK_HELLO_TIMER].task_state == OSPF_TASK_STATE_INIT_COMPLETE) && (ospf.ospf_tasks[OSPF_TASK_INPUT].task_state == OSPF_TASK_STATE_INIT_COMPLETE) && (ospf.ospf_tasks[OSPF_TASK_RTM].task_state == OSPF_TASK_STATE_INIT_COMPLETE)) { /* all OSPF tasks finished initialization, synch point achieved */ semFlush (ospf_startup_sem_id); semDelete (ospf_startup_sem_id); return OK; } taskDelay (sysClkRateGet ()); /* wait 1 seconds */ } /* while some OSPF tasks did not finish initialization */ printf ("OSPF tasks did not initialize correctly\n"); /* force protocol_enabled to true for ospfShutdown() to work properly */ ospf.protocol_enabled = TRUE; /* clean up */ ospfShutdown();
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -