<commit_before>/**
 * \file
 * \brief
 */

/*
 * Copyright (c) 2007, 2008, 2010, 2011, 2012, ETH Zurich.
 * All rights reserved.
 *
 * This file is distributed under the terms in the attached LICENSE file.
 * If you do not find this file, copies can be found by writing to:
 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
 */

#include "monitor.h"
#include <if/monitor_mem_defs.h>
#include <if/monitor_mem_rpcclient_defs.h>

static uint8_t mem_core_id;
static struct monitor_mem_rpc_client monitor_mem_client;
static bool mem_setup_complete = false;
iref_t monitor_mem_iref = 0;

/**
 * \brief Request for some memory (over the memory allocation channel)
 */
static void mem_alloc_handler(struct monitor_mem_binding *b,
                              uint8_t size_bits, genpaddr_t minbase,
                              genpaddr_t maxlimit)
{
    struct capref cap;
    monitor_mem_caprep_t caprep = {0,0,0,0};
    errval_t err;
    errval_t reterr = SYS_ERR_OK;

    /* This should only run on the core with the mem_serv. Or else the system
       will deadlock. */
    assert(bsp_monitor);
    err = ram_alloc(&cap, size_bits);
    if (err_is_fail(err)) {
        reterr = err_push(err, LIB_ERR_RAM_ALLOC);
        goto out;
    }

    struct capability cap_raw;
    err = monitor_cap_identify(cap, &cap_raw);
    if (err_is_fail(err)) {
        reterr = err_push(err, MON_ERR_CAP_IDENTIFY);
        err = cap_destroy(cap);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "cap_destroy failed");
        }
        goto out;
    }
    assert(cap_raw.type == ObjType_RAM);
    intermon_caprep_t caprep2;
    capability_to_caprep(&cap_raw, &caprep2);
    // XXX: work around stupid flounder behaviour: these types are identical!
    STATIC_ASSERT_SIZEOF(caprep, sizeof(caprep2));
    memcpy(&caprep, &caprep2, sizeof(caprep));

out:
    // RPC protocol, this can never fail with TX_BUSY
    err = b->tx_vtbl.alloc_response(b, NOP_CONT, reterr, caprep);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "reply failed");
    }

    // XXX: cap is leaked! *should* set owner to dest core and then delete, but
    // dest core not known.
}

static errval_t mon_ram_alloc(struct capref *ret, uint8_t size_bits,
                              uint64_t minbase, uint64_t maxlimit)
{
    errval_t err;
    intermon_caprep_t caprep;
    errval_t reterr;

    err = monitor_mem_client.vtbl.alloc(&monitor_mem_client, size_bits,
                                        minbase, maxlimit, &reterr,
                                        (monitor_mem_caprep_t *) &caprep);
    if (err_is_fail(err)) {
        return err_push(err, MON_ERR_RAM_ALLOC_ERR);
    } else if (err_is_fail(reterr)) {<commit_msg>Properly cleanup caps during alloc through monitor_mem.<commit_after>/**
 * \file
 * \brief
 */

/*
 * Copyright (c) 2007, 2008, 2010, 2011, 2012, ETH Zurich.
 * All rights reserved.
 *
 * This file is distributed under the terms in the attached LICENSE file.
 * If you do not find this file, copies can be found by writing to:
 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
 */

#include "monitor.h"
#include "capops.h"
#include <if/monitor_mem_defs.h>
#include <if/monitor_mem_rpcclient_defs.h>

static uint8_t mem_core_id;
static struct monitor_mem_rpc_client monitor_mem_client;
static bool mem_setup_complete = false;
iref_t monitor_mem_iref = 0;

static void mem_alloc_delete_result_handler(errval_t status, void *st)
{
    struct capref *cap = (struct capref*)st;
    errval_t err;

    if (err_is_fail(status)) {
        DEBUG_ERR(status, "capops_delete failed, cap will leak");
    }
    else {
        struct capability out;
        err = monitor_cap_identify(*cap, &out);
        if (err_no(err) != SYS_ERR_CAP_NOT_FOUND) {
            DEBUG_ERR(err, "capops_delete returned OK, but cap still there");
            char buf[512];
            debug_print_cap(buf, sizeof(buf), &out);
        }
        err = slot_free(*cap);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "slot_free failed, cap will leak");
        }
    }

    free(cap);
}

/**
 * \brief Request for some memory (over the memory allocation channel)
 */
static void mem_alloc_handler(struct monitor_mem_binding *b,
                              uint8_t size_bits, genpaddr_t minbase,
                              genpaddr_t maxlimit)
{
    struct capref *cap = NULL;
    monitor_mem_caprep_t caprep = {0,0,0,0};
    errval_t err;
    errval_t reterr = SYS_ERR_OK;

    /* This should only run on the core with the mem_serv. Or else the system
       will deadlock. */
    assert(bsp_monitor);

    cap = malloc(sizeof(*cap));
    if (!cap) {
        reterr = LIB_ERR_MALLOC_FAIL;
        goto out;
    }

    err = ram_alloc(cap, size_bits);
    if (err_is_fail(err)) {
        reterr = err_push(err, LIB_ERR_RAM_ALLOC);
        goto out;
    }

    struct capability cap_raw;
    err = monitor_cap_identify(*cap, &cap_raw);
    if (err_is_fail(err)) {
        reterr = err_push(err, MON_ERR_CAP_IDENTIFY);
        goto out;
    }
    assert(cap_raw.type == ObjType_RAM);
    intermon_caprep_t caprep2;
    capability_to_caprep(&cap_raw, &caprep2);
    // XXX: work around stupid flounder behaviour: these types are identical!
    STATIC_ASSERT_SIZEOF(caprep, sizeof(caprep2));
    memcpy(&caprep, &caprep2, sizeof(caprep));

    bool unused_has_descendants;
    err = monitor_cap_remote(*cap, true, &unused_has_descendants);
    if (err_is_fail(err)) {
        reterr = err;
        memset(&caprep, 0, sizeof(caprep));
    }

out:
    // RPC protocol, this can never fail with TX_BUSY
    err = b->tx_vtbl.alloc_response(b, NOP_CONT, reterr, caprep);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "reply failed");
    }

    err = capops_delete(get_cap_domref(*cap), mem_alloc_delete_result_handler, cap);
    if (err_is_fail(err)) {
        DEBUG_ERR(err, "capops_delete failed, cap will leak");
        free(cap);
    }
}

static errval_t mon_ram_alloc(struct capref *ret, uint8_t size_bits,
                              uint64_t minbase, uint64_t maxlimit)
{
    errval_t err;
    intermon_caprep_t caprep;
    errval_t reterr;

    err = monitor_mem_client.vtbl.alloc(&monitor_mem_client, size_bits,
                                        minbase, maxlimit, &reterr,
                                        (monitor_mem_caprep_t *) &caprep);
    if (err_is_fail(err)) {
        return err_push(err, MON_ERR_RAM_ALLOC_ERR);
    } else if (err_is_fail(reterr)) {
{'fraction_non_alphanumeric': 0.10013801564177273, 'fraction_numerical': 0.01318816132495016, 'mean_word_length': 2.7311212814645307, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4298104', 'n_tokens_mistral': 2303, 'n_tokens_neox': 2212, 'n_words': 555}