1 | // This file is part of SmallBASIC |
---|---|
2 | // |
3 | // Task manager |
4 | // |
5 | // This program is distributed under the terms of the GPL v2.0 or later |
6 | // Download the GNU Public License (GPL) from www.gnu.org |
7 | // |
8 | // Copyright(C) 2000 Nicholas Christopoulos |
9 | |
10 | #include "common/smbas.h" |
11 | #include "common/tasks.h" |
12 | |
13 | static task_t *tasks; /**< tasks table @ingroup sys */ |
14 | static int task_count; /**< total number of tasks @ingroup sys */ |
15 | static int task_index; /**< current task number @ingroup sys */ |
16 | |
17 | /** |
18 | * @ingroup sys |
19 | * |
20 | * return the number of the tasks |
21 | * |
22 | * @return the number of the tasks |
23 | */ |
24 | int count_tasks() { |
25 | return task_count; |
26 | } |
27 | |
28 | /** |
29 | * @ingroup sys |
30 | * |
31 | * return the nth task-structure |
32 | * |
33 | * @return the nth task-structure |
34 | */ |
35 | task_t *taskinfo(int n) { |
36 | return &tasks[n]; |
37 | } |
38 | |
39 | /** |
40 | * @ingroup sys |
41 | * |
42 | * initialize tasks manager |
43 | */ |
44 | int init_tasks() { |
45 | tasks = NULL; |
46 | task_count = 0; |
47 | task_index = 0; |
48 | ctask = NULL; |
49 | int tid = create_task("main"); |
50 | activate_task(tid); |
51 | return tid; |
52 | } |
53 | |
54 | /** |
55 | * @ingroup sys |
56 | * |
57 | * destroys tasks and closes task manager |
58 | */ |
59 | void destroy_tasks() { |
60 | for (int i = 0; i < task_count; i++) { |
61 | close_task(i); |
62 | } |
63 | task_count = 0; |
64 | task_index = 0; |
65 | ctask = NULL; |
66 | free(tasks); |
67 | tasks = NULL; |
68 | } |
69 | |
70 | /** |
71 | * @ingroup sys |
72 | * |
73 | * create an empty new task |
74 | * |
75 | * @param name is the task name |
76 | * @return the task-id |
77 | */ |
78 | int create_task(const char *name) { |
79 | int tid = -1; |
80 | |
81 | if (task_count == 0) { |
82 | // this is the first task |
83 | tid = task_count; |
84 | task_count++; |
85 | tasks = (task_t *) malloc(sizeof(task_t) * task_count); |
86 | } else { |
87 | // search for an available free entry |
88 | for (int i = 0; i < task_count; i++) { |
89 | if (tasks[i].status == tsk_free) { |
90 | tid = i; |
91 | break; |
92 | } |
93 | } |
94 | |
95 | // create a new task |
96 | if (tid == -1) { |
97 | tid = task_count; |
98 | task_count++; |
99 | tasks = (task_t *) realloc(tasks, sizeof(task_t) * task_count); |
100 | } |
101 | } |
102 | |
103 | // init task |
104 | memset(&tasks[tid], 0, sizeof(task_t)); |
105 | strlcpy(tasks[tid].file, name, sizeof(tasks[0].file)); |
106 | tasks[tid].status = tsk_ready; |
107 | tasks[tid].parent = task_index; |
108 | tasks[tid].tid = tid; |
109 | |
110 | return tid; |
111 | } |
112 | |
113 | /** |
114 | * @ingroup sys |
115 | * |
116 | * closes a task and activate the next |
117 | */ |
118 | void close_task(int tid) { |
119 | tasks[tid].status = tsk_free; |
120 | if (task_index == tid) { |
121 | ctask = NULL; |
122 | } |
123 | // select next task |
124 | if (task_count) { |
125 | if (task_index == tid) { |
126 | if (task_count > task_index + 1) { |
127 | task_index++; |
128 | } else { |
129 | task_index = 0; |
130 | } |
131 | ctask = &tasks[task_index]; |
132 | } |
133 | } |
134 | } |
135 | |
136 | /** |
137 | * @ingroup sys |
138 | * |
139 | * set active task |
140 | * |
141 | * @param tid the task-id |
142 | * @return the previous task-id |
143 | */ |
144 | int activate_task(int tid) { |
145 | int prev_tid = task_index; |
146 | task_index = tid; |
147 | ctask = &tasks[tid]; |
148 | return prev_tid; |
149 | } |
150 | |
151 | /** |
152 | * @ingroup sys |
153 | * |
154 | * search for a task |
155 | * |
156 | * @param task_name the name of the task |
157 | * @return the task-id; or -1 on error |
158 | */ |
159 | int search_task(const char *task_name) { |
160 | for (int i = 0; i < task_count; i++) { |
161 | if (strcmp(tasks[i].file, task_name) == 0) { |
162 | return i; |
163 | } |
164 | } |
165 | return -1; |
166 | } |
167 |