EXPORT int stpool_task_clone_and_queue(struct sttask *ptask, int clone_schattr, struct sttask **ptask2, void *task_arg) { int e; ctask_t *nptask; cpool_t *pool = TASK_CAST_DOWN(ptask)->pool; struct schattr *attr = NULL, attr0; if (!pool) return POOL_TASK_ERR_DESTINATION; if (clone_schattr) { attr = &attr0; stpool_task_getschattr(ptask, attr); } if (!task_arg) task_arg = ptask->task_arg; if (!ptask2) { /** * We try to get a task object from the cache, * (@__stpool_cache_put(ptask) should be called later to recycle it) */ nptask = __stpool_cache_get(pool); if (!nptask) return POOL_ERR_NOMEM; __stpool_task_INIT(nptask, ptask->task_name, ptask->task_run, ptask->task_err_handler, task_arg); assert (!nptask->ref); } else { if (!(*ptask2 = stpool_task_new(pool, ptask->task_name, ptask->task_run, ptask->task_err_handler, task_arg))) return POOL_ERR_NOMEM; nptask = (ctask_t *)*ptask2; } nptask->gid = TASK_CAST_DOWN(ptask)->gid; if (attr) stpool_task_setschattr(TASK_CAST_UP(nptask), attr); /** * Deliver the task into the queue */ if ((e = ME_CALL(pool, task_queue)(pool->ins, nptask))) { if (ptask2) stpool_task_delete(*ptask2); else __stpool_cache_put(pool, nptask); /** * Get the export error code according to the inner error code */ return __stpool_liberror(e); } return 0; }
EXPORT struct sttask * stpool_task_clone(struct sttask *ptask, int clone_schattr) { struct sttask *nptask; nptask = stpool_task_new(TASK_CAST_DOWN(ptask)->pool, ptask->task_name, ptask->task_run, ptask->task_err_handler, ptask->task_arg); if (nptask) { if (clone_schattr) { struct schattr attr; stpool_task_getschattr(ptask, &attr); stpool_task_setschattr(nptask, &attr); } TASK_CAST_DOWN(nptask)->gid = TASK_CAST_DOWN(ptask)->gid; } return nptask; }
int main() { stpool_t *pool; int i, error, c = 0; struct schattr attr = {0, 1, ep_SCHE_TOP}; struct sttask *ptsk; long eCAPs = eCAP_F_DYNAMIC|eCAP_F_SUSPEND|eCAP_F_THROTTLE|eCAP_F_ROUTINE| eCAP_F_DISABLEQ|eCAP_F_PRIORITY|eCAP_F_WAIT_ALL; /** NO buffer */ setbuf(stdout, 0); /** Create a pool */ pool = stpool_create("mypool", /** pool name */ eCAPs, /** neccessary capabilites */ 20, /** limited threads number*/ 0, /** number of threads reserved to waiting for tasks*/ 0, /** do not suspend the pool */ 1 /** priority queue num */ ); if (!pool) abort(); /** Print the status of the pool */ printf("@stpool_create(20, 0, 0, 10)\n%s\n", stpool_stat_print(pool)); /*------------------------------------------------------------/ /--------------------Test @stpool_adjust(_abs)----------------/ /------------------------------------------------------------*/ printf("\nPress any key to test the @stpool_adjust(300, 4) ....\n"); getchar(); stpool_adjust_abs(pool, 300, 4); printf("@stpool_adjust_abs(pool, 300, 4)\n%s\n", stpool_stat_print(pool)); /** We call @stpool_adjust to recover the pool env */ printf("\nPress any key to test the @stpool_adjust(-280, -4) ....\n"); getchar(); stpool_adjust(pool, -280, -4); printf("@stpool_adjust(pool, -280, -4)\n%s\n", stpool_stat_print(pool)); /*------------------------------------------------------------------/ /----------------Test rescheduling task----------------------------/ /------------------------------------------------------------------*/ printf("\nPress any key to test rescheduling task. <then press key to stop testing.>\n"); getchar(); /** We creat a customed task to do the test */ ptsk = stpool_task_new(NULL, "test-reschedule", task_reschedule, NULL, &c); /** Attach the destinational pool */ error = stpool_task_set_p(ptsk, pool); if (error) printf("***Err: %d(%s). (try eCAP_F_CUSTOM_TASK)\n", error, stpool_strerror(error)); else { stpool_task_set_userflags(ptsk, 0x1); stpool_task_queue(ptsk); getchar(); /** Set the flag to notify the task to exit the rescheduling test */ stpool_task_set_userflags(ptsk, 0); stpool_task_wait(ptsk, -1); } stpool_task_delete(ptsk); /*-------------------------------------------------------------------/ /--------------------Test the throttle------------------------------/ /-------------------------------------------------------------------*/ printf("\nPress any key to test the throttle ....\n"); getchar(); /** Turn the throttle on */ stpool_throttle_enable(pool, 1); error = stpool_add_routine(pool, "test-throttle", task_run, task_err_handler, &c, NULL); if (error) printf("***Err: @stpool_add_task: %d\n", error); /** Turn the throttle off */ stpool_throttle_enable(pool, 0); /*-------------------------------------------------------------------/ /------------------Test the priority--------------------------------/ /-------------------------------------------------------------------*/ printf("\nPress any key to test the priority ....\n"); getchar(); stpool_suspend(pool, 0); /** * Add a task with zero priority, and the task will be pushed into the * lowest priority queue. */ stpool_add_routine(pool, "zero-priority", task_run, task_err_handler, &c, NULL); /** * task("non-zero-priority") will be scheduled prior to the task("zero-priority") * since it has a higher priority. */ stpool_add_routine(pool, "non-zero-priority", task_run, task_err_handler, &c, &attr); /** Wake up the pool to schedule the tasks */ stpool_resume(pool); /** Wait for all tasks' being done completely */ stpool_wait_all(pool, -1); /*------------------------------------------------------------------/ /---------------Test running amount of tasks-----------------------/ /------------------------------------------------------------------*/ printf("\nPress any key to add tasks ... <then can press any key to remove them.>\n"); getchar(); /** * We can suspend the pool firstly, and then resume the pool after delivering our * tasks into the pool, It'll be more effecient to do it like that if there are * a large amount of tasks that will be added into the pool. */ for (i=0; i<8000; i++) stpool_add_routine(pool, "task_run", task_run, task_err_handler, &c, NULL); /*----------------------------------------------------------------/ /-------------Test stoping all tasks fastly----------------------/ /----------------------------------------------------------------*/ printf("\nPress any key to test stoping all tasks fastly.\n"); getchar(); stpool_throttle_enable(pool, 1); stpool_remove_all(pool, 1); /** Wait for all tasks' being done */ stpool_wait_all(pool, -1); printf("---------------------------tasks have been finished.\n"); /*---------------------------------------------------------------/ /-------------Release the pool-----------------------------------/ /---------------------------------------------------------------*/ printf("Press any key to release the pool...\n"); getchar(); /** Release the pool */ printf("%s\n", stpool_stat_print(pool)); stpool_release(pool); printf("Press any key to exit ...\n"); getchar(); return 0; }