/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include <unistd.h>

#include <pagemap/pagemap.h>

#define SIMPLEQ_INSERT_SIMPLEQ_TAIL(head_a, head_b)             \
    do {                                                        \
        if (!SIMPLEQ_EMPTY(head_b)) {                           \
            if ((head_a)->sqh_first == NULL)                    \
                (head_a)->sqh_first = (head_b)->sqh_first;      \
            *(head_a)->sqh_last = (head_b)->sqh_first;          \
            (head_a)->sqh_last = (head_b)->sqh_last;            \
        }                                                       \
    } while (/*CONSTCOND*/0)

/* We use an array of int to store the references to a given offset in the swap
   1 GiB swap means 512KiB size array: offset are the index */
typedef unsigned short pm_pswap_refcount_t;
struct pm_proportional_swap {
    unsigned int array_size;
    pm_pswap_refcount_t *offset_array;
};

void pm_memusage_zero(pm_memusage_t *mu) {
    mu->vss = mu->rss = mu->pss = mu->uss = mu->swap = 0;
    mu->p_swap = NULL;
    SIMPLEQ_INIT(&mu->swap_offset_list);
}

void pm_memusage_pswap_init_handle(pm_memusage_t *mu, pm_proportional_swap_t *p_swap) {
    mu->p_swap = p_swap;
}

void pm_memusage_add(pm_memusage_t *a, pm_memusage_t *b) {
    a->vss += b->vss;
    a->rss += b->rss;
    a->pss += b->pss;
    a->uss += b->uss;
    a->swap += b->swap;
    SIMPLEQ_INSERT_SIMPLEQ_TAIL(&a->swap_offset_list, &b->swap_offset_list);
}

pm_proportional_swap_t * pm_memusage_pswap_create(int swap_size)
{
    pm_proportional_swap_t *p_swap = NULL;

    p_swap = malloc(sizeof(pm_proportional_swap_t));
    if (p_swap == NULL) {
        fprintf(stderr, "Error allocating proportional swap.\n");
    } else {
        p_swap->array_size = swap_size / getpagesize();
        p_swap->offset_array = calloc(p_swap->array_size, sizeof(pm_pswap_refcount_t));
        if (p_swap->offset_array == NULL) {
            fprintf(stderr, "Error allocating proportional swap offset array.\n");
            free(p_swap);
            p_swap = NULL;
        }
    }

    return p_swap;
}

void pm_memusage_pswap_destroy(pm_proportional_swap_t *p_swap) {
    if (p_swap) {
        free(p_swap->offset_array);
        free(p_swap);
    }
}

void pm_memusage_pswap_add_offset(pm_memusage_t *mu, unsigned int offset) {
    pm_swap_offset_t *soff;

    if (mu->p_swap == NULL)
        return;

    if (offset >= mu->p_swap->array_size) {
        fprintf(stderr, "SWAP offset %d is out of swap bounds.\n", offset);
        return;
    }

    if (mu->p_swap->offset_array[offset] == USHRT_MAX) {
        fprintf(stderr, "SWAP offset %d ref. count if overflowing ushort type.\n", offset);
    } else {
        mu->p_swap->offset_array[offset]++;
    }

    soff = malloc(sizeof(pm_swap_offset_t));
    if (soff) {
        soff->offset = offset;
        SIMPLEQ_INSERT_TAIL(&mu->swap_offset_list, soff, simpleqe);
    }
}

void pm_memusage_pswap_get_usage(pm_memusage_t *mu, pm_swapusage_t *su) {

    int pagesize = getpagesize();
    pm_swap_offset_t *elem;

    if (su == NULL)
        return;

    su->proportional = su->unique = 0;
    SIMPLEQ_FOREACH(elem, &mu->swap_offset_list, simpleqe) {
        su->proportional += pagesize / mu->p_swap->offset_array[elem->offset];
        su->unique += mu->p_swap->offset_array[elem->offset] == 1 ? pagesize : 0;
    }
}

void pm_memusage_pswap_free(pm_memusage_t *mu) {
    pm_swap_offset_t *elem = SIMPLEQ_FIRST(&mu->swap_offset_list);
    while (elem) {
        SIMPLEQ_REMOVE_HEAD(&mu->swap_offset_list, simpleqe);
        free(elem);
        elem = SIMPLEQ_FIRST(&mu->swap_offset_list);
    }
}
