2 * Worldvisions Weaver Software:
3 * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
5 * A set of classes that provide co-operative multitasking support. By
6 * default there's no scheduler -- you have to provide it yourself. As it
7 * stands, this is just a convenient way to switch from one context to
8 * another when you know exactly what you want to do.
10 * This is mainly intended for use by WvStream, but that's probably not the
11 * only possible use... see also WvCont.
18 #include "wvwin32task.h"
23 #include "wvlinklist.h"
24 #include "wvstreamsdebugger.h"
25 #include "wvstringlist.h"
29 #define WVTASK_MAGIC 0x123678
33 /** Represents a single thread of control. */
36 friend class WvTaskMan
;
38 // you might think it would be useful to have this return an int, since
39 // yield() and run() both return int. But that ends up being more
40 // confusing than you think, because if you call task1->run(), and he
41 // calls task2->run(), and task2 calls yield(), then task1->run() returns
42 // the value *task2* passed to yield! So we avoid the confusion by not
43 // using return values here, which discourages people from thinking of
44 // them as return values.
45 typedef void TaskFunc(void *userdata
);
47 static int taskcount
, numtasks
, numrunning
;
48 int magic_number
, *stack_magic
;
54 bool running
, recycled
;
57 ucontext_t mystate
; // used for resuming the task
58 ucontext_t func_call
, func_return
;
63 WvTask(WvTaskMan
&_man
, size_t _stacksize
= 64*1024);
68 void start(WvStringParm _name
, TaskFunc
*_func
, void *_userdata
);
69 bool isrunning() const
72 int get_tid() const { return tid
; }
73 WvString
get_name() const { return name
; }
77 DeclareWvList(WvTask
);
79 /** Provides co-operative multitasking support among WvTask instances. */
84 static WvTaskMan
*singleton
;
87 static int magic_number
;
88 static WvTaskList all_tasks
, free_tasks
;
90 static void get_stack(WvTask
&task
, size_t size
);
91 static void stackmaster();
92 static void _stackmaster();
93 static void do_task();
94 static void call_func(WvTask
*task
);
96 static char *stacktop
;
97 static ucontext_t stackmaster_task
;
99 static WvTask
*stack_target
;
100 static ucontext_t get_stack_return
;
102 static WvTask
*current_task
;
103 static ucontext_t toplevel
;
106 virtual ~WvTaskMan();
108 #ifdef ENABLE_DELETE_DETECTOR
109 friend void operator &&<WvTaskMan
>(CheckIObject
, const WvTaskMan
*);
113 /// get/dereference the singleton global WvTaskMan
114 static WvTaskMan
*get();
115 static void unlink();
117 WvTask
*start(WvStringParm name
,
118 WvTask::TaskFunc
*func
, void *userdata
,
119 size_t stacksize
= 64*1024);
121 // run() and yield() return the 'val' passed to run() when this task
123 static int run(WvTask
&task
, int val
= 1);
124 static int yield(int val
= 1);
126 static WvTask
*whoami()
127 { return current_task
; }
129 static const void *current_top_of_stack();
130 static size_t current_stacksize_limit();
133 static WvString
debugger_tasks_run_cb(WvStringParm
, WvStringList
&,
134 WvStreamsDebugger::ResultCallback
, void *);
138 #endif // ifdef _WIN32