Exemple #1
0
static traces_log_t *traces_obtain_log_line(void)
{
	int linenum = traces_obtain_log_line_number();

	/* write out log lines */
	while (linenum >= LAST_LOGLINE) {
		AO_fetch_and_sub1(&traces->usecnt);
		
		DEBUG("writing out");
		traces_log_write_out();
		
		linenum = traces_obtain_log_line_number();
	}

	traces_log_t *logline = &traces->logs[linenum];

	memset(logline, 0, sizeof(traces_log_t));

	struct timespec timestamp;

	clock_gettime(traces->clkid, &timestamp);

	logline->msec  = timestamp.tv_sec * 1000 + timestamp.tv_nsec / 1000000;
	logline->pid   = getpid();
	logline->thrid = pthread_self();

	return logline;
}
/**
 * Description: This function pops the next function from queues
 * based on a 'deadline' if the task state is RUNNABLE.
 * If the task state is not RUNNABLE
 */
struct nkn_task *
nkn_rttask_pop_from_queue(int tnum, nkn_task_state_t tstate)
{
    int             deadline = 0;
    struct nkn_task *ntask = NULL;

    switch(tstate) {
	case TASK_STATE_RUNNABLE:
	    ntask  = 
		(struct nkn_task *)
		rtslot_get_next_item(nkn_rtsched_deadline_mgr[tnum]);

	    assert(ntask);
	    assert(ntask->sched_priv != 0xdeaddead);
	    s_dbg_find_duplicate_rttask(nkn_glob_rtsched_main_task_q,
				      ntask->task_id);
	    ntask->task_state = TASK_STATE_RUNNING;
	    deadline = ntask->deadline_q_idx;

	    ntask->debug_q_status  = DEBUG_Q_STATUS_POP;
	    AO_fetch_and_add1(&glob_rtsched_runnable_q_pops);
	    AO_fetch_and_sub1(&glob_rtsched_main_task_q_count);
	    nkn_rttask_check_deadline_miss(ntask->task_id);
	    return (ntask);
	default:
	    return NULL;
    }
    return NULL;
}
Exemple #3
0
static inline int traces_obtain_log_line_number(void)
{
	int linenum;

	while (1) {
		/* wait for buffer to be emptied */
		while (AO_load(&traces->logcnt) > LAST_LOGLINE);

		while (AO_test_and_set(&traces->lock) == AO_TS_SET);
		
		/* new line will be used! */
		AO_fetch_and_add1(&traces->usecnt);
		
		/* get log line number */
		linenum = AO_fetch_and_add1(&traces->logcnt);

		AO_CLEAR(&traces->lock);

		/* line number with valid properties has been acquired so leave */
		if (linenum <= LAST_LOGLINE)
			break;
		
		/* release non-existing line number */
		AO_fetch_and_sub1(&traces->usecnt);
	}
	
	DEBUG("linenum = %d", linenum);

	/* linenum is storing now a unique number n, such as 0 <= n <= LAST_LOGLINE */
	return linenum;
}
Exemple #4
0
static void traces_release_log_line(traces_log_t *logline)
{
	if (traces) {
		AO_fetch_and_sub1(&traces->usecnt);

		DEBUG("released %p", logline);
	}
}
static int diameter_object_release(diameter_object_type_t type, void *p)
{
	unsigned int *refcount;

	switch(type) {
	case DIAMETER_TYPE_INCOMING_REQ_CTX:
		AO_fetch_and_sub1(&glob_dia_obj_req_ctx_cnt);
		break;
	case DIAMETER_TYPE_PEER_EVENT:
		AO_fetch_and_sub1(&glob_dia_obj_peer_event_cnt);
		break;
	case DIAMETER_TYPE_PEER:
		AO_fetch_and_sub1(&glob_dia_obj_peer_cnt);
		break;
	case DIAMETER_TYPE_PEER_CONNECTION:
		AO_fetch_and_sub1(&glob_dia_obj_peer_connection_cnt);
		break;
	case DIAMETER_TYPE_PEERGROUP:
		AO_fetch_and_sub1(&glob_dia_obj_peergroup_cnt);
		break;
	case DIAMETER_TYPE_SERVER:
		AO_fetch_and_sub1(&glob_dia_obj_server_cnt);
		break;
	default:
		AO_fetch_and_sub1(&glob_dia_obj_unknown_cnt);
		break;
	}

	refcount = (unsigned int *)p - 1;
	return (AO_int_fetch_and_sub1(refcount) - 1);
}
static uint32_t diameter_object_free(diameter_object_type_t type, void *p)
{
	unsigned int *refcount;

	if (p == NULL)
		return DIAMETER_CB_ERROR;
	refcount = (unsigned int *)p - 1;
	free(refcount);

	switch(type) {
	case DIAMETER_TYPE_INCOMING_REQ_CTX:
		AO_fetch_and_sub1(&glob_dia_obj_req_ctx);
		break;
	case DIAMETER_TYPE_PEER_EVENT:
		AO_fetch_and_sub1(&glob_dia_obj_peer_event);
		break;
	case DIAMETER_TYPE_PEER:
		AO_fetch_and_sub1(&glob_dia_obj_peer);
		break;
	case DIAMETER_TYPE_PEER_CONNECTION:
		AO_fetch_and_sub1(&glob_dia_obj_peer_connection);
		break;
	case DIAMETER_TYPE_PEERGROUP:
		AO_fetch_and_sub1(&glob_dia_obj_peergroup);
		break;
	case DIAMETER_TYPE_SERVER:
		AO_fetch_and_sub1(&glob_dia_obj_server);
		break;
	default:
		AO_fetch_and_sub1(&glob_dia_obj_unknown);
		break;
	}

	return DIAMETER_CB_OK;
}
void
dm2_dec_write_cnt_on_cache_dev(dm2_cache_info_t *freespace_ci)
{
    NKN_ASSERT(AO_load(&freespace_ci->ci_update_cnt));
    AO_fetch_and_sub1(&freespace_ci->ci_update_cnt);
#if 0
    DBG_DM2E("dec update cnt: %s %d",
	     freespace_ci->mgmt_name, freespace_ci->ci_update_cnt);
#endif
}	/* dm2_dec_write_cnt_on_cache_dev */
static int vcs_fuse_release(
    const char *path,
    struct fuse_file_info *fi)
{
    nkn_vc_channel_t *ch = (nkn_vc_channel_t *)fi->fh;
    UNUSED_ARGUMENT(path);
    if (ch)
        AO_fetch_and_sub1(&ch->current_open_virt_files_cnt);
    fi->fh = 0;
    return 0;
}
static void delete_nodemap_stat_t(nodemap_stat_t *pstat)
{
    if (pstat) {
        if (pstat->name) {
	    free(pstat->name);
	    pstat->name = NULL;
	}
    	free(pstat);
	AO_fetch_and_sub1(&nodemap_stat_elements);
    }
}
Exemple #10
0
void * add1sub1_thr(void * id)
{
  int me = (int)(AO_PTRDIFF_T)id;

  int i;

  for (i = 0; i < NITERS; ++i)
    if ((me & 1) != 0) {
      (void)AO_fetch_and_sub1(&counter);
    } else {
      (void)AO_fetch_and_add1(&counter);
    }
  return 0;
}
void * add1sub1_thr(void * id)
{
  int me = (int)(long)id;

  int i;

  for (i = 0; i < NITERS; ++i)
    if (me & 1)
      AO_fetch_and_sub1(&counter);
    else
      AO_fetch_and_add1(&counter);

  return 0;
}
static void *
mem_slot_get(mem_slot_queue_t *pslot,
	     mem_slot_queue_t **base)
{
    struct free_queue *pfreeq;

    if ((base[0]->flags & MEM_SLOT_INIT_DONE) == 0) {
	// don't call init_slot_mem for global pool
	if (*base  != mem_slot_q)
	    init_slot_mem(base);
    }
    // Quick, lock free check
    if (!pslot->freeq) {
#ifdef MEM_DEBUG
	AO_fetch_and_add1(&pslot->miss);
	if (AO_load(&pslot->miss) +
	    AO_load(&pslot->hits) -
	    AO_load(&pslot->free) > AO_load(&pslot->hwm))
	    AO_store(&pslot->hwm, AO_load(&pslot->miss) +
		     AO_load(&pslot->hits) - AO_load(&pslot->free));
#endif
	return NULL;
    }
    SLOT_LOCK(pslot);
    pfreeq = pslot->freeq;
    if (pfreeq != NULL) {
	pslot->freeq = pfreeq->next;
	pslot->tot_buf_in_this_slot --;
	SLOT_UNLOCK(pslot);
#ifdef MEM_DEBUG
	if (AO_load(&pslot->miss) + AO_load(&pslot->hits) -
	    AO_load(&pslot->free) > AO_load(&pslot->hwm))
	    AO_store(&pslot->hwm, AO_load(&pslot->miss) +
		     AO_load(&pslot->hits) - AO_load(&pslot->free));
	AO_fetch_and_add1(&pslot->hits);
	AO_fetch_and_sub1(&pslot->cnt);
#endif
	return (void *)pfreeq;
    }
    SLOT_UNLOCK(pslot);
#ifdef MEM_DEBUG
    AO_fetch_and_add1(&pslot->miss);
#endif
    return NULL;
}
/*
 * This function cleans up HTTP structure and con structure
 * It should be called only once for each socket at the time of socket close time
 */
void close_conn(int fd)
{
	int peer_fd;
	con_t * con = NULL;

	con = (con_t *)gnm[fd].private_data;
        if (!con) { 
	    DBG_LOG(MSG, MOD_PROXYD, "gnm[fd=%d].private_data NULL. returning", fd);
            return ; 
        }
        if (!CHECK_CON_FLAG(con, CONF_CLIENT_SIDE)) {
	    DBG_LOG(MSG, MOD_PROXYD, "gnm[fd=%d]. Svr side socket.", fd);
            return ; 
        }

	peer_fd = con->peer_fd;

	DBG_LOG(MSG, MOD_PROXYD, "fd=%d peer_fd=%d", fd, peer_fd);

	pxy_NM_close_socket(fd);
	pxy_NM_close_socket(peer_fd);

	AO_fetch_and_sub1(&glob_pxy_cur_open_sockets);
}
/*getFreeBuffer: gets a free attribute buffer for use
 * also handles eviction in case the new buffer to be allocated was in use
*/
nkn_buf_t * getFreeBuffer()
{
	int index = 0,i;
	int64_t worst_cost,temp_cost;
	nkn_buf_t * buf = NULL, *temp =NULL;


    //=====================================================================//

    //get the first buffer available from the hotness buckets
    for(i = 0; i< HOTNESS_LEVELS; i++) {

	if(!TAILQ_EMPTY(&bufferpool_queues[i])) {
	    buf = TAILQ_FIRST(&bufferpool_queues[i]);
	    index = i;
	    break;
	}
    }

    assert(buf); //buf shouldnt be NULL;

    worst_cost = (buf->use * LRUSCALE) -
	((AO_load(&nkn_cur_ts) - buf->use_ts)/DELAY_GRANULARITY);
     for(i = 0; i< HOTNESS_LEVELS; i++) {

	 if (!TAILQ_EMPTY(&bufferpool_queues[i])) {

	    temp = TAILQ_FIRST(&bufferpool_queues[i]);
	    temp_cost = (temp->use * LRUSCALE) -
		((AO_load(&nkn_cur_ts) - temp->use_ts)/DELAY_GRANULARITY);
	    if (temp_cost < worst_cost) {
		worst_cost = temp_cost;
		index = i;

	    }


	}
     }

    buf = NULL;
    buf = TAILQ_FIRST(&bufferpool_queues[index]);
    TAILQ_REMOVE(&bufferpool_queues[index],buf,bufferpoolentry);

    assert(buf->ref == 0);

    if (buf->uri_name != NULL) {
	//if the buffer is in use, evict it!
	g_hash_table_remove(uri_hash_table,buf->uri_name);
	total_bytes_in_ram -= buf->length;

	//dec refcount for buf->attribute buffer since evicting;;
	AO_fetch_and_sub1(&((buf->attrbuf)->ref));
	(buf->attrbuf)->buffer_count--;

	//if((buf->attrbuf)->ref < 0)
	assert((AO_load(&((buf->attrbuf)->ref)) >= 0));
	//printf("attrib buff ref count < 0\n");
	assert((AO_load(&((buf->attrbuf)->ref))) <1800000);

	free(buf->uri_name);

        if((AO_load(&((buf->attrbuf)->ref))) == 0) {

	    calculateHotnessBucket(buf->attrbuf);

	}
	//derefbuffer(buf->attrbuf);
	makeBufferAvailable(buf);
	TAILQ_REMOVE(&bufferpool_queues[buf->flist],buf,bufferpoolentry);
    }

    return buf;

}
int
ns_stat_free_stat_token(ns_stat_token_t ns_stoken)
{
    ns_stat_entry_t *ns;
    char     *key;
    int64_t  old_refcnt, keyhash;
    uint32_t ns_index = NS_STAT_TOKEN_IDX(ns_stoken);
    uint32_t gen = NS_STAT_TOKEN_GEN(ns_stoken);
    uint32_t curr_gen;
    int      free_ns = 0;

    if (ns_is_stat_token_null(ns_stoken)) {
        glob_ns_stat_free_null_token_err++;
        return 0;
    }

    key = ns_slot_info[ns_index]->ns_key;
    keyhash = n_str_hash(key);

    NS_HASH_RLOCK();
    ns = nhash_lookup(s_ns_stat_hash, keyhash, key);
    if (ns == NULL || ns->state == NS_STATE_DELETED) {
        /* We should always find the namespace stat object */
        NKN_ASSERT(0);
        NS_HASH_RUNLOCK();
        return ENOENT;
    }
    curr_gen = (uint32_t) AO_load(&ns_token_gen[ns_index]);
    old_refcnt = AO_fetch_and_sub1(&s_ns_stat_refcnt[ns_index]);
    assert(old_refcnt >= 1);
    if (ns->state == NS_STATE_TO_BE_DELETED) {
        /* Delete on last free */
        NKN_ASSERT(curr_gen == gen+1);
        if (curr_gen != gen+1)
            glob_ns_stat_freedel_gen_mismatch_err++;
        if (old_refcnt == 1)
            free_ns = 1;
        assert(old_refcnt != 0);	// Extra free called
        glob_ns_stat_freedel_cnt++;
    } else {
        NKN_ASSERT(curr_gen == gen);
        if (curr_gen != gen)
            glob_ns_stat_free_gen_mismatch_err++;
        glob_ns_stat_free_cnt++;
    }
    NS_HASH_RUNLOCK();

    if (free_ns) {
        NS_HASH_WLOCK(1);
        if (nhash_remove(s_ns_stat_hash, keyhash, key) == 0) {
            /* Object not found */
            DBG_LOG(SEVERE, MOD_NAMESPACE,
                    "Unable to remove namespace stat hash table object: %s",
                    key);
            assert(0);
        }
        ns_stat_delete_counters(ns->ns_key);
        ns->state = NS_STATE_DELETED;
        glob_ns_stat_delete_on_free_cnt++;
        NS_HASH_WUNLOCK(1);
    }
    return 0;
}	/* ns_stat_free_stat_token */
int
ns_stat_del_namespace(const char *ns_uuid)
{
    ns_stat_entry_t *ns;
    int64_t	    keyhash;
    int		    err = 0;

    /* We might get a delete call before the hash table is created and filled */
    if (!s_ns_stat_hash)
        return err;

    keyhash = n_str_hash(ns_uuid);

    NS_HASH_WLOCK(1);
    ns = nhash_lookup(s_ns_stat_hash, keyhash, (void *)ns_uuid /*key*/);
    if (ns == NULL || IS_NS_STATE_DELETING(ns)) {
        if (ns == NULL) {
            DBG_LOG(SEVERE, MOD_NAMESPACE,
                    "Namespace not found: %s", ns_uuid);
            NKN_ASSERT(0);
            glob_ns_stat_delete_not_found_err++;
        } else {
            /* Duplicate delete request */
            DBG_LOG(SEVERE, MOD_NAMESPACE,
                    "Namespace already deleted: %s", ns_uuid);
            NKN_ASSERT(0);
            glob_ns_stat_already_deleted_err++;
        }
        err = ENOENT;
        goto end;
    }
    AO_fetch_and_add1(&ns_token_gen[ns->index]);	// bump generation #

    if (ns->num_dup_ns != 0) {
        /* Duplicate Namespace referring to the stat structure present.
         * Dont delete the stat structure or mark for deletion.
         */
        /* Ref down the count which was incremented during the
         * add_namespace call */
        ns->num_dup_ns--;
        err = 0;
        goto end;
    }

    /* If the refcnt is 0, which means that the stat is no longer used for
     * duplicate inherited namespaces, we can remove it from the hash table
     */

    if (AO_load(&s_ns_stat_refcnt[ns->index]) == 0) {
        if (nhash_remove(s_ns_stat_hash, keyhash, (void *)ns_uuid) == 0) {
            /* Object not found */
            DBG_LOG(SEVERE, MOD_NAMESPACE,
                    "Unable to remove namespace stat hash table object: %s",
                    ns_uuid);
            assert(0);
        }
        ns_stat_delete_counters(ns->ns_key);
        ns->state = NS_STATE_DELETED;
        glob_ns_stat_delete_cnt++;
    } else {
        /* Delete on last free */
        ns->state = NS_STATE_TO_BE_DELETED;
        glob_ns_stat_to_be_deleted_cnt++;
    }
    AO_fetch_and_sub1(&ns_num_namespaces);
end:
    NS_HASH_WUNLOCK(1);
    glob_ns_num_namespaces = AO_load(&ns_num_namespaces);
    return err;
}	/* ns_stat_del_namespace */
/**
 * start the file processing pipeline by doing the following
 * a. adds to a thread pool for processing.
 * @param path - path to the PMF file
 * @return retunrs 0 on success and a negative integer on error 
 */
int32_t mfp_file_start_listener_session(char *path) 
{

    int32_t rv, sess_id;
    mfp_publ_t *pub;

    AO_fetch_and_add1(&glob_mfp_file_tot_conv_sessions);
	
    /* process and cleanup queue element */
    rv = readPublishContextFromFile(path,
				    &pub);
    if (rv) {
	DBG_MFPLOG ("0", ERROR, MOD_MFPFILE, "error parsing PMF file -"
		    " error code: %d" , -rv);
	AO_fetch_and_add1(&glob_mfp_file_tot_err_sessions);
	return rv;
    }

    /* add to the mgmt session map */
    if (pub->src_type != CONTROL_SRC) {
	/* attach the context to a session */
	sess_id = attachPubContextToSessionId(pub);
	if (sess_id < 0) {
	    rv = -E_MFP_INVALID_SESS;
	    DBG_MFPLOG ("0", ERROR, MOD_MFPFILE, "no free session id"
			" (total concurrent sessions possible %d) -"
			" error code: %d", 
			glob_mfp_max_sess_supported, rv);
	    /* no session id, calling the cleanup routine directly */
	    pub->delete_publish_ctx(pub);
	    AO_fetch_and_add1(&glob_mfp_file_tot_err_sessions);
	    return rv;
	}
	rv = mfp_mgmt_sess_tbl_add(sess_id, (char*)pub->name);
	if (rv){
	    rv = -E_MFP_INVALID_SESS;
	    printf("session id collision %d\n, pmf sess id %s", sess_id,
		   pub->name); 
	    DBG_MFPLOG (pub->name, ERROR, MOD_MFPFILE, "session id collision" 
			"error code:  %d", -rv);
	    AO_fetch_and_add1(&glob_mfp_file_num_ses_collision);
	    return rv;
	}
    } else {
	AO_fetch_and_add1(&glob_mfp_file_num_ctrl_sessions);
	AO_fetch_and_sub1(&glob_mfp_file_tot_conv_sessions);
	rv = handleControlPMF(pub, file_state_cont, FILE_SRC);
	pub->delete_publish_ctx(pub);
	return rv;
    }

    AO_fetch_and_add1(&glob_mfp_file_num_active_sessions);

    /* initiate a coversion */
    rv = mfp_convert_pmf(sess_id);

    if ((glob_mfp_fconv_tpool_enable) && (rv >= 0)) {
	    printf("Processing in progress using thread pool\n");
	    return rv;
    }
    // commented temp. till we fix pubSchemes storage url update in xml
    //file_state_cont->remove(file_state_cont, sess_id);
    return rv;
}
/**
 * starts a live listener session. Does this following sequence of
 * operations
 * a. parses the PMF file and creates a publisher context
 * b. generates a valid session id
 * c. starts the listening session using the event handler API's
 * @param path - path to the PMF file
 * @return returns 0 on success, -ve integer on error
 */
static void mfp_live_start_listener_session(void *data)
{
    int32_t *rv;
    mfp_publ_t *pub;
    int32_t sess_id;
    mgmt_sess_state_t *sess_obj = NULL;
    mfp_live_sess_mgr_cont_t *smc;

    smc = (mfp_live_sess_mgr_cont_t*)(data);
    rv = &smc->err;
    pub = smc->pub;

    /* add to the mgmt session map */
    if (pub->src_type != CONTROL_SRC) {

	/* attach the pub context to a global session
	 * id
	 */
	sess_id = attachPubContextToSessionId(pub);
	if (sess_id < 0) {
	    *rv = -E_MFP_INVALID_SESS;
	    DBG_MFPLOG ("0", ERROR, MOD_MFPLIVE, "no free session id"
		    " (total concurrent sessions possible %ld) -"
		    " error code: %d" ,
		    glob_mfp_max_sess_supported, *rv);
	    /* no session id, calling the cleanup routine directly */
	    pub->delete_publish_ctx(pub);
	    AO_fetch_and_add1(&glob_mfp_live_tot_err_sessions);
	    free(smc);
	    return;
	}
	sess_obj = mfp_mgmt_sess_tbl_acq((char *)pub->name);
	/**
	 * SCTE DEMO: if there is an existing sess obj for a session
	 * name and the session is not active then we will attach it
	 * to a new session id. Previously we used to return a session
	 * id collision error at this point
	 */
	if (sess_obj) {
	    if (sess_obj->status == PUB_SESS_STATE_REMOVE) {
		mfp_mgmt_sess_replace(sess_obj, sess_id);
	    } else {
		*rv = -E_MFP_INVALID_SESS;
		DBG_MFPLOG (pub->name, ERROR, MOD_MFPLIVE, "Session ID"
			" Collision");
		AO_fetch_and_add1(&glob_mfp_live_num_ses_collision);
		mfp_mgmt_sess_tbl_rel((char *)pub->name);
		free(smc);
		return;
	    }
	    mfp_mgmt_sess_tbl_rel((char *)pub->name);
	} else {
	    mfp_mgmt_sess_tbl_add(sess_id, (char*)pub->name);
	}
    } else {
	AO_fetch_and_add1(&glob_mfp_live_num_ctrl_sessions);
	AO_fetch_and_sub1(&glob_mfp_live_tot_sessions);
	*rv = handleControlPMF(pub, live_state_cont, LIVE_SRC);
	pub->delete_publish_ctx(pub);
	free(smc);
	return;
    }

    /* initialize the session pipeline */
    AO_fetch_and_add1(&glob_mfp_live_num_active_sessions);
    *rv = initSessionPipeline(sess_id);
    if (*rv < 0) {
	DBG_MFPLOG (pub->name, ERROR, MOD_MFPLIVE, "Unable to initialize"
		" session pipeline - error code: %d" ,
		*rv);
	mfp_mgmt_sess_unlink((char*)pub->name, PUB_SESS_STATE_REMOVE,
		*rv);
	live_state_cont->remove(live_state_cont, sess_id);
	AO_fetch_and_add1(&glob_mfp_live_tot_err_sessions);
	AO_fetch_and_sub1(&glob_mfp_live_num_active_sessions);
	free(smc);
	return;
    }

    DBG_MFPLOG (pub->name, MSG, MOD_MFPLIVE, "Session Started Succesfully");

    free(smc);
    return;
}