Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: ed8b35f23a7111dbf8a5a68aaa6d14fcde057348 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package org.eclipse.linuxtools.oprofile.core.opxml;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.eclipse.linuxtools.oprofile.core.opxml.info.InfoAdapter;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/** 
 * Caches the event data used by the CheckEventAdapter. The performance
 * improvement is targeted at the first time a call with the given arguments is
 * made. The first given call to check-event will take roughly O(n), and all
 * other calls whether they be new or recurring take O(1). Note that recurring
 * calls are handled by an entirely different cache. This particular class
 * simply parses the XML from ophelp -X and stores it.
 */
public class EventIdCache {
	
	private static final String HELP_EVENTS = "help_events"; //$NON-NLS-1$
	private static final String OPHELP = "ophelp"; //$NON-NLS-1$
	private static final String EVENT = "event"; //$NON-NLS-1$
	private static final String EVENT_NAME = "event_name"; //$NON-NLS-1$

	private Document eventDoc; // the document to hold the xml from ophelp
	private Element eventRoot; // the root corresponding to the xml from ophelp
	// name - the name of the event
	// Element - the DOM node
	private HashMap<String, Element> nameMap;
	private static EventIdCache single;
	
	public static EventIdCache getInstance(){
		if (single == null){
			single = new EventIdCache ();
		}
		return single;
	}
	
	/**
	 * @param id the id corresponding to an event
	 * @return the DOM Element corresponding to the event tag
	 */
	public Element getElementWithName (String name) {
		if (single.nameMap == null){
			readXML();
			buildCache();
		}
		return single.nameMap.get(name) != null ? (Element)single.nameMap.get(name) : null;
	}

	/**
	 * Build the cache
	 */
	private void buildCache() {
		single.nameMap = new HashMap<String, Element> ();
		NodeList eventList = single.eventRoot.getElementsByTagName(EVENT);
		for (int i = 0; i < eventList.getLength(); i++){
			Element elem = (Element) eventList.item(i);
			String eventName = elem.getAttribute(EVENT_NAME);
			single.nameMap.put(eventName, elem);
		}
	}

	/**
	 * Read the XML from ophelp
	 */
	private void readXML() {
		try {
			Process p = Runtime.getRuntime().exec(OPHELP + " " + "-X");
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder;
			try {
				builder = factory.newDocumentBuilder();
				try {
					single.eventDoc = builder.parse(p.getInputStream());
					Element elem = (Element) single.eventDoc.getElementsByTagName(HELP_EVENTS).item(0);
					single.eventRoot = elem;
				} catch (IOException e) {
				} catch (SAXException e) {
				}
			} catch (ParserConfigurationException e1) {
				e1.printStackTrace();
			}
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * @param name the name of the event
	 * @return the type of unit mask. This can be either mandatory, exclusive,
	 * bitmask, or null if none could be found.
	 */
	public String getUnitMaskType(String name) {
		String unitMaskType = null;
		File file = new File(InfoAdapter.CPUTYPE);

		try {
			BufferedReader bi = new BufferedReader(new FileReader(file));
			String cpuType = bi.readLine();
			File opArchEvents = new File(InfoAdapter.OP_SHARE + cpuType + "/" + InfoAdapter.EVENTS); //$NON-NLS-1$
			File opArchUnitMasks = new File(InfoAdapter.OP_SHARE + cpuType + "/" + InfoAdapter.UNIT_MASKS); //$NON-NLS-1$
			
			BufferedReader eventReader = new BufferedReader(new FileReader(opArchEvents));
			String line;
			while ((line = eventReader.readLine()) != null){
				// find the line with the event name
				if (line.contains("name:"+name+" ")){ //$NON-NLS-1$
					int start = line.indexOf("um:") + 3; //$NON-NLS-1$
					int end = line.indexOf(" ", start); //$NON-NLS-1$
					// grab the string that references the unit mask type
					String um = line.substring(start, end);
					BufferedReader unitMaskReader = new BufferedReader(new FileReader(opArchUnitMasks));
					while ((line = unitMaskReader.readLine()) != null){
						if (line.contains("name:"+um+" ")){ //$NON-NLS-1$
							start = line.indexOf("type:") + 5; //$NON-NLS-1$
							end = line.indexOf(" ", start); //$NON-NLS-1$
							unitMaskType = line.substring(start, end);
							return unitMaskType;
						}
					}
				}
			}
			eventReader.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return unitMaskType;
	}
}

Back to the top