/** * RESCH APIs are called through write() system call. * See api.h for details. * Do not use timespec_to_jiffies(), since it rounds up the value. */ static ssize_t resch_write (struct file *file, const char *buf, size_t count, loff_t *offset) { int res = RES_SUCCESS; struct api_struct a; unsigned long us; /* copy data to kernel buffer. */ if (copy_from_user(&a, buf, count)) { printk(KERN_WARNING "RESCH: failed to copy data.\n"); return -EFAULT; } switch (a.api) { /* PORT I: preemptive periodic real-time scheduling.*/ case API_INIT: res = api_init(); break; case API_EXIT: res = api_exit(a.rid); break; case API_RUN: us = timespec_to_usecs(&a.arg.ts); res = api_run(a.rid, usecs_to_jiffies(us)); break; case API_WAIT_PERIOD: res = api_wait_for_period(a.rid); break; case API_WAIT_INTERVAL: us = timespec_to_usecs(&a.arg.ts); res = api_wait_for_interval(a.rid, usecs_to_jiffies(us)); break; case API_SET_PERIOD: us = timespec_to_usecs(&a.arg.ts); res = api_set_period(a.rid, usecs_to_jiffies(us)); break; case API_SET_DEADLINE: us = timespec_to_usecs(&a.arg.ts); res = api_set_deadline(a.rid, usecs_to_jiffies(us)); break; case API_SET_WCET: us = timespec_to_usecs(&a.arg.ts); res = api_set_wcet(a.rid, us); break; case API_SET_RUNTIME: us = timespec_to_usecs(&a.arg.ts); res = api_set_runtime(a.rid, us); break; case API_SET_PRIORITY: res = api_set_priority(a.rid, a.arg.val); break; case API_SET_SCHEDULER: res = api_set_scheduler(a.rid, a.arg.val); break; case API_BACKGROUND: res = api_background(a.rid); break; /* PORT II: event-driven asynchrous scheduling.*/ case API_SLEEP: us = timespec_to_usecs(&a.arg.ts); res = api_sleep(a.rid, usecs_to_jiffies(us)); break; case API_SUSPEND: res = api_suspend(a.rid); break; case API_WAKE_UP: res = api_wake_up(a.arg.val); break; /* PORT III: reservation-based scheduling.*/ case API_RESERVE_START: us = timespec_to_usecs(&a.arg.ts); res = api_reserve_start(a.rid, usecs_to_jiffies(us), false); break; case API_RESERVE_START_XCPU: us = timespec_to_usecs(&a.arg.ts); res = api_reserve_start(a.rid, usecs_to_jiffies(us), true); break; case API_RESERVE_STOP: res = api_reserve_stop(a.rid); break; case API_RESERVE_EXPIRE: res = api_reserve_expire(a.rid); break; case API_SERVER_RUN: res = api_server_run(a.rid); break; /* PORT IV.*/ /* PORT V: hierarchical scheduling.*/ case API_COMPONENT_CREATE: res = api_component_create(); break; case API_COMPONENT_DESTROY: res = api_component_destroy(a.arg.val); break; case API_COMPOSE: res = api_compose(a.rid, a.arg.val); break; case API_DECOMPOSE: res = api_decompose(a.rid); break; default: /* illegal api identifier. */ res = RES_ILLEGAL; printk(KERN_WARNING "RESCH: illegal API identifier.\n"); break; } return res; }
int handle_run(uint64_t con_id, struct message_request *request, char *pluginkey, struct api_error *error) { uint64_t callid; array *meta = NULL; string function_name; char *targetpluginkey; struct message_object args_object; if (!error || !request) return (-1); /* check params size */ if (request->params.size != 3) { error_set(error, API_ERROR_TYPE_VALIDATION, "Error dispatching run API request. Invalid params size"); return (-1); } if (request->params.obj[0].type == OBJECT_TYPE_ARRAY) meta = &request->params.obj[0].data.params; else { error_set(error, API_ERROR_TYPE_VALIDATION, "Error dispatching run API request. meta params has wrong type"); return (-1); } if (!meta) { error_set(error, API_ERROR_TYPE_VALIDATION, "Error dispatching run API request. meta params is NULL"); return (-1); } /* meta = [targetpluginkey, nil]*/ if (meta->size != 2) { error_set(error, API_ERROR_TYPE_VALIDATION, "Error dispatching run API request. Invalid meta params size"); return (-1); } /* extract meta information */ if (meta->obj[0].type != OBJECT_TYPE_STR) { error_set(error, API_ERROR_TYPE_VALIDATION, "Error dispatching run API request. meta elements have wrong type"); return (-1); } if (!meta->obj[0].data.string.str || meta->obj[0].data.string.length+1 != PLUGINKEY_STRING_SIZE) { error_set(error, API_ERROR_TYPE_VALIDATION, "Error dispatching run API request. Invalid meta params size"); return (-1); } targetpluginkey = meta->obj[0].data.string.str; to_upper(targetpluginkey); if (meta->obj[1].type != OBJECT_TYPE_NIL) { error_set(error, API_ERROR_TYPE_VALIDATION, "Error dispatching run API request. meta elements have wrong type"); return (-1); } if (request->params.obj[1].type != OBJECT_TYPE_STR) { error_set(error, API_ERROR_TYPE_VALIDATION, "Error dispatching run API request. function string has wrong type"); return (-1); } if (!request->params.obj[1].data.string.str) { error_set(error, API_ERROR_TYPE_VALIDATION, "Error dispatching register API request. Invalid meta params size"); return (-1); } function_name = request->params.obj[1].data.string; if (request->params.obj[2].type != OBJECT_TYPE_ARRAY) { error_set(error, API_ERROR_TYPE_VALIDATION, "Error dispatching run API request. function string has wrong type"); return (-1); } args_object = request->params.obj[2]; callid = (uint64_t) randommod(281474976710656LL); LOG_VERBOSE(VERBOSE_LEVEL_1, "generated callid %lu\n", callid); hashmap_put(uint64_t, ptr_t)(callids, callid, pluginkey); if (api_run(targetpluginkey, function_name, callid, args_object, con_id, request->msgid, error) == -1) { if (false == error->isset) error_set(error, API_ERROR_TYPE_VALIDATION, "Error executing run API request."); return (-1); } return (0); }