LCOV - code coverage report
Current view: top level - common - dfg_reader.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 230 367 62.7 %
Date: 2018-01-11 Functions: 35 51 68.6 %

          Line data    Source code
       1             : /*
       2             : START OF LICENSE STUB
       3             :     DeDOS: Declarative Dispersion-Oriented Software
       4             :     Copyright (C) 2017 University of Pennsylvania, Georgetown University
       5             : 
       6             :     This program is free software: you can redistribute it and/or modify
       7             :     it under the terms of the GNU General Public License as published by
       8             :     the Free Software Foundation, either version 3 of the License, or
       9             :     (at your option) any later version.
      10             : 
      11             :     This program is distributed in the hope that it will be useful,
      12             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :     GNU General Public License for more details.
      15             : 
      16             :     You should have received a copy of the GNU General Public License
      17             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : END OF LICENSE STUB
      19             : */
      20             : /**
      21             :  * @file dfg_reader.c
      22             :  *
      23             :  * Defines conversion of JSON strings to dedos_dfg
      24             :  */
      25             : 
      26             : #include "dfg_reader.h"
      27             : #include "dfg.h"
      28             : #include "jsmn_parser.h"
      29             : #include "jsmn.h"
      30             : #include "logging.h"
      31             : 
      32             : #include <strings.h>
      33             : #include <stdbool.h>
      34             : #include <string.h>
      35             : 
      36             : /** The objects types which can be located in the json DFG
      37             :  * See ::key_map for usage.
      38             :  * */
      39             : enum object_type {
      40             :     ROOT=0, RUNTIMES=1, ROUTES=2, DESTINATIONS=3, MSUS=4, PROFILING=5,
      41             :     META_ROUTING=6, SOURCE_TYPES=7, SCHEDULING=8, DEPENDENCIES=9, MSU_TYPES = 10
      42             : };
      43             : 
      44             : /**
      45             :  * Fixes the thread assignment within the DFG such that the
      46             :  * pinned and unpinned threads are accurate.
      47             :  * Must be run, because during execution the only hint of pinned/unpinned is
      48             :  * msu blocking mode.
      49             :  * To be run after DFG is fully parsed.
      50             :  * @return 0 on success, -1 on error
      51             :  */
      52           3 : static int fix_num_threads(struct dedos_dfg *dfg) {
      53           5 :     for (int i=0; i<dfg->n_runtimes; i++) {
      54           3 :         struct dfg_runtime *rt = dfg->runtimes[i];
      55             : 
      56           3 :         int n_pinned = rt->n_pinned_threads;
      57           3 :         int n_unpinned = rt->n_unpinned_threads;
      58           3 :         int total = n_pinned + n_unpinned;
      59          21 :         for (int t=0; t < total; t++) {
      60          18 :             struct dfg_thread *thread = rt->threads[t];
      61          18 :             if (thread->mode == PINNED_THREAD) {
      62           7 :                 n_pinned--;
      63          11 :             } else if (thread->mode == UNPINNED_THREAD) {
      64           5 :                 n_unpinned--;
      65             :             } else {
      66           6 :                 if (n_pinned > 0) {
      67           2 :                     thread->mode = PINNED_THREAD;
      68           2 :                     log(LOG_DFG_READER, "Setting thread %d with no MSUs to pinned", t);
      69           2 :                     n_pinned--;
      70           4 :                 } else if (n_unpinned > 0) {
      71           4 :                     thread->mode = UNPINNED_THREAD;
      72           4 :                     log(LOG_DFG_READER, "Setting thread %d with no MSUs to unpinned", t);
      73           4 :                     n_unpinned--;
      74             :                 } else {
      75           0 :                     log_error("Cannot determine pinned/unpinned status of threads "
      76             :                               "based on number of blocking/nonblock MSUs");
      77           0 :                     return -1;
      78             :                 }
      79             :             }
      80             :         }
      81           3 :         if (n_pinned < 0 || n_unpinned < 0) {
      82           1 :             log_error("More pinned/unpinned threads specified by MSUs than by DFG on rt %d: "
      83             :                       "%d more pinned, %d more unpinned", rt->id, -1 * n_pinned, -1 * n_unpinned);
      84           1 :             return -1;
      85             :         }
      86             :     }
      87           2 :     return 0;
      88             : }
      89             : 
      90             : /**
      91             :  * Provides the mapping between the keys in the JSON and the functions which are called
      92             :  * when those keys are encountered.
      93             :  */
      94             : static struct key_mapping key_map[];
      95             : 
      96           1 : struct dedos_dfg *parse_dfg_json_file(const char *filename){
      97             : 
      98           1 :     struct dedos_dfg *dfg = calloc(1, sizeof(*dfg));
      99             : 
     100           1 :     set_dfg(dfg);
     101             : 
     102           1 :     int rtn = parse_file_into_obj(filename, dfg, key_map);
     103             : 
     104           1 :     if (rtn >= 0){
     105           1 :         rtn = fix_num_threads(dfg);
     106           1 :         if (rtn < 0) {
     107           0 :             return NULL;
     108             :         }
     109           1 :         return dfg;
     110             :     } else {
     111           0 :         log_error("Failed to parse jsmn");
     112           0 :         return NULL;
     113             :     }
     114             : }
     115             : 
     116             : /** Key: "application_name", Object: ::ROOT */
     117           1 : PARSE_FN(set_app_name) {
     118           1 :     struct dedos_dfg *dfg = GET_PARSE_OBJ();
     119           1 :     char *name = GET_STR_TOK();
     120           1 :     if (strlen(name) > MAX_APP_NAME_LENGTH) {
     121           0 :         log_error("Application name '%s' is too long", name);
     122           0 :         return -1;
     123             :     }
     124           1 :     strcpy(dfg->application_name, name);
     125           1 :     return 0;
     126             : }
     127             : 
     128             : /** Key: "global_ctl_ip", Object: ::ROOT */
     129           1 : PARSE_FN(set_ctl_ip) {
     130           1 :     struct dedos_dfg *dfg = GET_PARSE_OBJ();
     131           1 :     char *ip = GET_STR_TOK();
     132             :     struct in_addr addr;
     133           1 :     int rtn = inet_pton(AF_INET, ip, &addr);
     134           1 :     if (rtn <= 0) {
     135           0 :         log_perror("Error converting '%s' to IP address", ip);
     136           0 :         return -1;
     137             :     }
     138           1 :     dfg->global_ctl_ip = addr.s_addr;
     139           1 :     return 0;
     140             : }
     141             : 
     142             : /** Key: "global_ctl_port", Object: ::ROOT */
     143           1 : PARSE_FN(set_ctl_port) {
     144           1 :     struct dedos_dfg *dfg = GET_PARSE_OBJ();
     145           1 :     dfg->global_ctl_port = GET_INT_TOK();
     146           1 :     return 0;
     147             : }
     148             : 
     149             : /** Key: "db_ip", Object: ::ROOT */
     150           0 : PARSE_FN(set_db_ip) {
     151           0 :     struct dedos_dfg *dfg = GET_PARSE_OBJ();
     152           0 :     char *ip = GET_STR_TOK();
     153             :     struct in_addr addr;
     154           0 :     int rtn = inet_pton(AF_INET, ip, &addr);
     155           0 :     if (rtn <= 0) {
     156           0 :         log_perror("Error converting '%s' to IP address", ip);
     157           0 :         return -1;
     158             :     }
     159           0 :     dfg->db.ip = addr.s_addr;
     160             : 
     161           0 :     return 0;
     162             : }
     163             : 
     164             : /** Key: "global_ctl_port", Object: ::ROOT */
     165           0 : PARSE_FN(set_db_port) {
     166           0 :     struct dedos_dfg *dfg = GET_PARSE_OBJ();
     167           0 :     dfg->db.port = GET_INT_TOK();
     168             : 
     169           0 :     return 0;
     170             : }
     171             : 
     172             : /** Key: "db_user", Object ::ROOT */
     173           0 : PARSE_FN(set_db_user) {
     174           0 :     struct dedos_dfg *dfg = GET_PARSE_OBJ();
     175           0 :     char *str_db_user = GET_STR_TOK();
     176           0 :     memcpy(dfg->db.user, str_db_user, strlen(str_db_user));
     177             : 
     178           0 :     return 0;
     179             : }
     180             : 
     181             : /** Key: "db_pwd", Object ::ROOT */
     182           0 : PARSE_FN(set_db_pwd) {
     183           0 :     struct dedos_dfg *dfg = GET_PARSE_OBJ();
     184           0 :     char *str_db_pwd = GET_STR_TOK();
     185           0 :     memcpy(dfg->db.pwd, str_db_pwd, strlen(str_db_pwd));
     186             : 
     187           0 :     return 0;
     188             : }
     189             : 
     190             : /** Key: "db_name", Object ::ROOT */
     191           0 : PARSE_FN(set_db_name) {
     192           0 :     struct dedos_dfg *dfg = GET_PARSE_OBJ();
     193           0 :     char *str_db_name = GET_STR_TOK();
     194           0 :     memcpy(dfg->db.name, str_db_name, strlen(str_db_name));
     195             : 
     196           0 :     return 0;
     197             : }
     198             : 
     199             : /** Key: element in "runtimes", Object ::ROOT */
     200           1 : INIT_OBJ_FN(init_runtime) {
     201           1 :     struct dedos_dfg *dfg = GET_PARSE_OBJ();
     202           1 :     int index = GET_OBJ_INDEX();
     203             : 
     204           1 :     dfg->n_runtimes++;
     205           1 :     dfg->runtimes[index] = calloc(1, sizeof(*dfg->runtimes[index]));
     206             : 
     207           1 :     RETURN_OBJ(dfg->runtimes[index], RUNTIMES);
     208             : }
     209             : 
     210             : /** Key: "runtimes", Object ::ROOT */
     211           1 : PARSE_OBJ_LIST_FN(set_runtimes, init_runtime);
     212             : 
     213             : /** Key: element in "MSUs", Object ::ROOT */
     214           3 : INIT_OBJ_FN(init_dfg_msu_from_json) {
     215           3 :     struct dedos_dfg *dfg = GET_PARSE_OBJ();
     216           3 :     int index = GET_OBJ_INDEX();
     217             : 
     218           3 :     dfg->n_msus++;
     219           3 :     dfg->msus[index] = calloc(1, sizeof(struct dfg_msu));
     220             : 
     221           3 :     RETURN_OBJ(dfg->msus[index], MSUS);
     222             : }
     223             : 
     224             : /** Key: "MSUs", Object ::ROOT */
     225           1 : PARSE_OBJ_LIST_FN(set_msus, init_dfg_msu_from_json);
     226             : 
     227             : /** Key: element in "MSU_types", Object ::ROOT */
     228           2 : INIT_OBJ_FN(init_dfg_msu_type) {
     229           2 :     struct dedos_dfg *dfg = GET_PARSE_OBJ();
     230             : 
     231           2 :     int index = GET_OBJ_INDEX();
     232             : 
     233           2 :     dfg->n_msu_types++;
     234           2 :     dfg->msu_types[index] = calloc(1, sizeof(**dfg->msu_types));
     235             : 
     236           2 :     RETURN_OBJ(dfg->msu_types[index], MSU_TYPES);
     237             : }
     238             : 
     239             : /** Key: "MSU_types", Object: ::ROOT */
     240           1 : PARSE_OBJ_LIST_FN(set_msu_types, init_dfg_msu_type);
     241             : 
     242             : /** Key: "id", Object: ::MSU_TYPES */
     243           2 : PARSE_FN(set_msu_type_id) {
     244           2 :     struct dfg_msu_type *type = GET_PARSE_OBJ();
     245           2 :     type->id = GET_INT_TOK();
     246           2 :     return 0;
     247             : }
     248             : 
     249             : /** Key: "name", Object: ::MSU_TYPES */
     250           2 : PARSE_FN(set_msu_type_name) {
     251           2 :     struct dfg_msu_type *type = GET_PARSE_OBJ();
     252           2 :     char *name = GET_STR_TOK();
     253             : 
     254           2 :     if (strlen(name) > MAX_MSU_NAME_LEN) {
     255           0 :         log_error("MSU name %s too long", name);
     256           0 :         return -1;
     257             :     }
     258           2 :     strcpy(type->name, name);
     259           2 :     return 0;
     260             : }
     261             : 
     262             : /** Key: "meta_routing", Object: ::MSU_TYPES */
     263           0 : PARSE_OBJ_FN(set_meta_routing, struct dfg_msu_type, meta_routing, META_ROUTING);
     264             : 
     265             : /** Key: Element in "dependencies", Object: ::MSU_TYPES */
     266           0 : INIT_OBJ_FN(init_dependencies) {
     267           0 :     struct dfg_msu_type *type = GET_PARSE_OBJ();
     268           0 :     int index = GET_OBJ_INDEX();
     269             : 
     270           0 :     type->n_dependencies++;
     271           0 :     type->dependencies[index] = calloc(1, sizeof(*type->dependencies[index]));
     272             : 
     273           0 :     RETURN_OBJ(type->dependencies[index], DEPENDENCIES);
     274             : }
     275             : 
     276             : /** Key: "dependencies", Object ::MSU_TYPES */
     277           0 : PARSE_OBJ_LIST_FN(set_dependencies, init_dependencies);
     278             : 
     279             : /** Key: "cloneable", Object ::MSU_TYPES */
     280           0 : PARSE_FN(set_cloneable) {
     281           0 :     struct dfg_msu_type *type = GET_PARSE_OBJ();
     282           0 :     type->cloneable = GET_INT_TOK();
     283           0 :     return 0;
     284             : }
     285             : 
     286             : /** Key: "colocation_group", object ::MSU_TYPES */
     287           0 : PARSE_FN(set_colocation_group) {
     288           0 :     struct dfg_msu_type *type = GET_PARSE_OBJ();
     289           0 :     type->colocation_group = GET_INT_TOK();
     290           0 :     return 0;
     291             : }
     292             : 
     293             : /** Key: "init_data", Object: ::MSUS */
     294           0 : PARSE_FN(set_msu_init_data) {
     295           0 :     struct dfg_msu *vertex = GET_PARSE_OBJ();
     296             : 
     297           0 :     char *init_data = GET_STR_TOK();
     298           0 :     if (strlen(init_data) > MAX_INIT_DATA_LEN) {
     299           0 :         log_error("Init data '%s' too long", init_data);
     300           0 :         return -1;
     301             :     }
     302           0 :     strcpy(vertex->init_data.init_data, init_data);
     303           0 :     return 0;
     304             : }
     305             : 
     306             : /** Key: "id", Object ::MSUS */
     307           3 : PARSE_FN(set_msu_id) {
     308           3 :     struct dfg_msu *msu = GET_PARSE_OBJ();
     309           3 :     msu->id = GET_INT_TOK();
     310           3 :     return 0;
     311             : }
     312             : 
     313             : /** Key: "vertex_type", Object ::MSUS */
     314           2 : PARSE_FN(set_msu_vertex_type) {
     315           2 :     struct dfg_msu *msu = GET_PARSE_OBJ();
     316           2 :     char *str_type = GET_STR_TOK();
     317           2 :     msu->vertex_type = str_to_vertex_type(str_type);
     318           2 :     return 0;
     319             : }
     320             : 
     321             : /** Key "type", Object ::MSUS */
     322           3 : PARSE_FN(set_msu_type) {
     323           3 :     struct dfg_msu *vertex = GET_PARSE_OBJ();
     324             : 
     325           3 :     struct dfg_msu_type *type = get_dfg_msu_type(GET_INT_TOK());
     326           3 :     if (type == NULL) {
     327             :         // Return once type has been instantiated
     328           0 :         return 1;
     329             :     }
     330           3 :     vertex->type = type;
     331             : 
     332           3 :     type->instances[type->n_instances] = vertex;
     333           3 :     type->n_instances++;
     334           3 :     return 0;
     335             : }
     336             : 
     337             : /** key: "blocking_mode", object: ::MSUS */
     338           6 : PARSE_FN(set_blocking_mode) {
     339           6 :     struct dfg_msu *vertex = GET_PARSE_OBJ();
     340             : 
     341           6 :     char *str_mode = GET_STR_TOK();
     342             : 
     343           6 :     vertex->blocking_mode = str_to_blocking_mode(str_mode);
     344           6 :     if (vertex->blocking_mode == UNKNOWN_BLOCKING_MODE) {
     345           0 :         log_error("Unknown blocking mode specified: %s", str_mode);
     346           0 :         return -1;
     347             :     }
     348             : 
     349           6 :     struct dfg_runtime *rt = vertex->scheduling.runtime;
     350           6 :     if (rt == NULL) {
     351           3 :         return 1;
     352             :     }
     353             : 
     354           3 :     struct dfg_thread *thread = vertex->scheduling.thread;
     355           3 :     if (thread == NULL) {
     356           0 :         log(LOG_DFG_READER, "Waiting for thread instantiation");
     357           0 :         return 1;
     358             :     }
     359             : 
     360           3 :     if (thread->mode == UNSPECIFIED_THREAD_MODE) {
     361           3 :         thread->mode = (vertex->blocking_mode == NONBLOCK_MSU) ? PINNED_THREAD : UNPINNED_THREAD;
     362             :     }
     363             : 
     364           3 :     if ((thread->mode == PINNED_THREAD) ^ (vertex->blocking_mode == NONBLOCK_MSU)) {
     365           0 :         log_error("Can only put blocking MSUs on pinned threads, and nonblock MSUs on unpinned");
     366           0 :         return -1;
     367             :     }
     368           3 :     return 0;
     369             : }
     370             : 
     371             : /** Key: "scheduling", Object ::MSUS */
     372           3 : PARSE_OBJ_FN(set_scheduling, struct dfg_msu, scheduling, SCHEDULING);
     373             : 
     374             : /** Key: id, Object ::RUNTIMES */
     375           1 : PARSE_FN(set_rt_id) {
     376           1 :     struct dfg_runtime *rt = GET_PARSE_OBJ();
     377           1 :     rt->id = GET_INT_TOK();
     378           1 :     return 0;
     379             : }
     380             : 
     381             : /** Key: ip, Object ::RUNTIMES */
     382           1 : PARSE_FN(set_rt_ip) {
     383           1 :     struct dfg_runtime *rt = GET_PARSE_OBJ();
     384           1 :     char *ip = GET_STR_TOK();
     385             :     struct in_addr addr;
     386           1 :     int rtn = inet_pton(AF_INET, ip, &addr);
     387           1 :     if (rtn <= 0) {
     388           0 :         log_perror("Error converting '%s' to IP address", ip);
     389           0 :         return -1;
     390             :     }
     391           1 :     rt->ip = addr.s_addr;
     392           1 :     return 0;
     393             : }
     394             : 
     395             : /** Key: port, object ::RUNTIMES */
     396           1 : PARSE_FN(set_rt_port) {
     397           1 :     struct dfg_runtime *rt = GET_PARSE_OBJ();
     398           1 :     rt->port = GET_INT_TOK();
     399           1 :     return 0;
     400             : }
     401             : 
     402             : /** Key: num_cores, object ::RUNTIMES */
     403           1 : PARSE_FN(set_rt_n_cores) {
     404           1 :     struct dfg_runtime *rt = GET_PARSE_OBJ();
     405           1 :     rt->n_cores = GET_INT_TOK();
     406           1 :     return 0;
     407             : }
     408             : 
     409             : /** Key: num_pinned_threads, object ::RUNTIMES */
     410           1 : PARSE_FN(set_num_pinned_threads) {
     411           1 :     struct dfg_runtime *rt = GET_PARSE_OBJ();
     412             : 
     413           1 :     int n_existing = rt->n_unpinned_threads;
     414           1 :     int n_new = GET_INT_TOK();
     415             : 
     416           3 :     for (int i=n_existing; i<n_existing+n_new; i++) {
     417           2 :         rt->threads[i] = calloc(1, sizeof(**rt->threads));
     418           2 :         rt->threads[i]->id = i+1;
     419             :     }
     420           1 :     rt->n_pinned_threads = n_new;
     421           1 :     return 0;
     422             : }
     423             : 
     424             : /** Key: num_unpinned_threads, object ::RUNTIMES */
     425           1 : PARSE_FN(set_num_unpinned_threads) {
     426           1 :     struct dfg_runtime *rt = GET_PARSE_OBJ();
     427             : 
     428           1 :     int n_existing = rt->n_pinned_threads;
     429           1 :     int n_new = GET_INT_TOK();
     430             : 
     431           2 :     for (int i=n_existing; i < n_existing + n_new; i++) {
     432           1 :         rt->threads[i] = calloc(1, sizeof(**rt->threads));
     433           1 :         rt->threads[i]->id = i+1;
     434             :     }
     435           1 :     rt->n_unpinned_threads = n_new;
     436           1 :     return 0;
     437             : }
     438             : 
     439             : /** Key: Element in "routes", object ::RUNTIMES */
     440           2 : INIT_OBJ_FN(init_route) {
     441           2 :     struct dfg_runtime *rt = GET_PARSE_OBJ();
     442           2 :     int index = GET_OBJ_INDEX();
     443           2 :     rt->n_routes++;
     444           2 :     rt->routes[index] = calloc(1, sizeof(**rt->routes));
     445           2 :     rt->routes[index]->runtime = rt;
     446             : 
     447           2 :     RETURN_OBJ(rt->routes[index], ROUTES);
     448             : }
     449             : 
     450             : /** Key: "routes", object ::RUNTIMES */
     451           1 : PARSE_OBJ_LIST_FN(set_rt_routes, init_route);
     452             : 
     453             : /** Key: "id", object ::ROUTES */
     454           2 : PARSE_FN(set_route_id) {
     455           2 :     struct dfg_route *route = GET_PARSE_OBJ();
     456           2 :     int id = GET_INT_TOK();
     457           2 :     struct dfg_route *existing = get_dfg_route(id);
     458           2 :     if (existing != NULL) {
     459           0 :         log_error("Route with ID %d exists twice in DFG", id);
     460           0 :         return -1;
     461             :     }
     462           2 :     route->id = id;
     463           2 :     log(LOG_DFG_PARSING, "Created route with id: %d", id);
     464           2 :     return 0;
     465             : }
     466             : 
     467             : /** Key: "type", object ::ROUTES */
     468           2 : PARSE_FN(set_route_type) {
     469           2 :     struct dfg_route *route = GET_PARSE_OBJ();
     470           2 :     int type_id = GET_INT_TOK();
     471           2 :     struct dfg_msu_type *type = get_dfg_msu_type(type_id);
     472           2 :     if (type == NULL) {
     473             :         // Return once type is instantiated
     474           0 :         return -1;
     475             :     }
     476           2 :     route->msu_type = type;
     477           2 :     return 0;
     478             : }
     479             : 
     480             : /** Key: Element in "endpoints", object ::ROUTES */
     481           2 : INIT_OBJ_FN(init_endpoint) {
     482           2 :     struct dfg_route *route = GET_PARSE_OBJ();
     483             : 
     484           2 :     int index = GET_OBJ_INDEX();
     485           2 :     route->n_endpoints++;
     486           2 :     route->endpoints[index] = calloc(1, sizeof(**route->endpoints));
     487             : 
     488           2 :     RETURN_OBJ(route->endpoints[index], DESTINATIONS);
     489             : }
     490             : 
     491             : /** Key: "endpoints", object ::ROUTES */
     492           2 : PARSE_OBJ_LIST_FN(set_route_endpoints, init_endpoint);
     493             : 
     494             : /** Key: "key", object ::DESTINATIONS */
     495           2 : PARSE_FN(set_dest_key) {
     496           2 :     struct dfg_route_endpoint *dest = GET_PARSE_OBJ();
     497           2 :     dest->key = GET_INT_TOK();
     498           2 :     return 0;
     499             : }
     500             : 
     501             : /** Key: "msu", object ::DESTINATIONS */
     502           4 : PARSE_FN(set_dest_msu) {
     503           4 :     struct dfg_route_endpoint *dest = GET_PARSE_OBJ();
     504           4 :     int msu_id = GET_INT_TOK();
     505             : 
     506           4 :     struct dfg_msu *msu = get_dfg_msu(msu_id);
     507           4 :     if (msu == NULL) {
     508             :         // Wait for MSU to be instantiated
     509           2 :         log(LOG_DFG_PARSING, "MSU %d is not yet instantiated", msu_id);
     510           2 :         return 1;
     511             :     }
     512           2 :     dest->msu = msu;
     513           2 :     return 0;
     514             : }
     515             : 
     516             : /** Key: "source_types", object ::META_ROUTING */
     517           0 : PARSE_FN(set_source_types) {
     518           0 :     struct dfg_meta_routing *meta = GET_PARSE_OBJ();
     519             :     int i;
     520           0 :     bool found_types = true;
     521           0 :     START_ITER_TOK_LIST(i) {
     522           0 :         int str_type = GET_INT_TOK();
     523           0 :         struct dfg_msu_type *type = get_dfg_msu_type(str_type);
     524           0 :         if (type == NULL) {
     525             :             // Wait for type to be instantiated
     526           0 :             log(LOG_DFG_PARSING, "Type %d is not yet instantiated", str_type);
     527           0 :             found_types = false;
     528             :         } else {
     529           0 :             meta->src_types[i] = type;
     530             :         }
     531           0 :     } END_ITER_TOK_LIST(i)
     532           0 :     meta->n_src_types = i;
     533           0 :     if (found_types == false)
     534           0 :         return 1;
     535           0 :     return 0;
     536             : }
     537             : 
     538             : /** Key: "dst_types", object ::META_ROUTING */
     539           0 : PARSE_FN(set_dst_types) {
     540           0 :     struct dfg_meta_routing *meta = GET_PARSE_OBJ();
     541           0 :     bool found_types = true;
     542             :     int i;
     543           0 :     START_ITER_TOK_LIST(i) {
     544           0 :         int str_type = GET_INT_TOK();
     545           0 :         struct dfg_msu_type *type = get_dfg_msu_type(str_type);
     546           0 :         if (type == NULL) {
     547           0 :             log(LOG_DFG_PARSING, "Type %d is not yet instantiated", str_type);
     548           0 :             found_types = false;
     549             :         } else {
     550           0 :             meta->dst_types[i] = type;
     551             :         }
     552           0 :     } END_ITER_TOK_LIST(i)
     553             : 
     554           0 :     meta->n_dst_types = i;
     555           0 :     if (found_types == false) {
     556           0 :         return 1;
     557             :     }
     558           0 :     return 0;
     559             : }
     560             : 
     561             : /** key: "type", object ::DEPENDENCIES */
     562           0 : PARSE_FN(set_dep_type) {
     563           0 :     struct dfg_dependency *dep = GET_PARSE_OBJ();
     564             : 
     565           0 :     int type_id = GET_INT_TOK();
     566           0 :     struct dfg_msu_type *type = get_dfg_msu_type(type_id);
     567             : 
     568           0 :     if (type == NULL) {
     569             :         // Return once type has been instantiated
     570           0 :         log(LOG_DFG_PARSING, "Type %d is not yet instantiated", type_id);
     571           0 :         return 1;
     572             :     }
     573           0 :     dep->type = type;
     574           0 :     return 0;
     575             : }
     576             : 
     577             : /** Key: "locality", object: ::DEPENDENCIES */
     578           0 : PARSE_FN(set_dep_locality) {
     579           0 :     struct dfg_dependency *dep = GET_PARSE_OBJ();
     580             : 
     581           0 :     char *str_loc = GET_STR_TOK();
     582           0 :     if (strcasecmp(str_loc, "local") == 0) {
     583           0 :         dep->locality = MSU_IS_LOCAL;
     584           0 :     } else if (strcasecmp(str_loc, "remote") == 0) {
     585           0 :         dep->locality = MSU_IS_REMOTE;
     586             :     } else {
     587           0 :         log_error("Unknown locality %s specified. Must be 'local' or 'remote'", str_loc);
     588             :     }
     589           0 :     return 0;
     590             : }
     591             : 
     592             : /** Key: "runtime", object: ::SCHEDULING */
     593           3 : PARSE_FN(set_msu_runtime) {
     594           3 :     struct dfg_scheduling *sched = GET_PARSE_OBJ();
     595             : 
     596           3 :     int id = GET_INT_TOK();
     597           3 :     struct dfg_runtime *rt = get_dfg_runtime(id);
     598           3 :     if (rt == NULL) {
     599           0 :         log(LOG_DFG_PARSING, "Runtime %d is not yet instantiated", id);
     600           0 :         return 1;
     601             :     }
     602           3 :     sched->runtime = rt;
     603           3 :     return 0;
     604             : }
     605             : 
     606             : /** Key: "thread_id", object: ::SCHEDULING */
     607           3 : PARSE_FN(set_msu_thread) {
     608           3 :     struct dfg_scheduling *sched = GET_PARSE_OBJ();
     609             : 
     610           3 :     if (sched->runtime == NULL) {
     611             :         // Runtime must be instantiated before thread
     612           0 :         log(LOG_DFG_PARSING, "MSU runtime not yet instantiated");
     613           0 :         return 1;
     614             :     }
     615           3 :     int id = GET_INT_TOK();
     616           3 :     struct dfg_thread *thread = get_dfg_thread(sched->runtime, id);
     617           3 :     if (thread == NULL) {
     618             :         // Thread must be instantiated too
     619           0 :         log(LOG_DFG_PARSING, "Thread %d not yet instantiated", id);
     620           0 :         return 1;
     621             :     }
     622           3 :     sched->thread = thread;
     623             : 
     624             :     // This is frustrating...
     625             :     // Have to iterate through all MSUs to find the one this scheduling object refers to
     626             :     // Should perhaps provide parse object as a linked list so you can traverse upwards?
     627           3 :     struct dedos_dfg *dfg = get_root_jsmn_obj();
     628           3 :     struct dfg_msu *msu = NULL;
     629           6 :     for (int i=0; i<dfg->n_msus; i++) {
     630           6 :         if (&dfg->msus[i]->scheduling == sched) {
     631           3 :             msu = dfg->msus[i];
     632           3 :             break;
     633             :         }
     634             :     }
     635             :     // Shouldn't happen, really...
     636           3 :     if (msu == NULL) {
     637           0 :         log(LOG_DFG_PARSING, "Msu for thead %d not yet instantiated", id);
     638           0 :         return 1;
     639             :     }
     640           3 :     thread->msus[thread->n_msus] = msu;
     641           3 :     thread->n_msus++;
     642             : 
     643           3 :     return 0;
     644             : }
     645             : 
     646             : /** key: "routes", object ::SCHEDULING */
     647           2 : PARSE_FN(set_msu_routes) {
     648           2 :     struct dfg_scheduling *sched = GET_PARSE_OBJ();
     649             : 
     650           2 :     bool set_routes = true;
     651             :     int i;
     652           2 :     log(LOG_DFG_PARSING, "MSU_ROUTE pre TOK: %s", GET_STR_TOK());
     653           4 :     START_ITER_TOK_LIST(i) {
     654           2 :         log(LOG_DFG_PARSING, "MSU_ROUTE TOK: %s", GET_STR_TOK());
     655           2 :         int route_id = GET_INT_TOK();
     656           2 :         struct dfg_route *route = get_dfg_route(route_id);
     657           2 :         if (route == NULL) {
     658           0 :             log(LOG_DFG_PARSING, "Route %d not yet instantiated for msu", route_id);
     659           0 :             set_routes = false;
     660             :         } else {
     661           2 :             sched->routes[i] = route;
     662             :         }
     663           2 :     } END_ITER_TOK_LIST(i)
     664             : 
     665           2 :     sched->n_routes = i;
     666           2 :     if (!set_routes) {
     667           0 :         return 1;
     668             :     }
     669           2 :     return 0;
     670             : }
     671             : 
     672             : /** To be used to raise an error when a JSON key is deprecated */
     673           0 : static int not_implemented(jsmntok_t **tok, char *j, struct json_state *in, struct json_state **saved) {
     674           0 :     log_warn("JSON key %s is not implemented in DFG reader", tok_to_str((*tok)-1, j));
     675           0 :     return 0;
     676             : }
     677             : 
     678             : /**
     679             :  * (See jsmn_parser.h for details of key_mapping structure)
     680             :  */
     681             : static struct key_mapping key_map[] = {
     682             :     { "application_name", ROOT, set_app_name },
     683             :     { "global_ctl_ip", ROOT, set_ctl_ip },
     684             :     { "global_ctl_port", ROOT, set_ctl_port },
     685             :     { "db_ip", ROOT, set_db_ip },
     686             :     { "db_port", ROOT, set_db_port },
     687             :     { "db_user", ROOT, set_db_user },
     688             :     { "db_pwd", ROOT, set_db_pwd },
     689             :     { "db_name", ROOT, set_db_name },
     690             : 
     691             :     { "MSU_types", ROOT, set_msu_types },
     692             :     { "MSUs", ROOT, set_msus },
     693             :     { "runtimes", ROOT, set_runtimes },
     694             : 
     695             :     { "id", MSU_TYPES, set_msu_type_id},
     696             :     { "name", MSU_TYPES, set_msu_type_name },
     697             :     { "meta_routing", MSU_TYPES, set_meta_routing },
     698             :     { "dependencies", MSU_TYPES, set_dependencies },
     699             :     { "cloneable", MSU_TYPES, set_cloneable },
     700             :     { "colocation_group", MSU_TYPES, set_colocation_group },
     701             : 
     702             :     { "id", MSUS, set_msu_id },
     703             :     { "vertex_type", MSUS, set_msu_vertex_type },
     704             :     { "init_data", MSUS, set_msu_init_data },
     705             :     { "type", MSUS, set_msu_type },
     706             :     { "blocking_mode", MSUS,  set_blocking_mode },
     707             :     { "scheduling", MSUS,  set_scheduling },
     708             : 
     709             :     { "id", RUNTIMES, set_rt_id },
     710             :     { "ip", RUNTIMES,  set_rt_ip },
     711             :     { "port", RUNTIMES, set_rt_port },
     712             :     { "num_cores", RUNTIMES, set_rt_n_cores },
     713             :     { "num_pinned_threads", RUNTIMES, set_num_pinned_threads },
     714             :     { "num_unpinned_threads", RUNTIMES, set_num_unpinned_threads },
     715             :     { "routes", RUNTIMES, set_rt_routes },
     716             : 
     717             :     { "id", ROUTES, set_route_id },
     718             :     { "type", ROUTES, set_route_type },
     719             :     { "endpoints", ROUTES, set_route_endpoints },
     720             : 
     721             :     { "key", DESTINATIONS, set_dest_key },
     722             :     { "msu", DESTINATIONS, set_dest_msu },
     723             : 
     724             :     { "source_types", META_ROUTING,  set_source_types },
     725             :     { "dst_types", META_ROUTING, set_dst_types },
     726             : 
     727             :     { "type", DEPENDENCIES, set_dep_type },
     728             :     { "locality", DEPENDENCIES, set_dep_locality },
     729             : 
     730             :     { "runtime", SCHEDULING, set_msu_runtime },
     731             :     { "thread_id", SCHEDULING, set_msu_thread },
     732             :     { "routes", SCHEDULING, set_msu_routes },
     733             : 
     734             :     { "load_mode", ROOT, not_implemented },
     735             :     { "application_deadline", ROOT, not_implemented },
     736             :     { "profiling", MSUS, not_implemented },
     737             :     { "statistics", MSUS, not_implemented },
     738             :     { "dram", RUNTIMES, not_implemented },
     739             :     { "io_network_bw", RUNTIMES, not_implemented},
     740             :     { "deadline", SCHEDULING,  not_implemented},
     741             :     { NULL, 0, NULL }
     742             : };
     743             : 

Generated by: LCOV version 1.10