#include #include #include #include "cbthread.h" #include "printqsim.h" typedef void (*func)(); void submit_job_slot_ready(Spq *s); void job_ready(Spq *s); typedef struct { cbthread_gsem user_sem; cbthread_gsem printer_sem; Job **buffer; int head; int tail; int njobs; func *user_funcs; Job **user_jobs; func *printer_funcs; } Info; void initialize_v(Spq *s) { Info *info; info = (Info *) malloc(sizeof(Info)); info->user_sem = cbthread_make_gsem(0); info->printer_sem = cbthread_make_gsem(0); info->buffer = (Job **) malloc(sizeof(Job *)*s->bufsize); info->user_funcs = (func *) malloc(sizeof(func)*s->nusers); info->printer_funcs = (func *) malloc(sizeof(func)*s->nprinters); info->user_jobs = (Job **) malloc(sizeof(Job *)*s->nusers); info->head = 0; info->tail = 0; info->njobs = 0; s->v = (void *) info; } void submit_job_cont(Spq *s) { Info *info; info = (Info *) s->v; if (info->njobs != s->bufsize) { info->buffer[info->tail] = info->user_jobs[s->id]; info->tail = (info->tail + 1) % s->bufsize; info->njobs++; if (cbthread_gsem_getval(info->printer_sem) < 0) cbthread_gsem_V(info->printer_sem); (*info->user_funcs[s->id])(s); cbthread_exit(); } else { cbthread_gsem_P(info->user_sem, submit_job_cont, s); } } void submit_job(Spq *s, Job *j, void (*function)()) { Info *info; info = (Info *) s->v; info->user_funcs[s->id] = function; info->user_jobs[s->id] = j; submit_job_cont(s); } void get_print_job_cont(Spq *s) { Info *info; info = (Info *) s->v; if (info->njobs == 0) { cbthread_gsem_P(info->printer_sem, get_print_job_cont, s); } else { s->job = info->buffer[info->head]; info->head = (info->head + 1) % s->bufsize; info->njobs--; if (cbthread_gsem_getval(info->user_sem) < 0) cbthread_gsem_V(info->user_sem); (*info->printer_funcs[s->id])(s); } } void get_print_job(Spq *s, void (*function)()) { Info *info; info = (Info *) s->v; info->printer_funcs[s->id] = function; get_print_job_cont(s); }