aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Otterness <otternes@cs.unc.edu>2016-05-04 15:19:33 -0400
committerNathan Otterness <otternes@cs.unc.edu>2016-05-04 15:19:33 -0400
commit9bfd0b21b94a8032e13c2337a67aa2b6b2c57f4b (patch)
treea99f1d56cf571213c7c7d1ce9a58b6eb11f43758
parentecf4342e34e0b1b90229b5c452e8fe7f3483a344 (diff)
Add more argument parsingwip_wait_free
-rw-r--r--include/pgm.h17
-rw-r--r--sample_arg.txt26
-rw-r--r--tools/pgmrt.cpp93
3 files changed, 126 insertions, 10 deletions
diff --git a/include/pgm.h b/include/pgm.h
index cafb18c..dd72bf6 100644
--- a/include/pgm.h
+++ b/include/pgm.h
@@ -90,8 +90,17 @@ typedef struct pgm_edge_attr
90 size_t nr_consume; /* #tokens consumed per invocation */ 90 size_t nr_consume; /* #tokens consumed per invocation */
91 size_t nr_threshold; /* #tokens required before consume allowed */ 91 size_t nr_threshold; /* #tokens required before consume allowed */
92 92
93 // This will be 1 for producer-consumer buffer, 2 for wait-free buffer and
94 // 0 for an unknown type.
95 int ipc_type_to_use;
96
93 pgm_edge_type_t type; /* type indicating underlying IPC of the edge */ 97 pgm_edge_type_t type; /* type indicating underlying IPC of the edge */
94 98
99 /* for logical page support. Refer RTSS16 paper */
100 unsigned int color;
101 unsigned int bank;
102 unsigned long offset;
103
95 /* edge-type specific params */ 104 /* edge-type specific params */
96 union 105 union
97 { 106 {
@@ -112,10 +121,6 @@ typedef struct pgm_edge_attr
112 { 121 {
113 /* The maximum number of bytes in a wait-free buffer. */ 122 /* The maximum number of bytes in a wait-free buffer. */
114 size_t buffer_bytes; 123 size_t buffer_bytes;
115 /* for logical page support. Refer RTSS16 paper */
116 unsigned int color;
117 unsigned int bank;
118 unsigned long offset;
119 }; 124 };
120 struct /* POSIX message queue params */ 125 struct /* POSIX message queue params */
121 { 126 {
@@ -139,7 +144,11 @@ static const edge_attr_t default_edge = {
139 .nr_produce = 1, 144 .nr_produce = 1,
140 .nr_consume = 1, 145 .nr_consume = 1,
141 .nr_threshold = 1, 146 .nr_threshold = 1,
147 .ipc_type_to_use = 0,
142 .type = pgm_cv_edge, 148 .type = pgm_cv_edge,
149 .color = 0,
150 .bank = 0,
151 .offset = 0,
143}; 152};
144 153
145/* 154/*
diff --git a/sample_arg.txt b/sample_arg.txt
index 7e118fe..507170b 100644
--- a/sample_arg.txt
+++ b/sample_arg.txt
@@ -1 +1,25 @@
1./pgmrt --wait --cluster node0:0,node1:3,node2:-1,node4:-1 --graph node0:node1,node0:node2,node1:node4 --rates node0:1:100 --execution node0:10,node1:15,node2:20,node4:10 --budget node0:99,node1:99,node2:99,node4:99 --criticality node0:0,node1:1,node2:2,node4:2 --buffer node0:node1:512,node0:node2:256,node1:node4:32 --wsCycle 3 --etoe 100 --duration 3 & 1# The original invocation
2
3./pgmrt --wait --cluster node0:0,node1:3,node2:-1,node4:-1 \
4 --graph node0:node1,node0:node2,node1:node4 \
5 --rates node0:1:100 \
6 --execution node0:10,node1:15,node2:20,node4:10 \
7 --budget node0:99,node1:99,node2:99,node4:99 \
8 --criticality node0:0,node1:1,node2:2,node4:2 \
9 --buffer node0:node1:512,node0:node2:256,node1:node4:32 \
10 --wsCycle 3 \
11 --etoe 100 \
12 --duration 3 &
13
14# Indicates node0:node1 edge should use a wait free buffer and node0:node2 to use a producer-consumer buffer.
15
16./pgmrt --wait --cluster node0:0,node1:3,node2:-1,node4:-1 \
17 --graph node0:node1,node0:node2,node1:node4@node0:node1,wf,0000ffff,000000fc,00000000@node0:node2,pc,0000ffff,000000fc,00000400 \
18 --rates node0:1:100 \
19 --execution node0:10,node1:15,node2:20,node4:10 \
20 --budget node0:99,node1:99,node2:99,node4:99 \
21 --criticality node0:0,node1:1,node2:2,node4:2 \
22 --buffer node0:node1:512,node0:node2:256,node1:node4:32 \
23 --wsCycle 3 \
24 --etoe 100 \
25 --duration 3 &
diff --git a/tools/pgmrt.cpp b/tools/pgmrt.cpp
index 25ad7d5..8ec9bee 100644
--- a/tools/pgmrt.cpp
+++ b/tools/pgmrt.cpp
@@ -4,6 +4,7 @@
4/* A program for running a complex PGM application. */ 4/* A program for running a complex PGM application. */
5 5
6#include <iostream> 6#include <iostream>
7#include <sstream>
7#include <thread> 8#include <thread>
8#include <exception> 9#include <exception>
9#include <stdexcept> 10#include <stdexcept>
@@ -13,6 +14,8 @@
13#include <cstdint> 14#include <cstdint>
14 15
15#include <errno.h> 16#include <errno.h>
17#include <stdio.h>
18#include <stdlib.h>
16#include <string.h> 19#include <string.h>
17 20
18// TODO: Use std::chrono routines instead. 21// TODO: Use std::chrono routines instead.
@@ -567,8 +570,58 @@ std::string make_edge_name(const std::string& a, const std::string& b)
567 return name; 570 return name;
568} 571}
569 572
573typedef struct {
574 std::string EdgeName;
575 // This is 0 if unknown, 1 if wait free, or 2 if producer consumer
576 uint8_t ProducerConsumerOrWaitFree;
577 uint32_t Color;
578 uint32_t Bank;
579 uint32_t Offset;
580} GraphEdgeAttributes;
581
582uint32_t HexToUint32(std::string hex) {
583 std::stringstream ss;
584 uint32_t toReturn;
585 ss << std::hex << hex;
586 ss >> toReturn;
587 return toReturn;
588}
589
590// Graph node attribute format:
591// ./pgmrt <...> --graph node0:node1,node0:node2@node0:node1,wf,0000ffff,000000fc,00000000@node1:...
592//
593// Basically, append an '@' to the end of the --graph argument string, followed
594// by a list of <edge name>:type,color,bank,offset. Attributes for more edges
595// can be appended using additional '@' symbols. Color, bank and offset are all
596// in hex.
597std::vector<GraphEdgeAttributes> ParseGraphEdgeAttributes(std::vector<std::string> desc) {
598 std::vector<std::string> attrs;
599 std::vector<GraphEdgeAttributes> toReturn;
600 for (int i = 0; i < desc.size(); i++) {
601 boost::split(attrs, desc[i], boost::is_any_of(","));
602 if (attrs.size() != 5) {
603 printf("Error: Edge attributes must be of the format %s\n",
604 "<edge name>,<edge type (wf or pc)>,<color>,<bank>,<offset>");
605 exit(1);
606 }
607 GraphEdgeAttributes thisEdge;
608 thisEdge.EdgeName = attrs[0];
609 thisEdge.ProducerConsumerOrWaitFree = 0;
610 if (attrs[1] == "wf") {
611 thisEdge.ProducerConsumerOrWaitFree = 1;
612 } else if (attrs[1] == "pc") {
613 thisEdge.ProducerConsumerOrWaitFree = 2;
614 }
615 thisEdge.Color = HexToUint32(attrs[2]);
616 thisEdge.Bank = HexToUint32(attrs[3]);
617 thisEdge.Offset = HexToUint32(attrs[4]);
618 toReturn.push_back(thisEdge);
619 }
620 return toReturn;
621}
622
570void parse_graph_description( 623void parse_graph_description(
571 const std::string& desc, 624 const std::string& desc_original,
572 const graph_t& g, 625 const graph_t& g,
573 std::vector<node_t>& nodes, 626 std::vector<node_t>& nodes,
574 std::vector<edge_t>& edges) 627 std::vector<edge_t>& edges)
@@ -577,10 +630,14 @@ void parse_graph_description(
577 // the edges. 630 // the edges.
578 // function does not need to be fast! 631 // function does not need to be fast!
579 632
633 std::vector<std::string> nodeNameChunksAndAttributes;
580 // strip token information 634 // strip token information
581 std::vector<std::string> nodeNameChunks; 635 std::vector<std::string> nodeNameChunks;
582 std::set<std::string> nodeNames; // set to ensure uniqueness 636 std::set<std::string> nodeNames; // set to ensure uniqueness
637 boost::split(nodeNameChunksAndAttributes, desc_original, boost::is_any_of("@"));
638 std::string desc = nodeNameChunksAndAttributes[0];
583 boost::split(nodeNameChunks, desc, boost::is_any_of(",") || boost::is_any_of(":")); 639 boost::split(nodeNameChunks, desc, boost::is_any_of(",") || boost::is_any_of(":"));
640
584 for(auto nStr(nodeNameChunks.begin()); nStr != nodeNameChunks.end(); ++nStr) { 641 for(auto nStr(nodeNameChunks.begin()); nStr != nodeNameChunks.end(); ++nStr) {
585 std::vector<std::string> tokenDesc; 642 std::vector<std::string> tokenDesc;
586 boost::split(tokenDesc, *nStr, boost::is_any_of(".")); 643 boost::split(tokenDesc, *nStr, boost::is_any_of("."));
@@ -591,7 +648,17 @@ void parse_graph_description(
591 for(auto nStr(nodeNames.begin()); nStr != nodeNames.end(); ++nStr) { 648 for(auto nStr(nodeNames.begin()); nStr != nodeNames.end(); ++nStr) {
592 printf("Node = %s\n", nStr->c_str()); 649 printf("Node = %s\n", nStr->c_str());
593 } 650 }
594 651
652 // Delete the original edge definitions in the attributes list...
653 nodeNameChunksAndAttributes[0] = nodeNameChunksAndAttributes[nodeNameChunksAndAttributes.size() - 1];
654 nodeNameChunksAndAttributes.pop_back();
655 std::vector<GraphEdgeAttributes> edgeAttrs = ParseGraphEdgeAttributes(nodeNameChunksAndAttributes);
656 for (int i = 0; i < edgeAttrs.size(); i++) {
657 printf("Edge %s: Type %d, color 0x%08x, bank 0x%08x, offset 0x%08x\n",
658 edgeAttrs[i].EdgeName.c_str(), (int) edgeAttrs[i].ProducerConsumerOrWaitFree,
659 edgeAttrs[i].Color, edgeAttrs[i].Bank, edgeAttrs[i].Offset);
660 }
661
595 // process each uniquely named node 662 // process each uniquely named node
596 std::map<std::string, node_t> nodeMap; 663 std::map<std::string, node_t> nodeMap;
597 for(auto nStr(nodeNames.begin()); nStr != nodeNames.end(); ++nStr) { 664 for(auto nStr(nodeNames.begin()); nStr != nodeNames.end(); ++nStr) {
@@ -604,7 +671,9 @@ void parse_graph_description(
604 // create all the edges. 671 // create all the edges.
605 std::vector<std::string> edgeDesc; 672 std::vector<std::string> edgeDesc;
606 boost::split(edgeDesc, desc, boost::is_any_of(",")); 673 boost::split(edgeDesc, desc, boost::is_any_of(","));
674 GraphEdgeAttributes *thisEdgeAttributes;
607 for(auto eStr(edgeDesc.begin()); eStr != edgeDesc.end(); ++eStr) { 675 for(auto eStr(edgeDesc.begin()); eStr != edgeDesc.end(); ++eStr) {
676 thisEdgeAttributes = NULL;
608 std::vector<std::string> nodePair; 677 std::vector<std::string> nodePair;
609 boost::split(nodePair, *eStr, boost::is_any_of(":")); 678 boost::split(nodePair, *eStr, boost::is_any_of(":"));
610 if(nodePair.size() > 2) { 679 if(nodePair.size() > 2) {
@@ -614,7 +683,7 @@ void parse_graph_description(
614 // assume single-node graph 683 // assume single-node graph
615 continue; 684 continue;
616 } 685 }
617 686 std::string edgeName = "";
618 int nr_produce = 1; 687 int nr_produce = 1;
619 int nr_consume = 1; 688 int nr_consume = 1;
620 int nr_threshold = 1; 689 int nr_threshold = 1;
@@ -627,6 +696,7 @@ void parse_graph_description(
627 nr_produce = boost::lexical_cast<int>(tokenDesc[1]); 696 nr_produce = boost::lexical_cast<int>(tokenDesc[1]);
628 nodePair[0] = tokenDesc[0]; 697 nodePair[0] = tokenDesc[0];
629 } 698 }
699 edgeName = tokenDesc[0] + ":";
630 tokenDesc.clear(); 700 tokenDesc.clear();
631 boost::split(tokenDesc, nodePair[1], boost::is_any_of(".")); 701 boost::split(tokenDesc, nodePair[1], boost::is_any_of("."));
632 if(tokenDesc.size() > 1) { 702 if(tokenDesc.size() > 1) {
@@ -639,8 +709,14 @@ void parse_graph_description(
639 } 709 }
640 nodePair[1] = tokenDesc[0]; 710 nodePair[1] = tokenDesc[0];
641 } 711 }
642 712 edgeName += tokenDesc[0];
643 713 thisEdgeAttributes = NULL;
714 for (int j = 0; j < edgeAttrs.size(); j++) {
715 if (edgeAttrs[j].EdgeName == edgeName) {
716 thisEdgeAttributes = &(edgeAttrs[j]);
717 break;
718 }
719 }
644 edge_t e; 720 edge_t e;
645 edge_attr_t cv_attr; 721 edge_attr_t cv_attr;
646 memset(&cv_attr, 0, sizeof(cv_attr)); 722 memset(&cv_attr, 0, sizeof(cv_attr));
@@ -648,6 +724,13 @@ void parse_graph_description(
648 cv_attr.nr_produce = nr_produce; 724 cv_attr.nr_produce = nr_produce;
649 cv_attr.nr_consume = nr_consume; 725 cv_attr.nr_consume = nr_consume;
650 cv_attr.nr_threshold = nr_threshold; 726 cv_attr.nr_threshold = nr_threshold;
727 if (thisEdgeAttributes) {
728 printf("Applying additional attributes for edge %s\n", edgeName.c_str());
729 cv_attr.color = thisEdgeAttributes->Color;
730 cv_attr.bank = thisEdgeAttributes->Bank;
731 cv_attr.offset = thisEdgeAttributes->Offset;
732 cv_attr.ipc_type_to_use = thisEdgeAttributes->ProducerConsumerOrWaitFree;
733 }
651 CheckError(pgm_init_edge(&e, nodeMap[nodePair[0]], nodeMap[nodePair[1]], 734 CheckError(pgm_init_edge(&e, nodeMap[nodePair[0]], nodeMap[nodePair[1]],
652 make_edge_name(nodePair[0], nodePair[1]).c_str(), &cv_attr)); 735 make_edge_name(nodePair[0], nodePair[1]).c_str(), &cv_attr));
653 edges.push_back(e); 736 edges.push_back(e);