void check_counts(int oversubscribed) { // First pass to snapshot the current counts for (unsigned int i = 0; i < MAX_NUM_STREAMS; i++) { stream_state[i].active = ((stream_state[i].last_count != 0) && (stream_state[i].count != 0)); stream_state[i].last_count = stream_state[i].snapshot; // Ensure the read/modify of count is atomic hwlock_acquire(lock); stream_state[i].snapshot = stream_state[i].count; stream_state[i].count = 0; hwlock_release(lock); } // Second pass to do the checking and printing for (unsigned int i = 0; i < MAX_NUM_STREAMS; i++) { if (stream_state[i].id.low || stream_state[i].id.high) { if (stream_state[i].snapshot == 0) { debug_printf("Removing stream 0x%x%x\n", stream_state[i].id.high, stream_state[i].id.low); hwlock_acquire(lock); stream_state[i].id.high = 0; stream_state[i].id.low = 0; hwlock_release(lock); } else { unsigned int expected_rate = CLASS_A_PACKETS_PER_SEC; if (oversubscribed) { // When the stream is oversubscribed then there will be an extra byte // of bandwidth allocated per packet. const unsigned int preamble_bytes = 8; const unsigned int ifg_bytes = 96/8; // InterFrameGap = 96 bit-times // The one extra byte is for the entire frame (data + preamble + IFG) unsigned int num_bytes = stream_state[i].packet_num_bytes + preamble_bytes + ifg_bytes; expected_rate = expected_rate * (num_bytes + 1) / num_bytes; } // Need to check the value of last_count because otherwise there are // spurious errors when the stream is stopping. if (stream_state[i].active && (stream_state[i].last_count < (expected_rate - ERROR_MARGIN) || stream_state[i].last_count > (expected_rate + ERROR_MARGIN))) { debug_printf("ERROR: 0x%x%x %d\n", stream_state[i].id.high, stream_state[i].id.low, stream_state[i].last_count); } } } } }
void media_input_fifo_update_enable_ind_state(unsigned int enable, unsigned int mask) { if (!enable_lock) return; hwlock_acquire(enable_lock); enable_indication_state = (enable_indication_state & ~mask) | enable; hwlock_release(enable_lock); }
void media_input_fifo_disable_fifos(unsigned int enable) { if (!enable_lock) return; hwlock_acquire(enable_lock); enable_request_state &= ~enable; hwlock_release(enable_lock); }
void avb_1722_router_table_add_or_update_forwarding_simple(int key0, int key1, int f0rward) { hwlock_acquire(table_lock); for(int i=0;i<AVB_MAX_NUM_SINK_AND_FORWARD_STREAMS;i++) { if (key0 == router_table[i].id[0] && key1 == router_table[i].id[1]) { router_table[i].f0rward = f0rward; hwlock_release(table_lock); return; } } // Add a new entry for(int i=0;i<AVB_MAX_NUM_SINK_AND_FORWARD_STREAMS;i++) { if (router_table[i].id[0] == 0) { router_table[i].f0rward = f0rward; router_table[i].link = -1; router_table[i].avb_hash = -1; router_table[i].id[0] = key0; router_table[i].id[1] = key1; break; } } hwlock_release(table_lock); }
int avb_1722_router_table_lookup_simple(int key0, int key1, int *link, int *avb_hash, int *f0rward) { if (key0==0 && key1==0) { return 0; } hwlock_acquire(table_lock); for(int i=0;i<AVB_MAX_NUM_SINK_AND_FORWARD_STREAMS;i++) { __asm__(".xtaloop " STRINGIFY(AVB_MAX_NUM_SINK_AND_FORWARD_STREAMS) "\n"); if (key0 == router_table[i].id[0] && key1 == router_table[i].id[1]) { *avb_hash = router_table[i].avb_hash; *f0rward = router_table[i].f0rward; *link = router_table[i].link; hwlock_release(table_lock); return 1; } } hwlock_release(table_lock); return 0; }
void avb_1722_router_table_add_or_update_entry_simple(int key0, int key1, int link, int avb_hash) { hwlock_acquire(table_lock); for(int i=0;i<AVB_MAX_NUM_SINK_AND_FORWARD_STREAMS;i++) { if (key0 == router_table[i].id[0] && key1 == router_table[i].id[1]) { // Found an existing entry with this stream ID, update it router_table[i].link = link; router_table[i].avb_hash = avb_hash; hwlock_release(table_lock); return; } } // Add a new entry for(int i=0;i<AVB_MAX_NUM_SINK_AND_FORWARD_STREAMS;i++) { if (router_table[i].id[0] == 0) { router_table[i].f0rward = 0; router_table[i].link = link; router_table[i].avb_hash = avb_hash; router_table[i].id[0] = key0; router_table[i].id[1] = key1; break; } } hwlock_release(table_lock); return; }
int avb_1722_router_table_lookup_hash(int key0, int key1, unsigned int *link, unsigned int *avb_hash) { unsigned int x; if (key0==0 && key1==0) return 0; hwlock_acquire(table_lock); x = hash(key0, key1, router_table_poly[0]); if (key0 == router_table[x].id[0] && key1 == router_table[x].id[1]) { *link = router_table[x].link; *avb_hash = router_table[x].avb_hash; hwlock_release(table_lock); return 1; } x = hash(key0, key1, router_table_poly[1]); if (key0 == router_table[x].id[0] && key1 == router_table[x].id[1]) { *link = router_table[x].link; *avb_hash = router_table[x].avb_hash; hwlock_release(table_lock); return 1; } hwlock_release(table_lock); return 0; }
void avb_1722_router_table_add_entry_hash(int key0, int key1, int link, int avb_hash) { int success = 0; while (!success) { success = insert(key0, key1, link, avb_hash); if (success) { avb_1722_router_table_entry_t *old_table = router_table; // flip the tables hwlock_acquire(table_lock); router_table = backup_table; router_table_poly[0] = backup_table_poly[0]; router_table_poly[1] = backup_table_poly[1]; hwlock_release(table_lock); backup_table = old_table; // make sure both tables contain the same memcpy(backup_table, router_table, sizeof(router_table0)); } else { // refill table with a different hash and try again refill_backup_table(); } } }
static void increment_count(const stream_id_t *id, unsigned int packet_num_bytes) { unsigned int free_index = MAX_NUM_STREAMS; hwlock_acquire(lock); for (unsigned int i = 0; i < MAX_NUM_STREAMS; i++) { if ((id->low == stream_state[i].id.low) && (id->high == stream_state[i].id.high)) { stream_state[i].count++; if (stream_state[i].packet_num_bytes != packet_num_bytes) { debug_printf("ERROR stream 0x%x%x packet size changed from %d to %d\n", stream_state[i].id.high, stream_state[i].id.low, stream_state[i].packet_num_bytes, packet_num_bytes); } goto increment_count_done; } else if ((stream_state[i].id.low == 0) && (stream_state[i].id.high == 0)) { free_index = i; } } if (free_index != MAX_NUM_STREAMS) { stream_state[free_index].id.low = id->low; stream_state[free_index].id.high = id->high; stream_state[free_index].count = 1; stream_state[free_index].snapshot = 0; stream_state[free_index].packet_num_bytes = packet_num_bytes; debug_printf("Adding stream 0x%x%x\n", stream_state[free_index].id.high, stream_state[free_index].id.low); } else { assert(0); // Can't track this stream - no free slots available } increment_count_done: hwlock_release(lock); }
void avb_1722_router_table_add_entry_simple(int key0, int key1, int link, int sink_num) { hwlock_acquire(table_lock); router_table[sink_num].id[0] = key0; router_table[sink_num].id[1] = key1; router_table[sink_num].link = link; hwlock_release(table_lock); return; }
void avb_1722_router_table_remove_entry_simple(int key0, int key1) { hwlock_acquire(table_lock); for(int i=0;i<AVB_MAX_NUM_SINK_AND_FORWARD_STREAMS;i++) { if (key0 == router_table[i].id[0] && key1 == router_table[i].id[1]) { router_table[i].id[0] = 0; router_table[i].id[1] = 0; // FIXME: Zero the whole entry! hwlock_release(table_lock); return; } } hwlock_release(table_lock); }
int avb_1722_router_table_lookup_simple(int key0, int key1, unsigned int *link, unsigned int *sink_num) { if (key0==0 && key1==0) return 0; hwlock_acquire(table_lock); for(int i=0;i<AVB_NUM_SINKS;i++) { __asm__(".xtaloop " STRINGIFY(AVB_NUM_SINKS) "\n"); if (key0 == router_table[i].id[0] && key1 == router_table[i].id[1]) { *sink_num = i; *link = router_table[i].link; hwlock_release(table_lock); return 1; } } hwlock_release(table_lock); return 0; }
void acquire_lock(void) // Acquire Hardware lock (MutEx) { hwlock_acquire(hwlock); } // acquiree_lock