Beispiel #1
0
int
workqueue_create(struct workqueue **wqp, const char *name,
    void (*callback_func)(struct work *, void *), void *callback_arg,
    pri_t prio, int ipl, int flags)
{
	struct workqueue *wq;
	struct workqueue_queue *q;
	void *ptr;
	int error = 0;

	CTASSERT(sizeof(work_impl_t) <= sizeof(struct work));

	ptr = kmem_zalloc(workqueue_size(flags), KM_SLEEP);
	wq = (void *)roundup2((uintptr_t)ptr, coherency_unit);
	wq->wq_ptr = ptr;
	wq->wq_flags = flags;

	workqueue_init(wq, name, callback_func, callback_arg, prio, ipl);

	if (flags & WQ_PERCPU) {
		struct cpu_info *ci;
		CPU_INFO_ITERATOR cii;

		/* create the work-queue for each CPU */
		for (CPU_INFO_FOREACH(cii, ci)) {
			q = workqueue_queue_lookup(wq, ci);
			error = workqueue_initqueue(wq, q, ipl, ci);
			if (error) {
				break;
			}
		}
	} else {
Beispiel #2
0
int rate_submit_init(struct thread_data *td, struct sk_out *sk_out)
{
    if (td->o.io_submit_mode != IO_MODE_OFFLOAD)
        return 0;

    return workqueue_init(td, &td->io_wq, &rated_wq_ops, td->o.iodepth, sk_out);
}
Beispiel #3
0
kstat_t krhino_init(void)
{
    g_sys_stat = RHINO_STOPPED;

#if (RHINO_CONFIG_USER_HOOK > 0)
    krhino_init_hook();
#endif

    runqueue_init(&g_ready_queue);

    tick_list_init();

#if (RHINO_CONFIG_SYSTEM_STATS > 0)
    kobj_list_init();
#endif

#if (RHINO_CONFIG_MM_TLF > 0)
    k_mm_init();
#endif

#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
    klist_init(&g_res_list);
    krhino_sem_create(&g_res_sem, "res_sem", 0);
    dyn_mem_proc_task_start();
#endif

#if (RHINO_CONFIG_CPU_NUM > 1)
    for (uint8_t i = 0; i < RHINO_CONFIG_CPU_NUM; i++) {
        krhino_task_cpu_create(&g_idle_task[i], "idle_task", NULL, RHINO_IDLE_PRI, 0,
                               &g_idle_task_stack[i][0], RHINO_CONFIG_IDLE_TASK_STACK_SIZE,
                               idle_task, i, 1u);
    }
#else
    krhino_task_create(&g_idle_task[0], "idle_task", NULL, RHINO_IDLE_PRI, 0,
                       &g_idle_task_stack[0][0], RHINO_CONFIG_IDLE_TASK_STACK_SIZE,
                       idle_task, 1u);
#endif

#if (RHINO_CONFIG_WORKQUEUE > 0)
    workqueue_init();
#endif

#if (RHINO_CONFIG_TIMER > 0)
    ktimer_init();
#endif

#if (RHINO_CONFIG_CPU_USAGE_STATS > 0)
    cpu_usage_stats_start();
#endif

    rhino_stack_check_init();

    return RHINO_SUCCESS;
}
Beispiel #4
0
int
main(int argc, char **argv)
{
    int rc;
    workqueue_t wq;

    rc = workqueue_init(&wq, "thread");
    assert(rc == 0);

    rc = workqueue_submit(&wq, hello, NULL);
    assert(rc == 0);

    workqueue_lock(&wq);
    while (!workqueue_idle(&wq)) {
        workqueue_wait(&wq, 0);
    }
    workqueue_unlock(&wq);

    workqueue_destroy(&wq);
    return 0;
}
int main(int argc, char *argv[]) {
	struct prg_ctx prg;
	int i;
	int num_jobs = 3;
	int ret;
	printf("starting\n");

	signal(SIGTERM, sighandler_func);

	prg.counter = 0;
	prg.ctx = workqueue_init(32, 1, NULL);

	for (i = 0; i < num_jobs; i++) {
		ret = workqueue_add_work(prg.ctx, 2, 0,
			callback_func, &prg);

		if (ret >= 0) {
			printf("Added job %d \n", ret);
		} else {
		  	printf("Error adding job err=%d\n", ret);
		}
	}
	workqueue_show_status(prg.ctx, stdout);

	for (i = 0; i < num_jobs; i++) {
		printf("job %d is queued=%d running=%d queued_or_running=%d\n", i,
			workqueue_job_queued(prg.ctx, i),
			workqueue_job_running(prg.ctx, i),
			workqueue_job_queued_or_running(prg.ctx, i));
	}

	workqueue_show_status(prg.ctx, stdout);

	for (i = 0; i < num_jobs; i++) {
		ret = workqueue_dequeue(prg.ctx, i),
		printf(" dequeue job %d  ret=%d\n", i , ret);
	}
	workqueue_show_status(prg.ctx, stdout);

	for (i = 0; i < num_jobs; i++) {
		ret = workqueue_add_work(prg.ctx, 2, 0,
			callback_func, &prg);

		if (ret >= 0) {
			printf("Added job %d \n", ret);
		} else {
		  	printf("Error adding job err=%d\n", ret);
		}
	}

	for (i = 0; i < num_jobs*2; i++) {
		ret = workqueue_dequeue(prg.ctx, i),
		printf(" dequeue job %d  ret=%d\n", i , ret);
	}


	for (i = 20; i && (ret = workqueue_get_queue_len(prg.ctx)); i--) {
	  	printf("waiting for %d jobs \n", ret);
		sleep(1);
	}

	workqueue_destroy(prg.ctx);

#ifdef WINDOWS
	system("pause");
#endif
	return 0;
}
int main(int argc, char *argv[]) {
	struct prg_ctx prg;
	int i;
	int num_jobs=6;
	int ret;
	printf("starting\n");
	prg.counter = 0;
	prg.ctx = workqueue_init(32, 1, NULL);

	for (i = 0; i < num_jobs; i++) {
		ret = workqueue_add_work(prg.ctx, 2, 0,
			callback_func, &prg);

		if (ret >= 0) {
			printf("Added job %d \n", ret);
		} else {
		  	printf("Error adding job err=%d\n", ret);
		}
	}
	workqueue_show_status(prg.ctx, stdout);

	for (i = 0; i < num_jobs; i++) {
		printf("job %d is queued=%d running=%d queued_or_running=%d\n", i,
			workqueue_job_queued(prg.ctx, i),
			workqueue_job_running(prg.ctx, i),
			workqueue_job_queued_or_running(prg.ctx, i));
	}

	for (i = 0; i < num_jobs/2; i++) {
		ret = workqueue_add_work(prg.ctx, 5, 0,
			callback_func, &prg);

		if (ret >= 0) {
			printf("Added job %d \n", ret);
		} else {
		  	printf("Error adding job err=%d\n", ret);
		}
	}
	workqueue_show_status(prg.ctx, stdout);

	for (i = 0; i < num_jobs/2; i++) {
		ret = workqueue_add_work(prg.ctx, 1, 0,
			callback_func, &prg);

		if (ret >= 0) {
			printf("Added job %d \n", ret);
		} else {
		  	printf("Error adding job err=%d\n", ret);
		}
	}
	workqueue_show_status(prg.ctx, stdout);

	for (i = 20; i && (ret = workqueue_get_queue_len(prg.ctx)) > 5; i--) {
	  	printf("waiting for %d jobs \n", ret);
		sleep(1);
	}

	// empty out remaining jobs and wait for running job to finish
	workqueue_empty_wait(prg.ctx);

	workqueue_destroy(prg.ctx);

#ifdef WINDOWS
	system("pause");
#endif
	return 0;
}
/**
* Run the server.  This function blocks, only returning when the server has terminated.
*/
int runServer(void) {
	int sockfd;
	struct sockaddr_in listen_addr;
	struct event ev_accept;
	int reuseaddr_on;

	/* Initialize libevent. */
	event_init();

	/* Set signal handlers
	 sigset_t:信号集,其被定义为一种数据类型
	 struct sigaction {
	 void     (*sa_handler)(int);	//此参数和signal()的参数handler 相同, 代表新的信号处理函数
	 void     (*sa_sigaction)(int, siginfo_t *, void *);
	 sigset_t   sa_mask;			//用来设置在处理该信号时暂时将sa_mask 指定的信号搁置
	 int        sa_flags;			//用来设置信号处理的其他相关操作,  A_NOCLDSTOP: 如果参数signum 为SIGCHLD, 则当子进程暂停时并不会通知父进程;SA_RESTART: 被信号中断的系统调用会自行重启;
	 void     (*sa_restorer)(void);	//此参数没有使用
	 };
	*/
	sigset_t sigset;
	sigemptyset(&sigset);	//初始化信号集,信号集里面的所有信号被清空
	/*struct sigaction siginfo = {
		.sa_handler = sighandler,
		.sa_mask = sigset,
		.sa_flags = SA_RESTART,
		};*/
	struct sigaction siginfo;
	siginfo.sa_handler = sighandler;
	siginfo.sa_mask = sigset;
	siginfo.sa_flags = SA_RESTART;
	sigaction(SIGINT, &siginfo, NULL);	//程序终止(interrupt)信号, 在用户键入INTR字符(通常是Ctrl-C)时发出 
	sigaction(SIGTERM, &siginfo, NULL);	//程序结束(terminate)信号, 与SIGKILL不同的是该信号可以被阻塞和处理.通常用来要求程序自己正常退出.shell命令kill缺省产生这个信号.
	/* Create our listening socket. */
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd < 0) {
		err(1, "listen failed");
	}
	memset(&listen_addr, 0, sizeof(listen_addr));
	listen_addr.sin_family = AF_INET;
	listen_addr.sin_addr.s_addr = INADDR_ANY;
	listen_addr.sin_port = htons(SERVER_PORT);
	if (bind(sockfd, (struct sockaddr *)&listen_addr, sizeof(listen_addr)) < 0) {
		err(1, "bind failed");
	}
	if (listen(sockfd, CONNECTION_BACKLOG) < 0) {
		err(1, "listen failed");
	}
	reuseaddr_on = 1;
	setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr_on, sizeof(reuseaddr_on));

	/* Set the socket to non-blocking, this is essential in event
	* based programming with libevent. */
	if (setnonblock(sockfd) < 0) {
		err(1, "failed to set server socket to non-blocking");
	}
	evbase_accept = event_base_new();
	if (NULL == evbase_accept)
	{
		perror("Unable to create socket accept event base");
		close(sockfd);
		return 1;
	}

	/* Initialize work queue. */
	if (workqueue_init(&workqueue, NUM_THREADS)) {
		perror("Failed to create work queue");
		close(sockfd);
		workqueue_shutdown(&workqueue);
		return 1;
	}

	/* We now have a listening socket, we create a read event to
	* be notified when a client connects. */
	event_set(&ev_accept, sockfd, EV_READ | EV_PERSIST, on_accept, (void *)&workqueue);
	event_base_set(evbase_accept, &ev_accept);
	event_add(&ev_accept, NULL);

	printf("Server is running...\n");

	/* Start the event loop. */
	event_base_dispatch(evbase_accept);

	event_base_free(evbase_accept);
	evbase_accept = NULL;

	close(sockfd);

	printf("Server shutdown.\n");

	return 0;
}
Beispiel #8
0
/**
 * Run the server.  This function blocks, only returning when the server has terminated.
 */
int runServer(void) {
	int listenfd;
	struct sockaddr_in listen_addr;
	struct event ev_accept;
	int reuseaddr_on;

	/* Initialize libevent. */
	event_init();

	/* Set signal handlers */
	sigset_t sigset;
	sigemptyset(&sigset);
	struct sigaction siginfo = {
		.sa_handler = sighandler,
		.sa_mask = sigset,
		.sa_flags = SA_RESTART,
	};
	sigaction(SIGINT, &siginfo, NULL);
	sigaction(SIGTERM, &siginfo, NULL);

	/* Create our listening socket. */
	listenfd = socket(AF_INET, SOCK_STREAM, 0);
	if (listenfd < 0) {
		err(1, "listen failed");
	}
	memset(&listen_addr, 0, sizeof(listen_addr));
	listen_addr.sin_family = AF_INET;
	listen_addr.sin_addr.s_addr = INADDR_ANY;
	listen_addr.sin_port = htons(SERVER_PORT);
	if (bind(listenfd, (struct sockaddr *)&listen_addr, sizeof(listen_addr)) < 0) {
		err(1, "bind failed");
	}
	if (listen(listenfd, CONNECTION_BACKLOG) < 0) {
		err(1, "listen failed");
	}
	reuseaddr_on = 1;
	setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr_on, sizeof(reuseaddr_on));

	/* Set the socket to non-blocking, this is essential in event
	 * based programming with libevent. */
	if (setnonblock(listenfd) < 0) {
		err(1, "failed to set server socket to non-blocking");
	}

	if ((evbase_accept = event_base_new()) == NULL) {
		perror("Unable to create socket accept event base");
		close(listenfd);
		return 1;
	}

	/* Initialize work queue. */
	if (workqueue_init(&workqueue, NUM_THREADS)) {
		perror("Failed to create work queue");
		close(listenfd);
		workqueue_shutdown(&workqueue);
		return 1;
	}

	/* We now have a listening socket, we create a read event to
	 * be notified when a client connects. */
	event_set(&ev_accept, listenfd, EV_READ|EV_PERSIST, on_accept, (void *)&workqueue);
	event_base_set(evbase_accept, &ev_accept);
	event_add(&ev_accept, NULL);

	printf("Server running.\n");

	/* Start the event loop. */
	event_base_dispatch(evbase_accept);

	event_base_free(evbase_accept);
	evbase_accept = NULL;

	close(listenfd);

	printf("Server shutdown.\n");

	return 0;
}