155 lines
4.2 KiB
C++
155 lines
4.2 KiB
C++
#include "math.h"
|
|
#include "sched.h"
|
|
#include "pthread.h"
|
|
#include "stdlib.h"
|
|
#include "semaphore.h"
|
|
#include "stdio.h"
|
|
#include <unistd.h>
|
|
|
|
typedef struct {
|
|
char task_id;
|
|
int call_num;
|
|
int ci;
|
|
int ti;
|
|
int ci_left;
|
|
int ti_left;
|
|
int flag;
|
|
int arg;
|
|
pthread_t th;
|
|
} task;
|
|
|
|
void *proc(void *args);
|
|
void *idle(void *);
|
|
int select_proc(int alg);
|
|
|
|
int task_num = 0;
|
|
int idle_num = 0;
|
|
int alg;
|
|
int curr_proc = -1;
|
|
int demo_time = 100;
|
|
task *tasks;
|
|
pthread_mutex_t proc_wait[100];
|
|
pthread_mutex_t main_wait, idle_wait;
|
|
float sum = 0;
|
|
pthread_t idle_proc;
|
|
|
|
int main(int argc, char ** argv) {
|
|
pthread_mutex_init(&main_wait, NULL);
|
|
pthread_mutex_lock(&main_wait);
|
|
pthread_mutex_init(&idle_wait, NULL);
|
|
pthread_mutex_lock(&idle_wait);
|
|
printf("Please input number of real time tasks:\n");
|
|
scanf("%d", &task_num);
|
|
tasks = (task *)malloc(task_num * sizeof(task));
|
|
int i;
|
|
for (i = 0; i < task_num; i++) {
|
|
pthread_mutex_init(&proc_wait[i], NULL);
|
|
pthread_mutex_lock(&proc_wait[i]);
|
|
}
|
|
for (i = 0; i < task_num; i++) {
|
|
printf("Please input task id, followed by Ci and Ti:\n");
|
|
getchar();
|
|
scanf("%c,%d,%d,", &tasks[i].task_id, &tasks[i].ci, &tasks[i].ti);
|
|
tasks[i].ci_left = tasks[i].ci;
|
|
tasks[i].ti_left = tasks[i].ti;
|
|
tasks[i].flag = 2;
|
|
tasks[i].arg = i;
|
|
tasks[i].call_num = 1;
|
|
sum += (float)tasks[i].ci / (float)tasks[i].ti;
|
|
}
|
|
printf("Please input algorithm, 1 for EDF, 2 for RMS:");
|
|
getchar();
|
|
scanf("%d", &alg);
|
|
printf("Please input demo time:");
|
|
scanf("%d", &demo_time);
|
|
double r = 1;
|
|
if (alg == 2) {
|
|
r = (double)task_num * (exp(log(2) / (double)task_num) - 1);
|
|
printf("r is %lf\n", r);
|
|
}
|
|
if (sum > r) {
|
|
printf("(sum = %lf > r = %lf), not schedulable!\n", sum, r);
|
|
exit(2);
|
|
}
|
|
pthread_create(&idle_proc, NULL, idle, NULL);
|
|
for (i = 0; i < task_num; i++)
|
|
pthread_create(&tasks[i].th, NULL, proc, &tasks[i].arg);
|
|
for (i = 0; i < demo_time; i++) {
|
|
int j;
|
|
if ((curr_proc = select_proc(alg)) != -1) {
|
|
pthread_mutex_unlock(&proc_wait[curr_proc]);
|
|
pthread_mutex_lock(&main_wait);
|
|
} else {
|
|
pthread_mutex_unlock(&idle_wait);
|
|
pthread_mutex_lock(&main_wait);
|
|
}
|
|
for (j = 0; j < task_num; j++) {
|
|
if (--tasks[j].ti_left == 0) {
|
|
tasks[j].ti_left = tasks[j].ti;
|
|
tasks[j].ci_left = tasks[j].ci;
|
|
pthread_create(&tasks[j].th, NULL, proc, &tasks[j].arg);
|
|
tasks[j].flag = 2;
|
|
}
|
|
}
|
|
printf("\n");
|
|
sleep(1);
|
|
}
|
|
}
|
|
|
|
void *proc(void *args) {
|
|
int *iargs = (int *)args;
|
|
while (tasks[*iargs].ci_left > 0) {
|
|
pthread_mutex_lock(&proc_wait[*iargs]);
|
|
if (idle_num != 0) {
|
|
printf("idle(%d)", idle_num);
|
|
idle_num = 0;
|
|
}
|
|
printf("%c%d", tasks[*iargs].task_id, tasks[*iargs].call_num);
|
|
tasks[*iargs].ci_left--;
|
|
if (tasks[*iargs].ci_left == 0) {
|
|
printf("(%d)", tasks[*iargs].ci);
|
|
tasks[*iargs].flag = 0;
|
|
tasks[*iargs].call_num++;
|
|
}
|
|
pthread_mutex_unlock(&main_wait);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void *idle(void *arg) {
|
|
while (1) {
|
|
pthread_mutex_lock(&idle_wait);
|
|
printf("->");
|
|
idle_num++;
|
|
pthread_mutex_unlock(&main_wait);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int select_proc(int alg) {
|
|
int j;
|
|
int templ, temp2;
|
|
templ = 10000;
|
|
temp2 = -1;
|
|
if ((alg == 2) && (curr_proc != -1) && (tasks[curr_proc].flag != 0))
|
|
return curr_proc;
|
|
for (j = 0; j < task_num; j++) {
|
|
if (tasks[j].flag == 2) {
|
|
switch (alg) {
|
|
case 1:
|
|
if (templ > tasks[j].ti_left) {
|
|
templ = tasks[j].ti_left;
|
|
temp2 = j;
|
|
}
|
|
break;
|
|
case 2:
|
|
if (templ > tasks[j].ti) {
|
|
templ = tasks[j].ti;
|
|
temp2 = j;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return temp2;
|
|
} |