int main (int argc, char *argv[]) { pthread_t thread_id; engine_t *engine; int count = 0, calls = 0; int status; status = pthread_key_create (&engine_key, destructor); if (status != 0) dbg_printf("Create key \n"); status = workq_init (&workq, 4, engine_routine); if (status != 0) dbg_printf ( "Init work queue \n"); status = pthread_create (&thread_id, NULL, thread_routine, NULL); if (status != 0) dbg_printf ("Create thread\n"); (void)thread_routine (NULL); status = pthread_join (thread_id, NULL); if (status != 0) dbg_printf ( "Join thread \n"); status = workq_destroy (&workq); /*死等模式将无法退出*/ if (status != 0) dbg_printf ("Destroy work queue \n"); return 0; }
int main(int argc, char** argv) { int i, nworkers = 1; pthread_t threads[32]; consumer_t consumers[32]; workq_t workq; /* Get number of workers from command line */ if (argc > 1) nworkers = atoi(argv[1]); if (nworkers > 32 || nworkers < 1) { fprintf(stderr, "Error: Must have between 1 and 32 workers\n"); return -1; } /* Initialize I/O mutex and work queue */ pthread_mutex_init(&io_lock, NULL); workq_init(&workq); /* Launch worker threads */ for (i = 0; i < nworkers; ++i) { consumers[i].id = i; consumers[i].workq = &workq; pthread_create(&threads[i], NULL, consumer_main, &consumers[i]); lprintf("Create worker %d\n", i); } /* Run producer */ producer_main(&workq, 100); /* Join on worker threads */ for (i = 0; i < nworkers; ++i) { lprintf("Join worker %d\n", i); pthread_join(threads[i], NULL); } /* Free I/O mutex and work queue */ workq_destroy(&workq); pthread_mutex_destroy(&io_lock); return 0; }
int main (int argc, char *argv[]) { pthread_t thread_id; engine_t *engine; int count = 0, calls = 0; int status; status = pthread_key_create (&engine_key, destructor); if (status != 0) err_abort (status, "Create key"); status = workq_init (&workq, 4, engine_routine); if (status != 0) err_abort (status, "Init work queue"); status = pthread_create (&thread_id, NULL, thread_routine, NULL); if (status != 0) err_abort (status, "Create thread"); (void)thread_routine (NULL); status = pthread_join (thread_id, NULL); if (status != 0) err_abort (status, "Join thread"); status = workq_destroy (&workq); if (status != 0) err_abort (status, "Destroy work queue"); /* * By now, all of the engine_t structures have been placed * on the list (by the engine thread destructors), so we * can count and summarize them. */ engine = engine_list_head; while (engine != NULL) { count++; calls += engine->calls; printf ("engine %d: %d calls\n", count, engine->calls); engine = engine->link; } printf ("%d engine threads processed %d calls\n", count, calls); return 0; }
int main(int argc, char** argv) { pthread_t thread_id; engine_t* engine; int count = 0; int calls = 0; int status; status = pthread_key_create(&engine_key, destructor); assert(status == 0); status = workq_init(&workq, 4, engine_routine); assert(status == 0); status = pthread_create(&thread_id, NULL, thread_routine, NULL); assert(status == 0); (void)thread_routine(NULL); status = pthread_join(thread_id, NULL); assert(status == 0); status = workq_destroy(&workq); assert(status == 0); engine = engine_list_head; while (engine != NULL) { count++; calls += engine->calls; printf("engine %d: %d calls\n", count, engine->calls); engine = engine->link; } printf("%d engine threads processed %d calls\n", count, calls); return 0; }
/** * This is the architecture-independent kernel entry point. Before it is * called, architecture-specific code has done the bare minimum initialization * necessary. This function initializes the kernel and its various subsystems. * It calls back to architecture-specific code at several well defined points, * which all architectures must implement (e.g., setup_arch()). * * \callgraph */ void start_kernel() { unsigned int cpu; unsigned int timeout; int status; /* * Parse the kernel boot command line. * This is where boot-time configurable variables get set, * e.g., the ones with param() and DRIVER_PARAM() specifiers. */ parse_params(lwk_command_line); /* * Initialize the console subsystem. * printk()'s will be visible after this. */ console_init(); /* * Hello, Dave. */ printk("%s", lwk_banner); printk(KERN_DEBUG "%s\n", lwk_command_line); sort_exception_table(); /* * Do architecture specific initialization. * This detects memory, CPUs, architecture dependent irqs, etc. */ setup_arch(); /* * Setup the architecture independent interrupt handling. */ irq_init(); /* * Initialize the kernel memory subsystem. Up until now, the simple * boot-time memory allocator (bootmem) has been used for all dynamic * memory allocation. Here, the bootmem allocator is destroyed and all * of the free pages it was managing are added to the kernel memory * pool (kmem) or the user memory pool (umem). * * After this point, any use of the bootmem allocator will cause a * kernel panic. The normal kernel memory subsystem API should be used * instead (e.g., kmem_alloc() and kmem_free()). */ mem_subsys_init(); /* * Initialize the address space management subsystem. */ aspace_subsys_init(); sched_init_runqueue(0); /* This CPUs scheduler state + idle task */ sched_add_task(current); /* now safe to call schedule() */ /* * Initialize the task scheduling subsystem. */ core_timer_init(0); /* Start the kernel filesystems */ kfs_init(); /* * Initialize the random number generator. */ rand_init(); workq_init(); /* * Boot all of the other CPUs in the system, one at a time. */ printk(KERN_INFO "Number of CPUs detected: %d\n", num_cpus()); for_each_cpu_mask(cpu, cpu_present_map) { /* The bootstrap CPU (that's us) is already booted. */ if (cpu == 0) { cpu_set(cpu, cpu_online_map); continue; } printk(KERN_DEBUG "Booting CPU %u.\n", cpu); arch_boot_cpu(cpu); /* Wait for ACK that CPU has booted (5 seconds max). */ for (timeout = 0; timeout < 50000; timeout++) { if (cpu_isset(cpu, cpu_online_map)) break; udelay(100); } if (!cpu_isset(cpu, cpu_online_map)) panic("Failed to boot CPU %d.\n", cpu); } /* * Initialize the PCI subsystem. */ init_pci(); /* * Enable external interrupts. */ local_irq_enable(); #ifdef CONFIG_NETWORK /* * Bring up any network devices. */ netdev_init(); #endif #ifdef CONFIG_CRAY_GEMINI driver_init_list("net", "gemini"); #endif #ifdef CONFIG_BLOCK_DEVICE /** * Initialize the block devices */ blkdev_init(); #endif mcheck_init_late(); /* * And any modules that need to be started. */ driver_init_by_name( "module", "*" ); #ifdef CONFIG_KGDB /* * Stop eary (before "late" devices) in KGDB if requested */ kgdb_initial_breakpoint(); #endif /* * Bring up any late init devices. */ driver_init_by_name( "late", "*" ); /* * Bring up the Linux compatibility layer, if enabled. */ linux_init(); #ifdef CONFIG_DEBUG_HW_NOISE /* Measure noise/interference in the underlying hardware/VMM */ extern void measure_noise(int, uint64_t); measure_noise(0, 0); #endif /* * Start up user-space... */ printk(KERN_INFO "Loading initial user-level task (init_task)...\n"); if ((status = create_init_task()) != 0) panic("Failed to create init_task (status=%d).", status); current->state = TASK_EXITED; schedule(); /* This should not return */ BUG(); }
int main(void) { workq_msg_t msg; int x; int size = 0; work_queue = workq_init(NULL, 0); if(work_queue < 0) { printf("Failed to initialize a private work queue: error %s (%d)\n", strerror(errno), errno); exit(EXIT_FAILURE); } atexit(kill_q); printf("Adding 10 items to the queue in order...\n"); ADD_OR_DIE(one, work_queue, 1); ADD_OR_DIE(two, work_queue, 2); ADD_OR_DIE(three, work_queue, 3); ADD_OR_DIE(four, work_queue, 4); ADD_OR_DIE(five, work_queue, 5); ADD_OR_DIE(six, work_queue, 6); ADD_OR_DIE(seven, work_queue, 7); ADD_OR_DIE(eight, work_queue, 8); ADD_OR_DIE(nine, work_queue, 9); ADD_OR_DIE(ten, work_queue, 10); printf("Removing from queue...\n"); for(x = 1; x <= 10; ++x) { size = workq_get(work_queue, &msg); if(size < 0) { printf("Error pulling from queue: %s (%d)\n", strerror(errno), errno); exit(EXIT_FAILURE); } else if(size == 0) { printf("No messages left...\n"); } else { printf("Got message \"%s\" priority %ld\n", msg.data, msg.type); } } printf("Adding 10 items to the queue in reverse order...\n"); ADD_OR_DIE(ten, work_queue, 10); ADD_OR_DIE(nine, work_queue, 9); ADD_OR_DIE(eight, work_queue, 8); ADD_OR_DIE(seven, work_queue, 7); ADD_OR_DIE(six, work_queue, 6); ADD_OR_DIE(five, work_queue, 5); ADD_OR_DIE(four, work_queue, 4); ADD_OR_DIE(three, work_queue, 3); ADD_OR_DIE(two, work_queue, 2); ADD_OR_DIE(one, work_queue, 1); printf("Removing from queue...\n"); for(x = 1; x <= 10; ++x) { size = workq_get(work_queue, &msg); if(size < 0) { printf("Error pulling from queue: %s (%d)\n", strerror(errno), errno); exit(EXIT_FAILURE); } else if(size == 0) { printf("No messages left...\n"); } else { printf("Got message \"%s\" priority %ld\n", msg.data, msg.type); } } printf("Tests passed.\n"); exit(EXIT_SUCCESS); }