job scheduler works with run once and run periodic schedules. Stop logic is not fully thought through.

Dependencies:   LinkedList

Dependents:   JobSchedulerDemo Borsch

Committer:
sgnezdov
Date:
Tue Jul 11 20:35:19 2017 +0000
Revision:
2:9bf5366ad5a2
Parent:
1:ec6a1d054065
Child:
3:f08f55827736
improved scheduler organization

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sgnezdov 0:806403f3d0d1 1 #include "scheduler.h"
sgnezdov 0:806403f3d0d1 2
sgnezdov 0:806403f3d0d1 3 void update(void *target) {
sgnezdov 0:806403f3d0d1 4 };
sgnezdov 0:806403f3d0d1 5
sgnezdov 0:806403f3d0d1 6 namespace JobScheduler {
sgnezdov 1:ec6a1d054065 7
sgnezdov 2:9bf5366ad5a2 8 bool descendingTimeline(Appointment *a1, Appointment *a2)
sgnezdov 2:9bf5366ad5a2 9 {
sgnezdov 2:9bf5366ad5a2 10 bool rv = a1->GetTime() <= a2->GetTime();
sgnezdov 2:9bf5366ad5a2 11 //printf("(%d %d:%d)", *d1, *d2, rv);
sgnezdov 2:9bf5366ad5a2 12 return rv;
sgnezdov 2:9bf5366ad5a2 13 };
sgnezdov 2:9bf5366ad5a2 14
sgnezdov 2:9bf5366ad5a2 15 /**
sgnezdov 2:9bf5366ad5a2 16 JobAddReq adds new job to the scheduler.
sgnezdov 2:9bf5366ad5a2 17 */
sgnezdov 1:ec6a1d054065 18 struct JobAddReq: Action {
sgnezdov 2:9bf5366ad5a2 19 Appointment *apt;
sgnezdov 1:ec6a1d054065 20 Response<JobID> response;
sgnezdov 2:9bf5366ad5a2 21 JobAddReq(Appointment *a) : Action(JobAddAT), apt(a), response(NoError, 0) {}
sgnezdov 1:ec6a1d054065 22 };
sgnezdov 0:806403f3d0d1 23
sgnezdov 0:806403f3d0d1 24 Scheduler::Scheduler(JobService *jobService)
sgnezdov 2:9bf5366ad5a2 25 : _jobService(jobService), _nextJobID(1) { }
sgnezdov 0:806403f3d0d1 26
sgnezdov 0:806403f3d0d1 27 void Scheduler::updateAdapter(void *thisPointer) {
sgnezdov 0:806403f3d0d1 28 Scheduler *self = static_cast<Scheduler*>(thisPointer);
sgnezdov 0:806403f3d0d1 29 self->updateHandler();
sgnezdov 0:806403f3d0d1 30 }
sgnezdov 0:806403f3d0d1 31
sgnezdov 0:806403f3d0d1 32 void Scheduler::Start() {
sgnezdov 0:806403f3d0d1 33 _updater.start(callback(Scheduler::updateAdapter, this));
sgnezdov 0:806403f3d0d1 34 }
sgnezdov 0:806403f3d0d1 35
sgnezdov 0:806403f3d0d1 36 void Scheduler::Stop() {
sgnezdov 0:806403f3d0d1 37 // it is not thread-safe, but impact is non-existent.
sgnezdov 0:806403f3d0d1 38 _quit = true;
sgnezdov 0:806403f3d0d1 39 }
sgnezdov 0:806403f3d0d1 40
sgnezdov 0:806403f3d0d1 41 void Scheduler::WaitToStop() {
sgnezdov 0:806403f3d0d1 42 _updater.join();
sgnezdov 0:806403f3d0d1 43 }
sgnezdov 0:806403f3d0d1 44
sgnezdov 2:9bf5366ad5a2 45 Response<JobID> Scheduler::JobAdd(JobTypeID jobTID, ISchedule *schedule, IJobData *data) {
sgnezdov 2:9bf5366ad5a2 46 Appointment *apt = new Appointment(jobTID, schedule, data, time_t(0));
sgnezdov 2:9bf5366ad5a2 47 if (NULL == apt) {
sgnezdov 2:9bf5366ad5a2 48 printf("[Scheduler::JobAdd] failed to allocate appointment\n");
sgnezdov 2:9bf5366ad5a2 49 return Response<JobID>(1, 0);
sgnezdov 2:9bf5366ad5a2 50 }
sgnezdov 2:9bf5366ad5a2 51 JobAddReq req(apt);
sgnezdov 1:ec6a1d054065 52 _actions.put(&req);
sgnezdov 0:806403f3d0d1 53 // default is wait forever
sgnezdov 1:ec6a1d054065 54 osEvent evt = req.resQueue.get();
sgnezdov 0:806403f3d0d1 55 if (evt.status == osEventMessage) {
sgnezdov 2:9bf5366ad5a2 56 if (evt.value.p != NULL) {
sgnezdov 2:9bf5366ad5a2 57 printf("[Scheduler::JobAdd] completed ok\n");
sgnezdov 2:9bf5366ad5a2 58 } else {
sgnezdov 2:9bf5366ad5a2 59 printf("[Scheduler::JobAdd] NOT added (C1)\n");
sgnezdov 2:9bf5366ad5a2 60 }
sgnezdov 2:9bf5366ad5a2 61 } else {
sgnezdov 2:9bf5366ad5a2 62 // not sure what condition is
sgnezdov 2:9bf5366ad5a2 63 printf("[Scheduler::JobAdd] NOT added (C2)\n");
sgnezdov 2:9bf5366ad5a2 64 delete apt;
sgnezdov 2:9bf5366ad5a2 65 apt = NULL;
sgnezdov 0:806403f3d0d1 66 }
sgnezdov 2:9bf5366ad5a2 67 // yes, return a copy of the structure
sgnezdov 1:ec6a1d054065 68 return req.response;
sgnezdov 0:806403f3d0d1 69 }
sgnezdov 0:806403f3d0d1 70
sgnezdov 2:9bf5366ad5a2 71 void Scheduler::JobRemove(JobID jobID) {
sgnezdov 0:806403f3d0d1 72 }
sgnezdov 0:806403f3d0d1 73
sgnezdov 0:806403f3d0d1 74 void Scheduler::updateHandler() {
sgnezdov 0:806403f3d0d1 75 while (!_quit) {
sgnezdov 0:806403f3d0d1 76 printf("[Scheduler::updateHandler] waiting for action\n");
sgnezdov 0:806403f3d0d1 77 // wait forever ...
sgnezdov 0:806403f3d0d1 78 osEvent evt = _actions.get();
sgnezdov 0:806403f3d0d1 79 if (evt.status == osEventMessage) {
sgnezdov 0:806403f3d0d1 80 printf("[Scheduler::updateHandler] process action\n");
sgnezdov 0:806403f3d0d1 81 this->process((Action*)evt.value.p);
sgnezdov 0:806403f3d0d1 82 } else {
sgnezdov 0:806403f3d0d1 83 printf("[Scheduler::updateHandler] NOT osEventMessage\n");
sgnezdov 0:806403f3d0d1 84 }
sgnezdov 0:806403f3d0d1 85 wait(2);
sgnezdov 0:806403f3d0d1 86 }
sgnezdov 0:806403f3d0d1 87 }
sgnezdov 0:806403f3d0d1 88
sgnezdov 0:806403f3d0d1 89 void Scheduler::process(Action *action)
sgnezdov 0:806403f3d0d1 90 {
sgnezdov 1:ec6a1d054065 91 switch(action->type) {
sgnezdov 1:ec6a1d054065 92 case JobAddAT: {
sgnezdov 1:ec6a1d054065 93 JobAddReq *req = static_cast<JobAddReq*>(action);
sgnezdov 2:9bf5366ad5a2 94 Job *job = req->apt->GetJob();
sgnezdov 2:9bf5366ad5a2 95 if (job->GetID() == 0) {
sgnezdov 2:9bf5366ad5a2 96 // assign job its ID
sgnezdov 2:9bf5366ad5a2 97 job->Init(_nextJobID++);
sgnezdov 2:9bf5366ad5a2 98 }
sgnezdov 2:9bf5366ad5a2 99 node<Appointment> *tmp = _timeline.insertOrdered(req->apt, descendingTimeline);
sgnezdov 2:9bf5366ad5a2 100 if (NULL == tmp) {
sgnezdov 2:9bf5366ad5a2 101 printf("[Scheduler::process] timeline insert failed\n");
sgnezdov 2:9bf5366ad5a2 102 action->resQueue.put(NULL);
sgnezdov 2:9bf5366ad5a2 103 return;
sgnezdov 2:9bf5366ad5a2 104 }
sgnezdov 2:9bf5366ad5a2 105 //printf("[Scheduler::process] simulate error\n");
sgnezdov 2:9bf5366ad5a2 106 //action->resQueue.put(NULL);
sgnezdov 1:ec6a1d054065 107 action->resQueue.put(&req->response);
sgnezdov 1:ec6a1d054065 108 break;
sgnezdov 1:ec6a1d054065 109 }
sgnezdov 1:ec6a1d054065 110 default:
sgnezdov 1:ec6a1d054065 111 printf("[Scheduler::process] unknown action type\n");
sgnezdov 1:ec6a1d054065 112 action->resQueue.put(NULL);
sgnezdov 1:ec6a1d054065 113 }
sgnezdov 0:806403f3d0d1 114 }
sgnezdov 0:806403f3d0d1 115
sgnezdov 0:806403f3d0d1 116 }