downstream_api.c 2.81 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
/* Filename: downstream.c
 *
 * Description: This file contains the implementation of downstream API to
 * transmit application context information to NRM.
 *
 * The application context information transmitted is used to monitor
 * application progress and/or invoke power policies to improve energy
 * efficiency at the node level.
 */

#include "downstream_api.h"
Sridutt Bhalachandra's avatar
Sridutt Bhalachandra committed
12 13 14 15 16 17 18 19 20 21 22
#include<zmq.h>
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>

int nrm_init(struct nrm_context *ctxt, const char *uuid)
{
    assert(ctxt != NULL);
    assert(uuid != NULL);
23
    const char *uri = getenv(NRM_ENV_URI);
Sridutt Bhalachandra's avatar
Sridutt Bhalachandra committed
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
    if(uri == NULL)
        uri = NRM_DEFAULT_URI;
    ctxt->container_uuid = getenv("ARGO_CONTAINER_UUID");
    assert(ctxt->container_uuid != NULL);
    ctxt->app_uuid = (char *)uuid;
    ctxt->context = zmq_ctx_new();
    ctxt->socket = zmq_socket(ctxt->context, ZMQ_PUB);
    int err = zmq_connect(ctxt->socket, uri);
    assert(err == 0);
    char buf[512];
    snprintf(buf, 512, NRM_START_FORMAT, ctxt->container_uuid, ctxt->app_uuid);
    sleep(1);
    err = zmq_send(ctxt->socket, buf, strnlen(buf, 512), 0);
    assert(err > 0);
    assert(!clock_gettime(CLOCK_REALTIME, &ctxt->time));
    ctxt->acc = 0;
    return 0;
}

int nrm_fini(struct nrm_context *ctxt)
{
    assert(ctxt != NULL);
    char buf[512];
    snprintf(buf, 512, NRM_EXIT_FORMAT, ctxt->app_uuid);
    int err = zmq_send(ctxt->socket, buf, strnlen(buf, 512), 0);
    assert(err > 0);
    zmq_close(ctxt->socket);
    zmq_ctx_destroy(ctxt->context);
    return 0;
}

int nrm_send_progress(struct nrm_context *ctxt, unsigned long progress)
{
    char buf[512];
    struct timespec now;
    clock_gettime(CLOCK_REALTIME, &now);
    long long int timediff = (now.tv_nsec - ctxt->time.tv_nsec) +
                 1e9* (now.tv_sec - ctxt->time.tv_sec);
    ctxt->acc += progress;
63 64
    if(timediff > NRM_RATELIMIT_THRESHOLD) 
    {
Sridutt Bhalachandra's avatar
Sridutt Bhalachandra committed
65 66 67 68 69 70 71 72
        snprintf(buf, 512, NRM_PROGRESS_FORMAT, ctxt->acc, ctxt->app_uuid);
        int err = zmq_send(ctxt->socket, buf, strnlen(buf, 512), 0);
        assert(err > 0);
        ctxt->acc = 0;
    }
    ctxt->time = now;
    return 0;
}
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93

int nrm_invoke_power_policy(struct nrm_context *ctxt, int cpu, double 
        startCompute, double endCompute, double startBarrier, double 
        endBarrier)
{
    char buf[512];
    struct timespec now;
    clock_gettime(CLOCK_REALTIME, &now);
    long long int timediff = (now.tv_nsec - ctxt->time.tv_nsec) +
                 1e9* (now.tv_sec - ctxt->time.tv_sec);

    if(timediff > NRM_RATELIMIT_THRESHOLD) 
    {
        snprintf(buf, 512, NRM_POWER_POLICY_FORMAT, cpu, startCompute, 
                endCompute, startBarrier, endBarrier, ctxt->app_uuid);
        int err = zmq_send(ctxt->socket, buf, strnlen(buf, 512), 0);
        assert(err > 0);
    }
    ctxt->time = now;
    return 0;  
}