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

11 12 13 14 15 16 17 18
#include <zmq.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>

#include "nrm.h"
Sridutt Bhalachandra's avatar
Sridutt Bhalachandra committed
19

20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
struct nrm_context* nrm_ctxt_create(void)
{
    struct nrm_context *ctxt;
    ctxt = calloc(1, sizeof(struct nrm_context));
    assert(ctxt != NULL);
    return ctxt;
}

int nrm_ctxt_delete(struct nrm_context *ctxt)
{
    assert(ctxt != NULL);
    free(ctxt);
    return 0;
}

Sridutt Bhalachandra's avatar
Sridutt Bhalachandra committed
35 36 37 38 39
int nrm_init(struct nrm_context *ctxt, const char *uuid)
{
    assert(ctxt != NULL);
    assert(uuid != NULL);
    const char *uri = getenv(NRM_ENV_URI);
40
    size_t buff_size;
Sridutt Bhalachandra's avatar
Sridutt Bhalachandra committed
41 42 43 44
    if(uri == NULL)
        uri = NRM_DEFAULT_URI;
    ctxt->container_uuid = getenv("ARGO_CONTAINER_UUID");
    assert(ctxt->container_uuid != NULL);
45 46 47
    buff_size = strnlen(uuid, 255) + 1;
    ctxt->app_uuid = malloc(buff_size*sizeof(char));
    strncpy(ctxt->app_uuid, uuid, buff_size);
Sridutt Bhalachandra's avatar
Sridutt Bhalachandra committed
48
    ctxt->context = zmq_ctx_new();
49
    ctxt->socket = zmq_socket(ctxt->context, ZMQ_DEALER);
50
    zmq_setsockopt(ctxt->socket, ZMQ_IDENTITY, ctxt->app_uuid, strnlen(uuid, 255));
Sridutt Bhalachandra's avatar
Sridutt Bhalachandra committed
51 52 53 54 55 56 57
    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);
Valentin Reis's avatar
Valentin Reis committed
58
    assert(!clock_gettime(CLOCK_MONOTONIC, &ctxt->time));
Sridutt Bhalachandra's avatar
Sridutt Bhalachandra committed
59 60 61 62 63 64 65 66 67 68 69
    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);
70
    free(ctxt->app_uuid);
Sridutt Bhalachandra's avatar
Sridutt Bhalachandra committed
71 72 73 74 75 76 77 78 79
    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;
Valentin Reis's avatar
Valentin Reis committed
80
    clock_gettime(CLOCK_MONOTONIC, &now);
Sridutt Bhalachandra's avatar
Sridutt Bhalachandra committed
81 82 83
    long long int timediff = (now.tv_nsec - ctxt->time.tv_nsec) +
                 1e9* (now.tv_sec - ctxt->time.tv_sec);
    ctxt->acc += progress;
Valentin Reis's avatar
Valentin Reis committed
84
    if(timediff > NRM_RATELIMIT_THRESHOLD)
Sridutt Bhalachandra's avatar
Sridutt Bhalachandra committed
85 86 87 88 89 90 91 92 93 94
    {
        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;
}

95 96 97
int nrm_send_phase_context(struct nrm_context *ctxt, unsigned int cpu, unsigned
    int aggregation, unsigned long long int computeTime, unsigned long long int
    totalTime)
Sridutt Bhalachandra's avatar
Sridutt Bhalachandra committed
98 99 100
{
    char buf[512];
    struct timespec now;
Valentin Reis's avatar
Valentin Reis committed
101
    clock_gettime(CLOCK_MONOTONIC, &now);
Sridutt Bhalachandra's avatar
Sridutt Bhalachandra committed
102 103 104
    long long int timediff = (now.tv_nsec - ctxt->time.tv_nsec) +
                 1e9* (now.tv_sec - ctxt->time.tv_sec);

Valentin Reis's avatar
Valentin Reis committed
105
    if(timediff > NRM_RATELIMIT_THRESHOLD)
Sridutt Bhalachandra's avatar
Sridutt Bhalachandra committed
106
    {
107 108
        snprintf(buf, 512, NRM_PHASE_CONTEXT_FORMAT, cpu, aggregation,
            computeTime, totalTime, ctxt->app_uuid);
Sridutt Bhalachandra's avatar
Sridutt Bhalachandra committed
109 110 111 112
        int err = zmq_send(ctxt->socket, buf, strnlen(buf, 512), 0);
        assert(err > 0);
    }
    ctxt->time = now;
Valentin Reis's avatar
Valentin Reis committed
113
    return 0;
Sridutt Bhalachandra's avatar
Sridutt Bhalachandra committed
114
}