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, ×tamp); 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; }
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; }
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); } }
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; }