forked from haotian0329/libstpool
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstpool.h
929 lines (843 loc) · 31.3 KB
/
stpool.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
#ifndef __ST_POOL_H__
#define __ST_POOL_H__
/*
* COPYRIGHT (C) 2014 - 2020, piggy_xrh
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Stpool is portable and efficient tasks pool library, it can works on diferent
* platforms such as Windows, linux, unix and ARM.
*
* If you have any troubles or questions on using the library, contact me.
*
* (Email: piggy_xrh@163.com QQ: 1169732280)
* blog: http://www.oschina.net/code/snippet_1987090_44422
*/
#include <time.h>
#include <stdlib.h>
#if defined(_WIN32) || defined(WIN32) || defined(_WIN64)
#ifdef _USRDLL
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif
#else
#define EXPORT
#endif
typedef void *HPOOL;
/* Error code */
enum {
/* System is out of memeory
*
* (@stpool_add_routine may return the error code)
*/
STPOOL_ERR_NOMEM = 1,
/* Task pool is being destroyed
*
* (It indicates that @stpool_release has been called and
* the reference of the pool is zero)
*/
STPOOL_ERR_DESTROYING = 2,
/* Task pool has been destroyed or has not been created */
STPOOL_ERR_NOCREATED = 3,
/* The throttle of the pool is disabled
*
* (It indicates that user has called @stpool_throttle_enable(hp, 0)
* to turn the throttle swither on)
*/
STPOOL_ERR_THROTTLE = 4,
/* The task has been removed by user.
*
* (It indicates that the task has been removed by @stpool_remove_pending_task
* or @stpool_mark_task(ex))
*/
STPOOL_TASK_ERR_REMOVED = 5,
/* The task is requested to be added into a deferent pool, But the task has
* not disconnected with the current pool completely.
*
* (@stpool_add_routine may return the error code)
*/
STPOOL_TASK_ERR_BUSY = 7,
/* The task has been marked with TASK_VMARK_DISABLE_QUEUE
* (@stpool_add_task may return the error code)
*/
STPOOL_TASK_ERR_DISABLE_QUEUE = 8,
};
struct sttask_t {
/* A const string to describle the task */
const char *task_name;
/* @task_run will be called when the task is scheduled by the pool.
* user can do their works in this function.
*/
int (*task_run)(struct sttask_t *ptsk);
/* If @task_complete is not NULL, it will be called when one of the conditions
* below matches.
* 1. @task_run has been executed by the pool.
* 2. The task is removed from the pool by @stpool_remove_pending_task
* or @stpool_mark_task(ex)
*
* NOTE:
* 1). If @task_run has been excuted by the pool, the argument @vmflags will
* owns the mask STTASK_VMARK_DONE, and the @task_code will be set to the value
* returned by @task_run. or the the @task_code will be set properly.
(@see the error codes STPOOL_XXX describled above)
*/
void (*task_complete)(struct sttask_t *ptsk, long vmflags, int task_code);
/* The argument reserved for task */
void *task_arg;
/* After users' succeeding in calling @stpool_add_task or @stpool_add_routine,
* the @hp_last_attached will be set to the handle of the pool automatically.
*/
HPOOL hp_last_attached;
/* Private datas for inner implemention. */
char impl_stack[0];
};
struct schattr_t {
/* If @permanent is not zero, the task's priority will not
* be changed until the user call @stpool_task_setschattr
* to modifiy it manually */
int permanent;
/* The priority of the task */
int sche_pri;
/* The policy to schedule the task (STP_SCHE_XX) */
int sche_pri_policy;
};
/* Status of the task */
enum {
/* Task is waiting for being schuduled */
STTASK_STAT_WAIT = (short)0x01,
/* Task is being scheduled by the pool */
STTASK_STAT_SCHEDULING = (short)0x02,
/* Task has been swaped from the ready queue since the
* pool that the task belong to has been marked suspened */
STTASK_STAT_SWAPED = (short)0x04,
/* Task has been marked with removed */
STTASK_STAT_DISPATCHING = (short)0x08,
/* The task should be added into the pool automatically
* after having done the task */
STTASK_STAT_WAIT_PENDING = (short)0x10,
};
/* Flags of the task */
enum {
/* @task_run has been executed */
STTASK_VMARK_DONE = 0x0001,
/* The task is removed by @stpool_remove_pending_task/@stpool_mark_task
* The user can mark tasks with STTASK_VMARK_REMOVE_BYPOOL or
* STTASK_VMARK_REMOVE, and as a result, the tasks will be removed from
* the pending queue.
* If task is marked with STTASK_VMARK_REMOVE_BYPOOL, @task_complete
* will be called by the pool. or @task_complete will be called by the
* function who marks the task.
*/
STTASK_VMARK_REMOVE_BYPOOL = 0x0004,
STTASK_VMARK_REMOVE = 0x0008,
/* The pool is being destroyed */
STTASK_VMARK_POOL_DESTROYING = 0x0010,
/* The task should be done again */
STTASK_VMARK_DO_AGAIN = 0x0020,
/* The task can(not) be delived into the pool */
STTASK_VMARK_DISABLE_QUEUE = 0x0040,
STTASK_VMARK_ENABLE_QUEUE = 0x0080,
};
/* The policy to schedule the tasks */
enum {
/* Insert our task before the tasks who has the same
* priority exisiting in the pool.
*/
STP_SCHE_TOP = 1,
/* Insert our task after the tasks who has the same
* priority exisiting in the pool.
*/
STP_SCHE_BACK,
};
/* Status details about the task */
struct stpool_tskstat_t {
/* Status of the task */
long stat;
/* Flags of the task (STTASK_VMARK_XX) */
long vmflags;
/* Current priority of the task */
int pri;
/* The object of the task */
struct sttask_t *task;
};
/* Status of the pool */
struct stpool_stat_t {
long ref; /* The user refereces */
time_t created; /* The time when the pool is created */
int pri_q_num; /* The number of the priority queue */
int throttle_enabled; /* Is throttle swither on ? */
int suspended; /* Is pool suspended ? */
int maxthreads; /* Max servering threads number */
int minthreads; /* Min servering threads number */
int curthreads; /* The number of threads exisiting in the pool */
int curthreads_active; /* The number of threads who is scheduling tasks */
int curthreads_dying; /* The number of threads who has been marked died by @stpool_adjust(_abs)/@stpool_flush */
long acttimeo; /* Max rest time of the threads (ms) */
size_t tasks_peak; /* The peak of the tasks number */
size_t threads_peak; /* The peak of the threads number */
size_t tasks_added; /* The number of tasks that has been added into the pool since the pool is created */
size_t tasks_done; /* The number of tasks that the pool has done since the pool is created */
size_t tasks_dispatched; /* The number of completion routines that the pool has called for removed tasks */
size_t cur_tasks; /* The number of tasks existing in the pool */
size_t cur_tasks_pending; /* The number of tasks who is waiting for being scheduled */
size_t cur_tasks_scheduling; /* The number of tasks who is being scheduled */
size_t cur_tasks_removing; /* The number of tasks who is marked removed */
};
enum ep_SCHE
{
ep_SCHE_NONE,
ep_SCHE_RR,
ep_SCHE_FIFO,
ep_SCHE_OTHER
};
struct stpool_thattr_t {
/* Stack size (0:default) */
int stack_size;
/* Schedule policy */
enum ep_SCHE ep_schep;
/* Schedule priority ([1-100] 0:default) */
int sche_priority;
};
#ifdef __cplusplus
extern "C" {
#endif
/*----------------APIs about the task --------------*/
/*@stpool_task_size
* Acquire the object size of the task
*
* Arguments:
* None
*
* Return:
* the object size of the task
*/
extern const size_t g_const_TASK_SIZE;
#define stpool_task_size() g_const_TASK_SIZE
/*@stpool_task_init
* Initialize the task object
*
* Arguments:
* @see the definition of the struct task_t for more details.
*
* Return:
* None
*/
EXPORT void stpool_task_init(struct sttask_t *ptsk,
const char *name, int (*run)(struct sttask_t *ptsk),
void (*complete)(struct sttask_t *ptsk, long vmflags, int code),
void *arg);
/*@stpool_task_new
* Allocate a task object from the heap. (The task allocated by
* @stpool_task_new should be free manually by calling @stpool_task_delete)
*
* Arguments:
* @see the definition of the struct task_t for more details.
*
* Return:
* On success, @stpool_task_new returns a task object,
* On error, NULL is returned.
*/
EXPORT struct sttask_t *stpool_task_new(const char *name,
int (*run)(struct sttask_t *ptsk),
void (*complete)(struct sttask_t *ptsk, long vmflags, int code),
void *arg);
/*@stpool_task_clone
* Clone a task from a task object. the cloned task should be free manually
* by calling @stpool_task_delete.
*
* Arguments:
* @ptsk [in] The source object.
* @clone_schattr [in] Tell the system whether clone the task's scheduling attribute or not.
*
* Return:
* On success, @stpool_task_clone returns a task object,
* On error, NULL is returned.
*/
EXPORT struct sttask_t *stpool_task_clone(struct sttask_t *ptsk, int clone_schattr);
/*@stpool_task_delete
* Free the task object that allocated by @stpool_task_new or @stpool_task_clone
*
* NOTE:
* Only tasks who does not belong to any pool can be free safely !
* normaly, the task will not be removed from the pool until the task's
* completion routine is executed completely. it means that it is not
* safe to destroy the task manually in the task's completion routine .
* (But If you really want to do this like that, you should call
* @stpool_detach_task firstly to remove the task from the pool
* imediately).
*
* Arguments:
* @ptsk [in] The task object that the user wants to destroy.
*
* Return:
* None
*/
EXPORT void stpool_task_delete(struct sttask_t *ptsk);
/*@stpool_task_set_userflags/stpool_task_get_userflags
* Set/Get the user flags for the task. (uflags' value range is from 0 to 0x7f)
*
* Arguments:
* @ptsk [in] The task object.
* @uflags [in] The private flags that the user want to set
*
* Return:
* The user flags of the task
*/
EXPORT long stpool_task_set_userflags(struct sttask_t *ptsk, long uflags);
EXPORT long stpool_task_get_userflags(struct sttask_t *ptsk);
/*@stpool_task_setschattr
* Set the scheduling attribute for the task
*
* Arguments:
* @ptsk [in] The task object.
* @attr [in] The scheduling attribute that will be applyed on the task
*
* Return:
* None
*/
EXPORT void stpool_task_setschattr(struct sttask_t *ptsk, struct schattr_t *attr);
/*@stpool_task_getschattr
* Get the scheduling attribute for the task
*
* Arguments:
* @ptsk [in] The task object.
* @attr [out] The scheduling attribute of the task.
*
* Return:
* None
*/
EXPORT void stpool_task_getschattr(struct sttask_t *ptsk, struct schattr_t *attr);
/*----------------APIs about the pool --------------*/
/*@stpool_version
* y/m/d-version-desc
*/
EXPORT const char *stpool_version();
/*@stpool_create
* Create a thread pool to running tasks. user should call
* @stpool_release to free the pool if he does not need it any
* more.
*
* Arguments:
* @maxthreads [in] the limited number of threads that is created
* by pool to provide services.
*
* @minthreads [in] the min number of threads that should be reserved
* to wait for tasks.
*
* @suspend [in] if @suspend is 1, the pool will not schedule any
* tasks that have been added into the pool untill the
* user calls @stpool_resume to wake up it.
*
* @pri_q_num [in] the number of the priority queues that the user wants
* to create. a priority task will be inserted into a propriate
* priority queue, and the tasks who has the higher priority
* will be scheduled prior to the tasks who has a lower priority.
* Return:
* On success, @stpool_create returns a pool handle. On error, NULL is returned,
*/
EXPORT HPOOL stpool_create(int maxthreads, int minthreads, int suspend, int pri_q_num);
EXPORT void stpool_thread_setscheattr(HPOOL hp, struct stpool_thattr_t *attr);
EXPORT struct stpool_thattr_t *stpool_thread_getscheattr(HPOOL hp, struct stpool_thattr_t *attr);
/*@stpool_addref
* Increase the reference of the pool. and the reference is 1
* after calling @stpool_create. When the reference of the pool is
* zero, the pool will be destroyed automatically.
*
* Arguments:
* @hp [in] the pool handle
*
* Return:
* the current reference of the pool.
*/
EXPORT long stpool_addref(HPOOL hp);
/*@stpool_release
* Decrease the reference of the pool.
* <see @stpool_addref for more details about the reference>
*
* Arguments:
* @hp [in] the pool handle
*
* Return:
* the current reference of the pool.
*
* NOTE:
* If the reference is zero, the pool will be marked destroyed,
* and as a result, all tasks existing in the pool will be marked with
* STTASK_VMARK_POOL_DESTROYING. and in this case. If the pool is
* suspended, all pending tasks will be removed and dispatched by the
* pool in the background.
* @stpool_release always return imediately. and the pool will be
* destroyed automatically at the background after all tasks have been
* done when it is marked with STTASK_VMARK_POOL_DESTROYING.
*/
EXPORT long stpool_release(HPOOL hp);
/*@stpool_set_activetimeo
* Set the timeout value of the servering threads belong to the pool,
* when tasks are added into the pool and the pool has not been marked sus
* -pended, the pool will create service threads imediately to excute the
* tasks. and the threads will quit automatically if they have not gotton
* any tasks in (@acttimeo + rand() % 60) seconds. the default value of
* @actitimeo is 20.
*
* Arguments:
* @hp [in] the pool handle
*
* @acttimeo [in] seconds for waitting for tasks
* Return:
* None
*/
EXPORT void stpool_set_activetimeo(HPOOL hp, long acttimeo, long randtimeo);
/*@stpool_adjust_abs
* Adjust the threads number of the pool. this function does not
* block, the pool will record the param and adjust the environment
* as soon as possible in the background.
*
* Arguments:
* @hp [in] the pool handle
*
* @maxthreads [in] the limited number of threads who is created
* by the pool to excute tasks.
*
* @minthreads [in] the min number of threads that should be reserved
* to wait for tasks. and it can not be greater than
* the @maxthreads.
* Return:
* None
*/
EXPORT void stpool_adjust_abs(HPOOL hp, int maxthreads, int minthreads);
/*@stpool_adjust
* @stpool_adjust is similar to @stpool_adjust_abs, the only
* difference between them is that the paraments received by
* @stpool_adjust are relative.
*
* stpool_adjust(pool, 1, 2) <==> stpool_adjust_abs(
* pool,
* pool->maxthreads + 1,
* pool->minthreads + 2
* )
*
* stpool_adjust(pool, 2, -1) <==> stpool_adjust_abs(
* pool,
* pool->maxthreads + 2,
* pool->minthreads - 1
* )
*/
EXPORT void stpool_adjust(HPOOL hp, int maxthreads, int minthreads);
/*@stpool_flush
* Mark all unused threads died. it's not recommented to do this since
* the pool knows when to shutdown the threads.
*
* Arguments:
* @hp [in] the pool handle
*
* Return:
* The number of threads who is marked died by @stpool_flush
*
* NOTE:
* This function does not block, user can call @stpool_adjust_wait to
* wait for all died threads' exits.
*/
EXPORT int stpool_flush(HPOOL hp);
/*@stpool_adjust_wait
* @stpool_adjust and @stpool_adjust_abs do not block, If users
* want to make sure that the pool's status is consistent with the
* param they have set, some threads may have to be marked died.
* and the threads who has been marked died will exit imediately
* after having done their current tasks.
* @stpool_adjust will not return until there are none servering
* threads marked died in the pool.
*
* Arguments:
* @hp [in] the pool handle
*
* Return:
* Non
*/
EXPORT void stpool_adjust_wait(HPOOL hp);
/*@stpool_getstat
* Get the status of the pool
*
* Arguments:
* @hp [in] the pool handle
*
* @stat [out] the status structure.
*
* Return:
* The argument @stat filled up with the pool's status will
* be returned.
*/
EXPORT struct stpool_stat_t *stpool_getstat(HPOOL hp, struct stpool_stat_t *stat);
/*@stpool_status_dump
* Print the status of the pool into the buffer.
*
* Arguments:
* @hp [in] the pool handle
*
* @buffer [out] the buffer into where the status data will
* be flushed, If it is NULL, the inner static
* buffer will be used.
*
* @bufferlen [in] the length of the buffer.
*
* Return:
* If the argument @buffer is not NULL, @buffer filled up with
* the pool's status will be returned. or the inner static buffer
* will be passed to user.
*/
EXPORT const char *stpool_status_print(HPOOL hp, char *buffer, size_t bufferlen);
/*@stpool_gettskstat
* Get the status of the task.
*
* Arguments:
* @hp [in] the pool handle
*
* @stat [in/out] the status that the user wants to have a look.
* <NOTE: stat->task should be set to the address of the
* task that the user interests>
* Return:
* If @stat->task does not exist in the pool, the function will return 0, or
* @stat->stat will be returned.
*/
EXPORT long stpool_gettskstat(HPOOL hp, struct stpool_tskstat_t *stat);
/* @stpool_suspend
* If we suspend the pool, the pool will go to sleep, and all pending
* tasks will not be excuted any way until the user calls @stpool_resume
* to wake up the pool.
*
* Arguments:
* @hp [in] the pool handle
* @wait [in] If @wait is 1, it indicated that the user want to wait
* for all the scheduling tasks' completions.
* (Some tasks maybe is being scheduled while user calls
* @stpool_suspend, the pool give users a choices to determine
* whether the @stpool_suspend should wait for the scheduling
* tasks' completions)
*
* Return:
* None
*/
EXPORT void stpool_suspend(HPOOL hp, int wait);
/* @stpool_resume
* Wake up the pool to schedule the tasks again.
*
* Arguments:
* @hp [in] the pool handle
*
* Return:
* None
*/
EXPORT void stpool_resume(HPOOL hp);
/* @stpool_add_task
* Add a task into the pool
*
* Arguments:
* @hp [in] the pool handle
* @ptsk [in] task that will be added into the pool
*
* NOTE:
* @stpool_add_task can be called one more times, If the task
* is already in the pool's pending queue, it does nothing, but if
* the task is being scheduled or has been marked with removed,
* @stpool_add_task will mark the task with @DO_AGAIN. and as a result,
* the task who has been marked with @DO_AGAIN will be added into the
* pool again automatically after the pool's having executed the task
* completely.
*
* But if the task has been marked with @DO_AGAIN, what will it
* happen if the user mark the task with @STTASK_VMARK_REMOVE again
* by calling @stpool_mark_task(ex) or @stpool_remove_pending_task ?
* In this situations, the pool just remove the @DO_AGAIN flag for
* the task.
*
* Return:
* On success, it returns 0.
* On error, error codes below may be returned,
* STPOOL_ERR_DESTROYING
* STPOOL_ERR_NOCREATED
STPOOL_ERR_THROTTLE
* STPOOL_TASK_ERR_BUSY
*
*/
EXPORT int stpool_add_task(HPOOL hp, struct sttask_t *ptsk);
/* @stpool_add_routine
* Add a routine into the pool. (The pool will create a task
* object for the routine with the parameters, and after having executed
* the routine, the pool will detroy the task object automatically).
*
* Arguments:
* @hp [in] the pool handle
* @name [in] a const string to describle the task
* @run [in] the working routine of the task
* @complete [in] the completion routine of the task
* @arg [in] the argument reserved for the task
* @attr [in] the scheduling policy of the task
*
* Return:
* On success, it returns 0.
* On error, error codes below may be returned,
* STPOOL_ERR_DESTROYING
* STPOOL_ERR_NOCREATED
* STPOOL_ERR_THROTTLE
* STPOOL_ERR_NOMEM
*/
EXPORT int stpool_add_routine(HPOOL hp,
const char *name, int (*run)(struct sttask_t *),
void (*complete)(struct sttask_t *, long, int),
void *arg, struct schattr_t *attr);
/* @stpool_remove_pending_task
* Remove tasks that existing in the pending queue.
*
* Arguments:
* @hp [in] the pool handle
*
* @ptsk [in] If ptsk NULL, all the tasks existing in the pending queue
* will be removed.
*
* @dispatched_by_pool [in] If dispatched_by_pool is 1, the pool will be responsible for
* calling the tasks' @task_complete, and the vmflags passed to
* @task_complete will be marked with STTASK_VMARK_REMOVE_BYPOOL.
* or @stpool_remove_pending_task itself will call the task'
* @task_complete, and the vmflags passed to @task_complete will
* be marked with STTASK_MARK_REMOVE.
* Return:
* If @ptsk is NULL, it returns the number of tasks that have been removed, or the task's
* @vmflags will be returned.
*/
EXPORT int stpool_remove_pending_task(HPOOL hp, struct sttask_t *ptsk, int dispatched_by_pool);
/* @stpool_mark_task(ex)
* Walk the status of the tasks existing in the pool. user can mark the task with
* masks listed below.
*
* .STTASK_VMARK_REMOVE
* If the task is in the pending queue, the task will be removed and the task's
* vmflags will be set, But if the task is being scheduled or is being dispatched,
* it has no effect. as you see, its functions are just the same as the @stpool_rem\
* ove_pending_task(hp, ptsk, 0)'s.
*
* .STMASK_VMARK_REMOVE_BYPOOL
* The diference between STTASK_VMARK_REMOVE is that the completion routines of the
* tasks marked with STTASK_VMARK_REMOVE will be called by @stpool_mark_task itself, but
* if the tasks are marked with STMASK_VMARK_REMOVE_BYPOOL, the tasks will be removed
* from the pending queue and the pool is responsible for calling their completions.
* its functions are just the same as the @stpool_remove_pending_task(hp, ptsk, 1)'s.
*
* NOTE:
* Only tasks who is in the pending queue can be marked with STTASK_VMARK_REMOVE or
* STMASK_VMARK_REMOVE_BYPOOL. it means that if the condition #1 is true, the pool will
* prevent the task from being marked with STTASK_VMARK_REMOVE or STTASK_VMARK_REMOVE_BYPOOL.
*
* #1:
* ((STTASK_STAT_SCHEDULING|STTASK_STAT_DISPATCHING) & @task_stat)
*
* Arguments:
* @hp [in] the pool handle
* @ptsk [in] if ptsk is not NULL, @stpool_mark_task will try to mark all tasks
* existing in the pool
* @lflags [in] the flags that the user want to use to mark the task
*
* @tskstat_walk [in] a callback that will be called by @stpool_mark_task_ex to visit
* the status of tasks exsiting in the pool.
*
* NOTE:
* @tskstat_walk returns the flags that will be used to mark the
* current task that passed to @tskstat_walk. but if @tskstat_walk
* returns -1, @stpool_mark_task_ex will do nothing and then it'll
* return and stop visiting the tasks.
*
* @arg [in] the argument reserved for @tskstat_walk
* Return:
* If ptsk is not NULL, @stpool_mark_task return the flags of the task. Or it returns
* the number of tasks that processed by @stpool_mark_task.
*
* @stpool_mark_task_ex return the number of tasks processed by @tskstat_walk.
*/
EXPORT long stpool_mark_task(HPOOL hp, struct sttask_t *ptsk, long lflags);
EXPORT int stpool_mark_task_ex(HPOOL hp,
long (*tskstat_walk)(struct stpool_tskstat_t *stat, void *arg),
void *arg);
/* @stpool_detach_task
* Deatch a task from the pool.
* NOTE:
* @stpool_detach_task will be only allowed to be called in
* the in the task's working routine or in the task's completion
* routine. Usally a task will be connected with a pool when it
* having been added into the pool. and before the task's being
* removed from the pool completely, users can call @stpool_detach_task
* to remove the task from the pool.
*
* NOTE:
* The pool will give a notification to @stpool_task_wait(1/2/3/ex)
* once that the task has been removed from the pool.
*
* Arguments:
* @hp [in] the pool handle
*
* @ptsk [in] the task object
*
* Return:
* None
*/
EXPORT void stpool_detach_task(HPOOL hp, struct sttask_t *ptsk);
/* @stpool_throttle_enable
* The pool has a throttle, if the throttle's switcher is turned on,
* tasks can not be added into the pool until the user calls @stpool_th
* -rottle_enable(hp, 0) to turn it off.
*
* Arguments:
* @hp [in] the pool handle
*
* @enable [in] if enable is 1, the throttle's switcher will be turned
* on, or the throttle's switcher will be turned off.
* Return:
* None
*/
EXPORT void stpool_throttle_enable(HPOOL hp, int enable);
/* @stpool_wkid
* User can save the wkid before his calling the wait functions such as
*@stpool_throttle_wait, @stpool_wait(1/2/3/ex) and @stpool_pending_leq_wait.
*and then call stpool_wakeup(wkid) to wake up these wait functions. Actually,
*the wkid returned by @stpool_wkid is the thread id.
*
* model:
* thread1: thread2:
* wkid = stpool_wkid();
* stpool_task_wait(...) wake up
* <----------- stpool_wakeup(wkid)
*
* Arguments:
* None
*
* Return:
* The id used to wake up the wait functions
*/
EXPORT long stpool_wkid();
/* @stpool_throttle_wait
* If the throttle's switcher is on, the call will not return
* util some users call @stpool_throttle_enable(hp, 0) to turn it
* off.
*
* Arguments:
* @hp [in] the pool handle
*
* @ms [in] milliseconds that the user wants to wait on the
* throttle's switcher.<@ms = -1 = INFINITE>
*
* Return:
* On success, it returns 0. On timeout, 1 is returned.
*
* NOTE: If @stpool_release is called by user and the reference of
* the pool is zero, as a result, the pool will be destroyed,
* If the throttle's switcher is on in this case, 2 will be
* returned.
*/
EXPORT int stpool_throttle_wait(HPOOL hp, long ms);
/* @stpool_wait(ex)
* Wait for the tasks' being done in @ms milliseconds. the functions
* of @stpool_waitex are just the same as @stpool_wait's. and as you see,
* @stpool_waitex use the callback @sttask_match to find the task. if there
* are tasks who matches the condition, @stpool_waitex will not return.
*
* Arguments:
* @hp [in] the pool handle
*
* @ptsk [in] If ptsk is not NULL, @stpool_wait will not return
* until all tasks whose address is equal to the ptsk
* have been done. or @stpool_wait will wait for all
* tasks's quiting.
*
* @sttask_match [in] a callback to match the task, if it return non zero
* value, @stpool_waitex will wait on the task that
* passed to it.
*
* @ms [in] -1 == INFINITE
*
* Return:
* On success, it returns 0.
* On timeout, 1 is returned,
* (If it is woke up by @stpool_wakeup , it returns -1)
*/
EXPORT int stpool_task_wait(HPOOL hp, struct sttask_t *ptsk, long ms);
EXPORT int stpool_task_waitex(HPOOL hp, int (*sttask_match)(struct stpool_tskstat_t *stat, void *arg), void *arg, long ms);
/* @stpool_task_wait2
* Wait for all tasks' being done in @ms milliseconds.
*/
#define stpool_task_wait2(hp, entry, n, ms) stpool_task_any_wait(hp, entry, n, NULL, ms)
/* @stpool_task_any_wait
* Wait for tasks' being done in @ms milliseconds.
*
* Arguments:
* @hp [in] the pool handle
*
* @entry [in] the tasks array entry, if @entry is NULL, the params @n
* and @npre, will be ignored. its function is the same as
* @stpool_task_wait(hp, NULL, ms) does.
*
* @n [in] the tasks item number of the @entry.
*
* @n_pre [in/out] If @npre is NULL, it tell the @stpool_task_any_wait that
* it should not return until the pool have done all of the tasks
* existing in the @entry.
* Or @stpool_task_any_wait will not return until the pool
* has done much more than *@npre tasks who is existing in the
* @entry, and after returning from @stpool_task_any_wait, *@npre
* will be filled up with the number of tasks who has been done
* by the pool currently.
*
*
* @ms [in] milliseconds to wait (-1 == INFINITE)
*
* Return:
* On success, it returns 0.
* On timeout, 1 is returned,
* (If it is woke up by @stpool_wakeup , it returns -1)
*/
EXPORT int stpool_task_any_wait(HPOOL hp, struct sttask_t *entry[], int n, int *npre, long ms);
/* @stpool_pending_leq_wait
* Watch the number of the pending task
*
* Arguments:
* @hp [in] the pool handle
*
* @n_max_pendings [in] If the number of pending task existing in the pool
* is no more than @n_max_pendings, @stpool_pending_leq_wait
* will return imediately.
*
* @ms [in] milliseconds to wait (-1 == INFINITE)
*
* Return:
* On success, it returns 0.
* On timeout, 1 is returned,
* (If it is woke up by @stpool_wakeup , it returns -1)
*/
EXPORT int stpool_pending_leq_wait(HPOOL hp, int n_max_pendings, long ms);
/* @stpool_wakeup
* Wake up the wait functions such as @stpool_throttle_wait,
* @stpool_task_wait, @stpool_task_wait2, @stpool_task_any_wait and
* so on.
*
* Arguments:
* @hp [in] the pool handle
*
* @wkid [in] the wkid returned by stpool_wkid(), stpool_wakeup(-1)
* will wake up all of the wait functions
* Return:
* None
*/
EXPORT void stpool_wakeup(HPOOL hp, long wkid);
#ifdef __cplusplus
}
#endif
#endif