void __noprof kernel_main_thread(void *data) { struct thread *me = CURRENT(); struct thread_queue tmp_q; tq_init(&tmp_q); tq_insert_head(me, &tmp_q); bug_on(!scheduler_enqueue(&tmp_q)); mach_running(); kprintf("Initializing vfs core... "); fs_init(); kprintf("Done.\n"); call_late_init(); run_tests(); load_init(); for (;;) { scheduler_yield(); arch_idle(); } bug(); }
void test_threads() { #ifdef OPT_TEST_THREADS struct thread *thread; struct thread_queue q; tq_init(&q); thread = thread_create(&func1, "[thread A]", NULL); if (!thread) { kprintf("failed to create thread\n"); bug(); } kprintf("Thread A created.\n"); tq_insert_head(thread, &q); scheduler_enqueue(&q); kprintf("Thread A added to run queue.\n"); thread = thread_create(&func2, "[thread B]", NULL); if (!thread) { kprintf("failed to create thread\n"); bug(); } kprintf("Thread B created.\n"); tq_insert_head(thread, &q); scheduler_enqueue(&q); kprintf("Thread B added to run queue.\n"); #endif /* OPT_TEST_THREADS */ }
void xmit_init (struct audio_s *p_modem, int debug_xmit_packet) { int j; int ad; #if __WIN32__ HANDLE xmit_th[MAX_CHANS]; #else //pthread_attr_t attr; //struct sched_param sp; pthread_t xmit_tid[MAX_CHANS]; #endif //int e; #if DEBUG text_color_set(DW_COLOR_DEBUG); dw_printf ("xmit_init ( ... )\n"); #endif save_audio_config_p = p_modem; g_debug_xmit_packet = debug_xmit_packet; /* * Push to Talk (PTT) control. */ #if DEBUG text_color_set(DW_COLOR_DEBUG); dw_printf ("xmit_init: about to call ptt_init \n"); #endif ptt_init (p_modem); #if DEBUG text_color_set(DW_COLOR_DEBUG); dw_printf ("xmit_init: back from ptt_init \n"); #endif /* * Save parameters for later use. * TODO1.2: Any reason to use global config rather than making a copy? */ for (j=0; j<MAX_CHANS; j++) { xmit_bits_per_sec[j] = p_modem->achan[j].baud; xmit_slottime[j] = p_modem->achan[j].slottime; xmit_persist[j] = p_modem->achan[j].persist; xmit_txdelay[j] = p_modem->achan[j].txdelay; xmit_txtail[j] = p_modem->achan[j].txtail; } #if DEBUG text_color_set(DW_COLOR_DEBUG); dw_printf ("xmit_init: about to call tq_init \n"); #endif tq_init (p_modem); for (ad = 0; ad < MAX_ADEVS; ad++) { dw_mutex_init (&(audio_out_dev_mutex[ad])); } #if DEBUG text_color_set(DW_COLOR_DEBUG); dw_printf ("xmit_init: about to create threads \n"); #endif //TODO: xmit thread should be higher priority to avoid // underrun on the audio output device. for (j=0; j<MAX_CHANS; j++) { if (p_modem->achan[j].valid) { #if __WIN32__ xmit_th[j] = (HANDLE)_beginthreadex (NULL, 0, xmit_thread, (void*)(long)j, 0, NULL); if (xmit_th[j] == NULL) { text_color_set(DW_COLOR_ERROR); dw_printf ("Could not create xmit thread %d\n", j); return; } #else int e; #if 0 //TODO: not this simple. probably need FIFO policy. pthread_attr_init (&attr); e = pthread_attr_getschedparam (&attr, &sp); if (e != 0) { text_color_set(DW_COLOR_ERROR); perror("pthread_attr_getschedparam"); } text_color_set(DW_COLOR_ERROR); dw_printf ("Default scheduling priority = %d, min=%d, max=%d\n", sp.sched_priority, sched_get_priority_min(SCHED_OTHER), sched_get_priority_max(SCHED_OTHER)); sp.sched_priority--; e = pthread_attr_setschedparam (&attr, &sp); if (e != 0) { text_color_set(DW_COLOR_ERROR); perror("pthread_attr_setschedparam"); } e = pthread_create (&(xmit_tid[j]), &attr, xmit_thread, (void *)(long)j); pthread_attr_destroy (&attr); #else e = pthread_create (&(xmit_tid[j]), NULL, xmit_thread, (void *)(long)j); #endif if (e != 0) { text_color_set(DW_COLOR_ERROR); perror("Could not create xmit thread for audio device"); return; } #endif } } #if DEBUG text_color_set(DW_COLOR_DEBUG); dw_printf ("xmit_init: finished \n"); #endif } /* end tq_init */