Files
2026-06-25 00:09:09 +08:00

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;
}