Commit 9fbd01eb authored by Rita Sousa's avatar Rita Sousa

Updated support to NVIDIA Jetson AGX Xavier

parent 81cd4ccc
......@@ -19,5 +19,12 @@ Assuming that the dataClay model has already been started and registered, the st
./run_nfrtool.sh
```
The master branch has the code to run on NVIDIA Jetson AGX Xavier.
If you need to run NFRTool on an Intel machine, before running the demo (previous snippet), switch to the "machine_x86" branch:
```
git checkout machine_x86
```
# Acknowledgements
This work has been supported by the EU H2020 project ELASTIC, contract #825473.
No preview for this file type
......@@ -189,6 +189,11 @@ int main(int argc, char **argv)
pthread_t *t;
t = calloc(sizePIDlist, sizeof(pthread_t));
char *update = "UPDATED\n";
int n = write(sock_cli, update, strlen(update));
if (n < 0)
perror("ERROR! Writing to server!!!\n");
for (int i = 0; i < sizePIDlist; i++)
{
printf("Thread %d com pid %d e ppid %d esta por ativar 2=%d\n", arr_pid[i].array_position, arr_pid[i].pid, arr_pid[i].ppid, arr_pid[i].active);
......@@ -217,6 +222,11 @@ int main(int argc, char **argv)
char *token = strtok(buffer, ",");
size = atoi(token);
compareActualReceivedPIDList(token, size);
char *update = "UPDATED\n";
int n = write(sock_cli, update, strlen(update));
if (n < 0)
perror("ERROR! Writing to server!!!\n");
//printf("Finished my compare job!!\n");
memset(&buffer, 0, sizeof buffer);
}
......
......@@ -21,14 +21,14 @@ public class ActivationWorkersManager implements Runnable {
private ResourceManager rm;
private ActiveWorkersMap activeWorkers;
private final int PERIOD = 10000;
// FIXME: Half of CPU_THRESHOLD
private final float CPU_REACTIVATION_THRESHOLD = 0.1f;
private float cpuReactivationThreshold;
ActivationWorkersManager(ResourceManager rm, ActiveWorkersMap activeWorkers) {
private final int PERIOD = 5000;
ActivationWorkersManager(ResourceManager rm, ActiveWorkersMap activeWorkers, float cpuThreshold) {
this.rm = rm;
this.activeWorkers = activeWorkers;
this.cpuReactivationThreshold = cpuThreshold / 2;
}
......@@ -45,20 +45,24 @@ public class ActivationWorkersManager implements Runnable {
if (activeWorkers.size() == 0){
System.out.println("No active Workers. Let's activate another Worker.");
if(activeWorkers.reactivateWorker()){
if(activeWorkers.reactivateWorker("NaW")){ // No active Workers
rm.updateActiveWorkersEverywhere();
continue;
} else {
System.out.println("1- There are no healthy workers to reactivate! No workers were activated!");
}
continue;
}
activeWorkers.isHistoryUpdated(); // which also means all metrics are filled
activeWorkers.isHistoryUpdated(); // which also means that all metrics are filled
float actualCPUUsage = activeWorkers.getTotalCPUUsage();
if(actualCPUUsage < CPU_REACTIVATION_THRESHOLD){
if(actualCPUUsage < cpuReactivationThreshold){
System.out.printf("Current CPU usage of Node is %.2f. Let's activate another Worker.\n",actualCPUUsage);
if(activeWorkers.reactivateWorker()){
if(activeWorkers.reactivateWorker("time")){
rm.updateActiveWorkersEverywhere();
}
} else {
System.out.println("2- There are no healthy workers to reactivate! No workers were activated!");
}
}
}
}
......
......@@ -18,6 +18,7 @@
package app;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
......@@ -25,6 +26,7 @@ import java.util.concurrent.ConcurrentHashMap;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONException;
import es.bsc.compss.nfr.model.Worker;
......@@ -40,6 +42,7 @@ public class ActiveWorkersMap {
private boolean updateEnergy = false;
private boolean historyMetricsFilled = false;
private boolean mapsUpdated = false;
private final int COMPUTING_UNITS = Runtime.getRuntime().availableProcessors();
......@@ -66,6 +69,10 @@ public class ActiveWorkersMap {
}
}
public String toString(){
return activeWorkerMetrics.toString();
}
public int size() {
return activeWorkerMetrics.size();
}
......@@ -84,18 +91,22 @@ public class ActiveWorkersMap {
}
public void put(int workerPid, JSONObject metrics) {
// Control the length of the history array (5 seconds = 5 metrics records)
if (activeWorkersMetricsHistory.get(workerPid).length() == monitoringPeriod) {
activeWorkersMetricsHistory.get(workerPid).remove(0);
try{
// Control the length of the history array (5 seconds = 5 metrics records)
if (activeWorkersMetricsHistory.get(workerPid).length() == monitoringPeriod) {
activeWorkersMetricsHistory.get(workerPid).remove(0);
}
// Correct the CPU usage by process to get in the whole "system", not by core
float cpuUsageSystem = metrics.getFloat("task-clock") / COMPUTING_UNITS;
metrics.put("task-clock", cpuUsageSystem);
// Add metrics received to calculate other values with CPU usage,
// e.g. energy consumed
activeWorkerMetrics.put(workerPid, metrics);
// Add metrics received to the history array
activeWorkersMetricsHistory.put(workerPid, activeWorkersMetricsHistory.get(workerPid).put(metrics));
}catch(NullPointerException ex){
System.out.println("!!WARNING!! Worker with PID " + workerPid+ " has active=" + getWorkerByPid(workerPid).isActive());
}
// Correct the CPU usage by process to get in the whole "system", not by core
float cpuUsageSystem = metrics.getFloat("task-clock") / COMPUTING_UNITS;
metrics.put("task-clock", cpuUsageSystem);
// Add metrics received to calculate other values with CPU usage,
// p.e. energy consumed
activeWorkerMetrics.put(workerPid, metrics);
// Add metrics received to the history array
activeWorkersMetricsHistory.put(workerPid, activeWorkersMetricsHistory.get(workerPid).put(metrics));
}
public boolean isWorkerActive(int workerPid) {
......@@ -103,7 +114,7 @@ public class ActiveWorkersMap {
}
public float getWorkerCPUUsage(int workerPid) {
return activeWorkerMetrics.get(workerPid).getFloat("task-clock");
return activeWorkerMetrics.get(workerPid).getFloat("task-clock");
}
public int getFirstActiveWorkerPid() {
......@@ -114,31 +125,68 @@ public class ActiveWorkersMap {
return 0;
}
public boolean reactivateWorker() {
public boolean reactivateWorker(String dimension) {
if (allWorkersSize() > 0) {
int workerToActivate = 0;
float minCPUUsage = workerList.get(0).getCpuUsage();
for (int i = 1; i < allWorkersSize(); i++) {
if ((!workerList.get(i).isActive()) && workerList.get(i).getCpuUsage() < minCPUUsage) {
workerToActivate = i;
minCPUUsage = workerList.get(i).getCpuUsage();
Map<Integer,Worker> inactiveWorkers = new HashMap<>();
for (Worker w : workerList) {
if(!w.isActive() && !(w.getDeactivationReasons().contains("security") || w.getDeactivationReasons().contains("communication"))){
inactiveWorkers.put(w.getPid(),w);
}
}
if(inactiveWorkers.size() > 0){
Map.Entry<Integer,Worker> entry = inactiveWorkers.entrySet().iterator().next();
int workerPidToActivate = entry.getKey();
if(dimension.equals("time")|| dimension.equals("NaW")){
float minCpuUsage = entry.getValue().getCpuUsage();
for (Worker worker : inactiveWorkers.values()) {
if (worker.getCpuUsage() < minCpuUsage) {
workerPidToActivate = worker.getPid();
minCpuUsage = worker.getCpuUsage();
}
}
} else if(dimension.equals("energy")){
float minEnergyUsage = entry.getValue().getEnergyUsage();
for (Worker worker : inactiveWorkers.values()) {
if (worker.getEnergyUsage() < minEnergyUsage) {
workerPidToActivate = worker.getPid();
minEnergyUsage = worker.getEnergyUsage();
}
}
}
// if(inactiveWorkers.get(workerPidToActivate).getDeactivationReason().contains(dimension) ||
// inactiveWorkers.get(workerPidToActivate).getDeactivationReason().contains("security")) {
inactiveWorkers.get(workerPidToActivate).setActive(true);
inactiveWorkers.get(workerPidToActivate).setComputingUnits(COMPUTING_UNITS);
//}
// int workerPidToActivate = inactiveWorkers.get(0).getPid();
// float minCpuUsage = inactiveWorkers.get(0).getCpuUsage();
// for (int i = 1; i < inactiveWorkers.size(); i++) {
// if (inactiveWorkers.get(i).getCpuUsage() < minCpuUsage) {
// workerPidToActivate = inactiveWorkers.get(i).getPid();
// minCpuUsage = inactiveWorkers.get(i).getCpuUsage();
// }
// }
// for (Worker w : workerList) {
// if(w.getPid() == workerPidToActivate & w.getDeactivationReason().equals("time")){
// w.setActive(true);
// w.setComputingUnits(COMPUTING_UNITS);
// }
// }
return true;
}
workerList.get(workerToActivate).setActive(true);
workerList.get(workerToActivate).setComputingUnits(COMPUTING_UNITS);
return true;
}
return false;
}
public int getMinCPUUsageWorkerPid() {
int minCPUUsageWorkerPid = getFirstActiveWorkerPid();
float minCPUUsage = getWorkerCPUUsage(minCPUUsageWorkerPid);
for (Integer workerPid : workerPids()) {
System.out.println();
if (getWorkerCPUUsage(workerPid) < minCPUUsage) {
minCPUUsageWorkerPid = workerPid;
minCPUUsage = getWorkerCPUUsage(workerPid);
......@@ -148,13 +196,26 @@ public class ActiveWorkersMap {
}
public float getTotalCPUUsage() {
//waitingToUpdateEnergy();
float sum = 0;
for (JSONObject metrics : activeWorkerMetrics.values()) {
for (JSONObject metrics : activeWorkerMetrics.values()) {
sum += metrics.getFloat("task-clock");
}
return sum;
}
/*public List<Worker> checkSecurity() {
List<Worker> unsafeWorkers = new ArrayList<>();
for (Worker worker : workerList) {
if (worker.isActive()) {
if (!worker.getApplication().isSecure()) {
unsafeWorkers.add(worker);
}
}
}
return unsafeWorkers;
}*/
/*************************************************************************
**************************** Energy Monitor *****************************
*************************************************************************
......@@ -170,7 +231,7 @@ public class ActiveWorkersMap {
public synchronized void energyCanBeUpdated() {
updateEnergy = true;
notifyAll();
notifyAll();
}
public synchronized void waitingToUpdateEnergy() {
......@@ -197,7 +258,7 @@ public class ActiveWorkersMap {
******************************************************************************/
public synchronized void waitForWorkersActivation() {
while (size()==0) {
while (size() == 0) {
try {
wait();
} catch (InterruptedException e) {
......@@ -208,6 +269,8 @@ public class ActiveWorkersMap {
public synchronized void updateActiveWorkersMetricsMap() {
mapsWillBeUpdated();
List<Integer> activeWorkersPids = getActualActiveWorkersPid();
if (size() == 0) {
......@@ -240,6 +303,22 @@ public class ActiveWorkersMap {
return activeWorkersPids;
}
public synchronized void mapsWillBeUpdated() {
mapsUpdated = false;
}
public synchronized boolean areMapsUpdated(String inputLine) {
if(inputLine.equals("UPDATED") && mapsUpdated == false) {
mapsUpdated = true;
System.out.println("Active Workers Updated");
return true;
} else if(mapsUpdated == false){
System.out.println("Wainting Active Workers Update");
return true;
}
return false;
}
/*************************************************************************
************************ Dataclay Writing Manager ***********************
*************************************************************************
......@@ -270,4 +349,4 @@ public class ActiveWorkersMap {
return activeWorkersMetricsHistory;
}
}
\ No newline at end of file
}
......@@ -17,6 +17,7 @@
package app;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
......@@ -48,40 +49,48 @@ public class DataclayWritingManager implements Runnable {
break;
}
activeWorkers.isHistoryUpdated();
// Add/Update CPU mean usage in DataClay Worker
Map<Integer, JSONArray> activeWorkersMetricsHistory = activeWorkers.getActiveWorkersHistory();
// Check for activated Workers
if (activeWorkers.size() == 0) {
activeWorkers.waitForWorkersActivation();
continue;
}
for (Integer pidWorker : activeWorkersMetricsHistory.keySet()) {
activeWorkers.isHistoryUpdated();
JSONArray metricsHistory = activeWorkersMetricsHistory.get(pidWorker);
// Add/Update CPU and Power Worker mean usage in dataClay
Map<Integer, JSONArray> activeWorkersMetricsHistory = new HashMap<>(activeWorkers.getActiveWorkersHistory());
for (Integer workerPid : activeWorkersMetricsHistory.keySet()) {
JSONArray metricsHistory = activeWorkersMetricsHistory.get(workerPid);
float sumCpuUsage = 0.0f;
float sumEnergyUsage = 0.0f;
float sumPowerUsage = 0.0f;
int lengthHistory = metricsHistory.length();
for (int i = 0; i < metricsHistory.length(); i++) {
JSONObject metrics = metricsHistory.getJSONObject(i);
if (metrics.isEmpty() || (!metrics.has("task-clock")) || (!metrics.has("power"))) {
lengthHistory--;
continue;
}
sumCpuUsage += metrics.getFloat("task-clock");
sumEnergyUsage += metrics.getFloat("power");
}
sumPowerUsage += metrics.getFloat("power");
}
float meanCpuUsage = sumCpuUsage / lengthHistory;
float meanEnergyUsage = sumEnergyUsage / lengthHistory;
float meanPowerUsage = sumPowerUsage / lengthHistory;
if(Float.isNaN(meanCpuUsage) || Float.isNaN(meanPowerUsage)) {
System.out.println("!!WARNING!! NaN values!");
continue;
}
for (Worker w : workerList) {
if (w.getPid() == pidWorker) {
if (w.getPid() == workerPid) {
w.setCpuUsage(meanCpuUsage);
w.setEnergyUsage(meanEnergyUsage);
w.setEnergyUsage(meanPowerUsage);
System.out.printf(
"Worker %d writes on Dataclay its average CPU and Energy usage\t|%.2f|\t|%.2f|\n",
pidWorker, meanCpuUsage, meanEnergyUsage);
"[dataClay]\tWorker %d writes on dataClay its average CPU and Energy usage\t|%.2f| |%.2f|\n",
w.getPid(), w.getCpuUsage(), w.getEnergyUsage());
break;
}
}
......
......@@ -25,6 +25,8 @@ import java.net.Socket;
import org.json.JSONObject;
import java.util.List;
import es.bsc.compss.nfr.model.Worker;
public class EnergyMonitor implements Runnable {
......@@ -67,6 +69,7 @@ public class EnergyMonitor implements Runnable {
Runtime.getRuntime().exec(command);
System.out.println(threadName + " Probe starts running");
JSONObject workerMetricsReceived = new JSONObject();
try {
System.out.println(threadName + " Server waiting" + " for the connection of " + threadName + " Probe");
......@@ -83,57 +86,70 @@ public class EnergyMonitor implements Runnable {
System.out.println(threadName + " waiting for metrics...");
String inputLine = "";
JSONObject energyMetricsReceived;
// JSONObject workerMetricsReceived;
float totalEnergyConsumed = 0.0f;
BufferedReader in = new BufferedReader(new InputStreamReader(socketEnergy.getInputStream()));
while ((inputLine = in.readLine()) != null) {
// New data has arrived, so history metrics must not be accessed
activeWorkers.historyWillBeUpdated();
//System.out.println(inputLine);
// Check for activated Workers
if (activeWorkers.size() == 0) {
activeWorkers.waitForWorkersActivation();
// in = new BufferedReader(new InputStreamReader(socketTime.getInputStream()));
in = new BufferedReader(new InputStreamReader(socketEnergy.getInputStream()));
continue;
}
energyMetricsReceived = new JSONObject(inputLine);
workerMetricsReceived = new JSONObject(inputLine);
// EnergyMonitor has to wait for TimeMonitor
activeWorkers.energyWait();
// if (activeWorkers.size() > 0) {
// Check Workers security
/*
List<Worker> unsafeWorkers = activeWorkers.checkSecurity();
if(!unsafeWorkers.isEmpty()){
for (Worker w : unsafeWorkers) {
System.out.println(threadName + " added security violation to queue");
NFRViolation violation = new NFRViolation("security", "security status", w.getPid());
queue.addNFRViolation(violation);
}
}*/
// While TimeMonitor does not save the metrics, more specifically CPU usage, it
// is not possible to determine the consumptions spent by Worker.
activeWorkers.waitingToUpdateEnergy();
// Save total energy consumed
totalEnergyConsumed = workerMetricsReceived.getFloat("SOCpower");
// After the time metrics are filled, the energy metrics can be filled
for (Integer pid : activeWorkers.workerPids()) {
// This verification is necessary as the probe may have already sent
// metrics against Workers that have been disabled in the meantime
if (activeWorkers.isWorkerActive(pid)) {
float cpuUsage = activeWorkers.getWorkerCPUUsage(pid);
totalEnergyConsumed = energyMetricsReceived.getFloat("SOCpower");
// New data has arrived, so history metrics must not be accessed
activeWorkers.historyWillBeUpdated();
// Add/Update power metric in Active Workers and History Maps
activeWorkers.addEnergyConsumed(pid, "power", cpuUsage * totalEnergyConsumed);
}
}
}
// After the time and energy metrics are filled, the history can be accessed
activeWorkers.historyIsUpdated();
// If so, check the Node capacity
// Check the Node capacity
getNodeEnergyCapacity();
System.out.printf("[EnergyMonitor]\tNode Energy consumed/capacity : %.2f / %.2f\n", totalEnergyConsumed,
energyThreshold);
if (totalEnergyConsumed > energyThreshold) {
System.out.println(threadName + " added time violation to queue: " + totalEnergyConsumed);
NFRViolation violation = new NFRViolation("energy", "energyload", totalEnergyConsumed);
System.out.printf("[EnergyMonitor]\tNode Energy consumed/capacity : %.2f / %.2f\n", totalEnergyConsumed,
energyThreshold);
System.out.println(threadName + " added energy violation to queue: " + totalEnergyConsumed);
NFRViolation violation = new NFRViolation("energy", "energy load", totalEnergyConsumed);
queue.addNFRViolation(violation);
}
//}
}
} catch (IOException e) {
......@@ -141,8 +157,9 @@ public class EnergyMonitor implements Runnable {
e.printStackTrace();
}
} catch (Exception e) {
socketEnergy.close();
//socketEnergy.close();
System.out.println(threadName + " Socket exception: " + e.getMessage());
System.out.println(workerMetricsReceived);
e.printStackTrace();
}
} catch (IOException e) {
......
......@@ -41,7 +41,7 @@ import java.util.List;
*/
public class NFRTool {
// FIXME: Threshold values for demo purposes only
private static final float CPU_THRESHOLD = 0.2f; // 0.8f;
private static final float CPU_THRESHOLD = 0.35f; // 0.8f;
private static final float ENERGY_THRESHOLD = 20.0f; // Watts
/**
......@@ -73,7 +73,6 @@ public class NFRTool {
System.out.println("NFRTool current public IP address: " + publicIP);
socket.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
......@@ -141,6 +140,11 @@ public class NFRTool {
return system;
}
/**
* Retrieves process ID.
* Necessary since we're using Java 8
* @return process ID.
*/
public static synchronized long getPidOfProcess(Process p) {
long pid = -1;
try {
......@@ -168,17 +172,17 @@ public class NFRTool {
Process p2 = Runtime.getRuntime().exec("fake_worker/fakeworker2");
pid2 = (int) getPidOfProcess(p2);
Process p3 = Runtime.getRuntime().exec("fake_worker/fakeworker3");
pid3 = (int) getPidOfProcess(p3);
// Process p3 = Runtime.getRuntime().exec("fake_worker/fakeworker3");
// pid3 = (int) getPidOfProcess(p3);
// Process p4 = Runtime.getRuntime().exec("fake_worker/fakeworker4");
// pid4 = (int) p4.pid();
// Process p4 = Runtime.getRuntime().exec("fake_worker/fakeworker4");
// pid4 = (int) getPidOfProcess(p4);
// Process p5 = Runtime.getRuntime().exec("fake_worker/fakeworker5");
// pid5 = (int) getPidOfProcess(p5);
// Process p5 = Runtime.getRuntime().exec("fake_worker/fakeworker5");
// pid5 = (int) getPidOfProcess(p5);
// Process p6 = Runtime.getRuntime().exec("fake_worker/fakeworker6");
// pid6 = (int) getPidOfProcess(p6);
Process p6 = Runtime.getRuntime().exec("fake_worker/fakeworker6");
pid6 = (int) getPidOfProcess(p6);
} catch (Exception e) {
e.printStackTrace();
......@@ -196,28 +200,28 @@ public class NFRTool {
float cpuUsage = 0.0f, energyUsage = 0.0f, communicationCost = 0.0f;
int computingUnits = Runtime.getRuntime().availableProcessors();
String ip = localIP;
List<String> deactivationReason = new ArrayList<>();
List<String> deactivationReason = new ArrayList<>();
deactivationReason.add("");
Worker worker1 = new Worker(node, pid1, true, app, cpuUsage, energyUsage, computingUnits, ip,
communicationCost, deactivationReason);
Worker worker2 = new Worker(node, pid2, true, app, cpuUsage, energyUsage, computingUnits, ip,
communicationCost, deactivationReason);
Worker worker3 = new Worker(node, pid3, true, app, cpuUsage, energyUsage, computingUnits, ip,
communicationCost, deactivationReason);
// Worker worker4 = new Worker(node, pid4, true, app, cpuUsage, energyUsage, computingUnits, ip,
// communicationCost, deactivationReason);
// Worker worker5 = new Worker(node, pid5, true, app, cpuUsage, energyUsage, computingUnits, ip,
//Worker worker3 = new Worker(node, pid3, true, app, cpuUsage, energyUsage, computingUnits, ip,
// communicationCost, deactivationReason);
// Worker worker6 = new Worker(node, pid6, true, app, cpuUsage, energyUsage, computingUnits, ip,
//Worker worker4 = new Worker(node, pid4, true, app, cpuUsage, energyUsage, computingUnits, ip,
// communicationCost, deactivationReason);
//Worker worker5 = new Worker(node, pid5, true, app, cpuUsage, energyUsage, computingUnits, ip,
// communicationCost, deactivationReason);
Worker worker6 = new Worker(node, pid6, true, app, cpuUsage, energyUsage, computingUnits, ip,
communicationCost, deactivationReason);
// Add worker to application
app.addWorker(worker1);
app.addWorker(worker2);
app.addWorker(worker3);
//app.addWorker(worker3);
//app.addWorker(worker4);
//app.addWorker(worker5);
//app.addWorker(worker6);
app.addWorker(worker6);
}
public static void getCurrentElasticSystem(ElasticSystem system) {
......@@ -263,6 +267,8 @@ public class NFRTool {
String mode = null;
String localIP = null;
System.out.println("--RUNNING ON AGX XAVIER--");
if (args.length < 1) {
System.err.println("[ERROR] Bad arguments. " + getUsage());
exitGracefully();
......@@ -344,7 +350,7 @@ public class NFRTool {
Thread rmThread = new Thread(resourceManager, "Resource Manager");
ActivationWorkersManager activationWorkersManager = new ActivationWorkersManager(resourceManager,
metricsActiveWorkersList);
metricsActiveWorkersList, CPU_THRESHOLD);
Thread awmThread = new Thread(activationWorkersManager, "Activation Workers Manager");
TimeMonitor timeMonitor = new TimeMonitor(resourceManager, queue, metricsActiveWorkersList);
......@@ -363,6 +369,45 @@ public class NFRTool {
awmThread.start();
dwmThread.start();
/*Thread.sleep(7000);
app.setSecurity(false);
System.out.println("METI A APP NÃO SEGURA");
Thread.sleep(7000);
app.setSecurity(true);
System.out.println("METI A APP SEGURA");
Thread.sleep(10000);
app.setSecurity(false);
System.out.println("METI A APP NÃO SEGURA");
Thread.sleep(5000);
app.setSecurity(true);
System.out.println("METI A APP SEGURA");
Thread.sleep(10000);
app.setSecurity(false);
System.out.println("METI A APP NÃO SEGURA");
Thread.sleep(5000);
app.setSecurity(true);
System.out.println("METI A APP SEGURA");
Thread.sleep(20000);
app.setSecurity(false);
System.out.println("METI A APP NÃO SEGURA");
Thread.sleep(5000);
app.setSecurity(true);
System.out.println("METI A APP SEGURA");
*/
rmThread.join();
tmThread.join();
emThread.join();
......
......@@ -40,15 +40,29 @@ public class NFRViolationQueue {
}
public synchronized NFRViolation getNFRViolation() {
while (queue.isEmpty()) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// while (queue.isEmpty()) {
// try {
// wait();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
NFRViolation remove = queue.remove();
return remove;
}
}
\ No newline at end of file
public synchronized void checkViolations(){
while (queue.isEmpty()) {
try {
wait();
} catch (InterruptedException e){
e.printStackTrace();
}
}
}
public int size(){
return this.queue.size();
}
}
......@@ -20,6 +20,8 @@ package app;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;