LCOV - code coverage report
Current view: top level - runtime - msu_state.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 36 45 80.0 %
Date: 2018-01-11 Functions: 3 5 60.0 %

          Line data    Source code
       1             : /*
       2             : START OF LICENSE STUB
       3             :     DeDOS: Declarative Dispersion-Oriented Software
       4             :     Copyright (C) 2017 University of Pennsylvania, Georgetown University
       5             : 
       6             :     This program is free software: you can redistribute it and/or modify
       7             :     it under the terms of the GNU General Public License as published by
       8             :     the Free Software Foundation, either version 3 of the License, or
       9             :     (at your option) any later version.
      10             : 
      11             :     This program is distributed in the hope that it will be useful,
      12             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :     GNU General Public License for more details.
      15             : 
      16             :     You should have received a copy of the GNU General Public License
      17             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : END OF LICENSE STUB
      19             : */
      20             : /**
      21             :  * @file msu_state.c
      22             :  *
      23             :  * State storage that is tied to a specific MSU message
      24             :  */
      25             : #include "msu_message.h"
      26             : #include "rt_stats.h"
      27             : #include "logging.h"
      28             : #include "uthash.h"
      29             : #include "local_msu.h"
      30             : 
      31             : /** Explicitly check whether a state is being replaced on a call to msu_init_state */
      32             : #define CHECK_STATE_REPLACEMENT 1
      33             : 
      34             : /** The structure contining msu state */
      35             : struct msu_state {
      36             :     /** The key with which the state is stored */
      37             :     struct composite_key key;
      38             :     /** The size of the data being stored */
      39             :     size_t size;
      40             :     /** An ID to facilitate the transferring of state between msus (not implemented yet) */
      41             :     int group_id;
      42             :     /** A unique identifier for the state 
      43             :      * (not used at the moment, will be utilized in state transfer) */
      44             :     int32_t id;
      45             :     /** The payload of the state */
      46             :     void *data;
      47             :     /** For use with the UT hash structure */
      48             :     UT_hash_handle hh;
      49             : };
      50             : 
      51           0 : int msu_num_states(struct local_msu *msu) {
      52           0 :     return HASH_COUNT(msu->item_state);
      53             : }
      54             : 
      55           6 : void *msu_init_state(struct local_msu *msu, struct msu_msg_key *key, size_t size) {
      56           6 :     struct msu_state *state = malloc(sizeof(*state));
      57           6 :     memcpy(&state->key, &key->key, key->key_len);
      58           6 :     state->group_id = key->group_id;
      59           6 :     state->data = malloc(size);
      60           6 :     state->size = size;
      61           6 :     state->id = key->id;
      62             : 
      63           6 :     log(LOG_STATE_MANAGEMENT, "Allocating new state of size %d for msu %d, key %d",
      64             :                (int)size, msu->id, (int)key->id);
      65             : 
      66             : #if CHECK_STATE_REPLACEMENT
      67           6 :     struct msu_state *old_state = NULL;
      68           6 :     HASH_REPLACE(hh, msu->item_state, key, key->key_len, state, old_state);
      69           6 :     if (old_state != NULL) {
      70           0 :         log_warn("Replacing old state! Not freeing! Bad!");
      71             :     }
      72             : #else
      73             :     HASH_ADD(hh, msu->item_state, key, key->key_len, state);
      74             : #endif
      75             : 
      76           6 :     increment_stat(MSU_MEM_ALLOC, msu->id, (double)(sizeof(*state) + size));
      77           6 :     increment_stat(MSU_NUM_STATES, msu->id, 1);
      78             : 
      79           6 :     return state->data;
      80             : }
      81             : 
      82           5 : void *msu_get_state(struct local_msu *msu, struct msu_msg_key *key, size_t *size) {
      83             :     struct msu_state *state;
      84           5 :     HASH_FIND(hh, msu->item_state, &key->key, key->key_len, state);
      85           5 :     log(LOG_STATE_MANAGEMENT, "Accessing state for MSU %d, key %d",
      86             :                msu->id, (int)key->id);
      87           5 :     if (state == NULL) {
      88           2 :         log(LOG_STATE_MANAGEMENT, "State does not exist");
      89           2 :         return NULL;
      90             :     }
      91           3 :     if (size != NULL) {
      92           1 :         *size = state->size;
      93             :     }
      94           3 :     return state->data;
      95             : }
      96             : 
      97           2 : int msu_free_state(struct local_msu *msu, struct msu_msg_key *key) {
      98             :     struct msu_state *state;
      99           2 :     HASH_FIND(hh, msu->item_state, &key->key, key->key_len, state);
     100           2 :     log(LOG_STATE_MANAGEMENT, "Freeing state for MSU %d, key %d",
     101             :                msu->id, (int)key->id);
     102           2 :     if (state == NULL) {
     103           1 :         log_warn("State for MSU %d, key %d does not exist",
     104             :                  msu->id, (int)key->id);
     105           1 :         return -1;
     106             :     }
     107           1 :     HASH_DEL(msu->item_state, state);
     108             : 
     109           1 :     increment_stat(MSU_MEM_ALLOC, msu->id,
     110           1 :                    (double)(-1 * (int)(sizeof(*state) + state->size)));
     111           1 :     increment_stat(MSU_NUM_STATES, msu->id, -1);
     112           1 :     free(state->data);
     113           1 :     free(state);
     114           1 :     return 0;
     115             : }
     116             : 
     117           0 : void msu_free_all_state(struct local_msu *msu) {
     118             :     struct msu_state *state, *tmp;
     119           0 :     HASH_ITER(hh, msu->item_state, state, tmp) {
     120           0 :         HASH_DEL(msu->item_state, state);
     121           0 :         free(state->data);
     122           0 :         free(state);
     123             :     }
     124           0 : }

Generated by: LCOV version 1.10