00001 #include <stdlib.h>
00002 #include <stdio.h>
00003 #include <sys/msg.h>
00004 #include <string.h>
00005
00006 #include "hprocess.h"
00007 #include "hlog.h"
00008 #include "hsignal.h"
00009 #include "hsqueue.h"
00010 #include "hsqlist.h"
00011
00012
00013 struct hprocess {
00015 int pid;
00017 int state;
00019 int nice;
00021 int priority;
00023 char* bitfilename;
00025 char* statefilename;
00026 struct hprocess* next;
00027 struct hprocess* prev;
00028 struct hsqueue* parent_queue;
00029 };
00030
00031
00034 static int pid_counter = 0;
00035
00036
00037 static int set_pid_(struct hprocess* process, int pid);
00038 static int set_state_(struct hprocess* process, int state);
00039 static int increment_pid_counter_();
00040 static int set_next_(struct hprocess* process, struct hprocess* next);
00041 static int set_prev_(struct hprocess* process, struct hprocess* prev);
00042 static int set_parent_queue_(struct hprocess* process, struct hsqueue* queue);
00043 static int enqueue_process_callback_(struct hprocess* process, struct hprocess* last_process);
00044 static int remove_process_callback_(struct hprocess* process);
00045 static int get_pid_count_();
00046
00047
00048
00049
00050 static int enqueue_process_callback_(struct hprocess* process, struct hprocess* last_process)
00051 {
00052 set_next_(last_process, process);
00053 set_prev_(process, last_process);
00054 set_next_(process, NULL);
00055
00056 return 0;
00057 }
00058
00059
00060 static int remove_process_callback_(struct hprocess* process)
00061 {
00062 if (process == NULL)
00063 return -1;
00064
00065
00066 struct hprocess* prev = hprocess_get_prev(process);
00067 struct hprocess* next = hprocess_get_next(process);
00068 set_prev_(next, prev);
00069 set_next_(prev, next);
00070
00071 return 0;
00072 }
00073
00074
00075 static int set_pid_(struct hprocess* process, int pid)
00076 {
00077 if (process == NULL)
00078 return -1;
00079 else if (!hprocess_is_valid_pid(pid))
00080 return -1;
00081
00082 process->pid = pid;
00083
00084 return 0;
00085 }
00086
00087
00088 static int set_state_(struct hprocess* process, int state)
00089 {
00090 if (process == NULL)
00091 return -1;
00092
00093 process->state = state;
00094
00095 return 0;
00096 }
00097
00098
00099 static int increment_pid_counter_()
00100 {
00101 pid_counter += 1;
00102
00103 return pid_counter;
00104 }
00105
00106
00107 static int get_pid_count_()
00108 {
00109 return pid_counter;
00110 }
00111
00112
00113 static int set_next_(struct hprocess* process, struct hprocess* next)
00114 {
00115 if (process == NULL)
00116 return -1;
00117
00118 process->next = next;
00119
00120 return 0;
00121 }
00122
00123
00124 static int set_prev_(struct hprocess* process, struct hprocess* prev)
00125 {
00126 if (process == NULL)
00127 return -1;
00128
00129 process->prev = prev;
00130
00131 return 0;
00132 }
00133
00134
00135 static int set_parent_queue_(struct hprocess* process, struct hsqueue* queue)
00136 {
00137 if (process == NULL)
00138 return -1;
00139
00140 process->parent_queue = queue;
00141
00142 return 0;
00143 }
00144
00145
00146 const int hprocess_base_priority()
00147 {
00148 return 49;
00149 }
00150
00151
00152 const int hprocess_max_processes()
00153 {
00154
00155 return 50;
00156 }
00157
00158 const int hprocess_max_filename_size()
00159 {
00160 return HPROCESS_MAX_FILENAME_SIZE;
00161 }
00162
00163
00164 struct hprocess* hprocess_get(int pid)
00165 {
00166 if (pid < 0 || pid > get_pid_count_())
00167 return NULL;
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178 int list_i = 0;
00179 struct hsqueue* queue = NULL;
00180 struct hprocess* process = NULL;
00181
00182 for (list_i = 0; list_i < HPS_NUMBER; list_i++) {
00183 queue = hsqlist_get_first_queue(list_i);
00184
00185 while (queue != NULL) {
00186 process = hsqueue_get_first_process(queue);
00187
00188 while (process != NULL) {
00189 if (hprocess_get_pid(process) == pid)
00190 return process;
00191 process = hprocess_get_next(process);
00192 }
00193 queue = hsqueue_get_next(queue);
00194 }
00195 }
00196
00197 return NULL;
00198 }
00199
00200
00201 struct hprocess* hprocess_get_next(struct hprocess* process)
00202 {
00203 if (process == NULL)
00204 return NULL;
00205
00206 return process->next;
00207 }
00208
00209
00210 struct hprocess* hprocess_get_prev(struct hprocess* process)
00211 {
00212 if (process == NULL)
00213 return NULL;
00214
00215 return process->prev;
00216 }
00217
00218
00219 struct hsqueue* hprocess_get_parent_queue(struct hprocess* process)
00220 {
00221 if (process == NULL)
00222 return NULL;
00223
00224 return process->parent_queue;
00225 }
00226
00227
00228 int hprocess_set_bitfilename(struct hprocess* process, char* filename)
00229 {
00230 if (process == NULL)
00231 return -1;
00232 else if (strlen(filename) > hprocess_max_filename_size())
00233 return -1;
00234
00235
00236 if (process->bitfilename == NULL || strlen(process->bitfilename) < strlen(filename))
00237 process->bitfilename = realloc(process->bitfilename, strlen(filename) + 1);
00238
00239 strcpy(process->bitfilename, filename);
00240
00241 return 0;
00242 }
00243
00244
00245 char* hprocess_get_bitfilename(struct hprocess* process)
00246 {
00247 if (process == NULL)
00248 return NULL;
00249
00250 return process->bitfilename;
00251 }
00252
00253
00254 int hprocess_remove(struct hprocess* process)
00255 {
00256 if (process == NULL)
00257 return -1;
00258
00259
00260 int ret = hsqueue_remove_process(hprocess_get_parent_queue(process), process);
00261 free(process);
00262
00263 return ret;
00264 }
00265
00266
00267 int hprocess_get_nice(struct hprocess* process)
00268 {
00269 if (process == NULL)
00270 return -1;
00271
00272 return process->nice;
00273 }
00274
00275
00276 int hprocess_get_pid(struct hprocess* process)
00277 {
00278 if (process == NULL)
00279 return -1;
00280
00281 return process->pid;
00282 }
00283
00284
00285 int hprocess_is_valid_pid(int pid)
00286 {
00287 if (pid < 0 || pid > (hprocess_max_processes() - 1))
00288 return 0;
00289
00290 return 1;
00291 }
00292
00293
00294 struct hprocess* hprocess_create(int nice)
00295 {
00296 struct hprocess* process = calloc(1, sizeof(*process));
00297 set_next_(process, NULL);
00298 set_prev_(process, NULL);
00299 set_state_(process, HPS_NEW);
00300 set_parent_queue_(process, NULL);
00301 set_pid_(process, increment_pid_counter_());
00302 hprocess_set_nice(process, nice);
00303
00304 hsqueue_register_signal(HSIGNAL_ADD_PROCESS, enqueue_process_callback_);
00305 hsqueue_register_signal(HSIGNAL_REMOVE_PROCESS, remove_process_callback_);
00306
00307 return process;
00308 }
00309
00310
00311 int hprocess_set_priority(struct hprocess* process, int priority)
00312 {
00313 if (process == NULL)
00314 return -1;
00315
00316 if (priority > 0)
00317 process->priority = priority;
00318 else {
00319 hlog_write(HLOG_ERROR, "hprocess_set_priority: Can't set negative priority.\n");
00320 return -1;
00321 }
00322
00323 return priority;
00324 }
00325
00326 int hprocess_get_priority(struct hprocess* process)
00327 {
00328 if (process == NULL)
00329 return -1;
00330
00331 return process->priority;
00332 }
00333
00334 int hprocess_set_nice(struct hprocess* process, int nice)
00335 {
00336 if (process == NULL)
00337 return -1;
00338
00339 process->nice = nice;
00340 return 0;
00341 }
00342
00343
00344 int hprocess_get_state(struct hprocess* process)
00345 {
00346 if (process == NULL)
00347 return -1;
00348
00349 return process->state;
00350 }
00351
00352