void sinsp_table::flush(sinsp_evt* evt) { if(!m_paused) { if(m_next_flush_time_ns != 0) { // // Time to emit the sample! // Add the proctable as a sample at the end of the second // process_proctable(evt); // // If there is a merging step, switch the types to point to the merging ones. // if(m_do_merging) { m_types = &m_postmerge_types; m_table = &m_merge_table; m_n_fields = m_n_postmerge_fields; m_vals_array_sz = m_postmerge_vals_array_sz; m_fld_pointers = m_postmerge_fld_pointers; m_extractors = &m_postmerge_extractors; } // // Emit the sample // create_sample(); if(m_type == sinsp_table::TT_TABLE) { // // Switch the data storage so that the current one is still usable by the // consumers of the table. // switch_buffers(); // // Clear the current data storage // m_buffer->clear(); } // // Reinitialize the tables // m_premerge_table.clear(); m_merge_table.clear(); } } uint64_t ts = evt->get_ts(); m_prev_flush_time_ns = m_next_flush_time_ns; m_next_flush_time_ns = ts - (ts % m_refresh_interval_ns) + m_refresh_interval_ns; return; }
static void audio_resume(void) { playing = true; if(AUDIO_GetDMAEnableFlag()==0) { switch_buffers(); AUDIO_StartDMA(); } }
/** * locking_finalize: - finalize last buffer at end of channel use * @rchan: the channel */ inline void locking_finalize(struct rchan *rchan) { unsigned long int flags; struct timeval time; u32 tsc; local_irq_save(flags); get_timestamp(&time, &tsc, rchan); switch_buffers(time, tsc, rchan, 1, 0, 0); local_irq_restore(flags); }
void dataLink_process() { u32 i; if(anim_state == ANIM_S_WAIT_EVEN && check_timer(&dataLink_timer)) { // Waiting to light up EVEN for(i=0; i < LEDS; i++) { u32 lidx = i*3; // if( (i % 2) == 0) { pixels[lidx] = ON_COLOR_G; pixels[lidx + 1] = ON_COLOR_R; pixels[lidx + 2] = ON_COLOR_B; // } else { // pixels[lidx] = OFF_COLOR_G; // pixels[lidx + 1] = OFF_COLOR_R; // pixels[lidx + 2] = OFF_COLOR_B; // } } switch_buffers(); start_ms_timer(&dataLink_timer, 1000); anim_state = ANIM_S_WAIT_ODD; } if(anim_state == ANIM_S_WAIT_ODD && check_timer(&dataLink_timer)) { // Waiting to light up ODD for(i=0; i < LEDS; i++) { u32 lidx = i*3; // if( (i % 2) == 0) { pixels[lidx] = OFF_COLOR_G; pixels[lidx + 1] = OFF_COLOR_R; pixels[lidx + 2] = OFF_COLOR_B; // } else { // pixels[lidx] = ON_COLOR_G; // pixels[lidx + 1] = ON_COLOR_R; // pixels[lidx + 2] = ON_COLOR_B; // } } switch_buffers(); start_ms_timer(&dataLink_timer, 1000); anim_state = ANIM_S_WAIT_EVEN; } }
/** * locking_reset_index - atomically set channel index to the beginning * @rchan: the channel * * If this fails, it means that something else just logged something * and therefore we probably no longer want to do this. It's up to the * caller anyway... * * Returns 0 if the index was successfully set, negative otherwise */ int locking_reset_index(struct rchan *rchan, u32 old_idx) { unsigned long flags; struct timeval time; u32 tsc; u32 cur_idx; relay_lock_channel(rchan, flags); cur_idx = locking_get_offset(rchan, NULL); if (cur_idx != old_idx) { relay_unlock_channel(rchan, flags); return -1; } get_timestamp(&time, &tsc, rchan); switch_buffers(time, tsc, rchan, 0, 1, 0); relay_unlock_channel(rchan, flags); return 0; }
static int play(void *data, int remaining, int flags) { int processed = 0; int samples = BUFFER_SIZE / (sizeof(s16) * HW_CHANNELS); s16 *source = (s16 *)data; while (remaining >= request_size && get_space() >= request_size) { copy_channels((s16 *)buffers[buffer_fill], source, samples, processed, remaining); DCStoreRangeNoSync(buffers[buffer_fill], BUFFER_SIZE); buffer_fill = (buffer_fill + 1) % BUFFER_COUNT; processed += request_size; source += request_size / sizeof(s16); buffered += BUFFER_SIZE; remaining -= request_size; } if ((flags & AOPLAY_FINAL_CHUNK) && remaining > 0) { samples = remaining / (sizeof(s16) * HW_CHANNELS); memset(buffers[buffer_fill], 0, BUFFER_SIZE); copy_channels((s16 *)buffers[buffer_fill], source, samples, processed, 0); DCStoreRangeNoSync(buffers[buffer_fill], BUFFER_SIZE); buffer_fill = (buffer_fill + 1) % BUFFER_COUNT; processed += remaining; buffered += BUFFER_SIZE; } if (!playing)// && buffered > request_size) { playing = true; switch_buffers(); AUDIO_StartDMA(); } return processed; }
// // Update the field, showing all sprites in their (new?) positions e.t.c. playfield::update( int redraw ) { /////////////////////////// // build the frontbuffer // /////////////////////////// // with sprites for (int i=0; i < numSprites; i++) { int x1,y1,o1,d1,x2,y2,o2,d2; // find out which positions our sprite will occupy Sprites[i]->get_position ( x1, y1, o1, d1, x2, y2, o2, d2 , maxX-1, maxY-1); // replicate those backtiles, if they aren't allready in the frontbuffer if (frontBuffer[ x1+y1*maxX ]==NULL) frontBuffer[ x1+y1*maxX ] = new tile ( *get_field_position(x1,y1) ); if (frontBuffer[ x2+y2*maxX ]==NULL) frontBuffer[ x2+y2*maxX ] = new tile ( *get_field_position(x2,y2) ); // superimpose the sprite on them.. frontBuffer[ x1+y1*maxX ]->overlay ( *(Sprites[i]->get_crnt_tile()), o1, d1 ); frontBuffer[ x2+y2*maxX ]->overlay ( *(Sprites[i]->get_crnt_tile()), o2, d2 ); } // and changed tiles: for (i=0; i<numLoadedTiles; i++) if (backgroundTiles[i]->is_changed()) for (int x=0; x<maxX; x++) for (int y=0; y<maxY; y++) if (frontBuffer[x+y*maxX]==NULL && field[x+y*maxX] == i) frontBuffer[x+y*maxX] = new tile (*get_field_position(x,y)); // update display : // for each position do : // nothing, if both front and backBuffer are NULL // show background, if only backBuffer != NULL // show front, if frontBuffer is != NULL tile* crnt; int cnt = 0; for (int y=0; y<maxY; y++) for (int x=0; x<maxX; x++, cnt++) { crnt = NULL; if (backBuffer[cnt] || redraw) crnt = backgroundTiles [ field[cnt] ]->get_crnt_tile(); if (frontBuffer[cnt]) crnt = frontBuffer[cnt]; if (crnt) crnt->show ( pixOfsX + x * tileWidth, pixOfsY + (fieldSizeY-y-1) * tileHeight ); } // make the frontbuffer a backbuffer... clean_buffer (backBuffer); switch_buffers(); // you're done! return 0; }
//handle request from HOST <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< //send data to PC static uint8_t usbd_video_DataIn (void *pdev, uint8_t epnum) { static uint16_t packets_cnt = 0xffff; static uint8_t header[2] = {2,0};//length + data uint16_t i; static uint32_t picture_pos; static uint16_t packets_in_frame = 1; static uint16_t last_packet_size = 0; uint8_t packet[VIDEO_PACKET_SIZE]; static uint8_t tx_enable_flag = 0;//разрешение передачи DCD_EP_Flush(pdev,USB_ENDPOINT_IN(1));//very important if (tx_enable_flag) packets_cnt++; if (tx_enable_flag == 0)//если передача закончилась//if previous transmission ended { if (jpeg_encode_done)//если кодирование закончилось//if frame endoding ended { tx_enable_flag = 1; switch_buffers();//переключить буферы для двойной буферизации//switch double buffering buffers new_frame_cap_enabled = 1;//начать новый захват кадра//start new frame capture //start of new UVC frame //начало нового кадра UVC packets_cnt = 0; header[1]^= 1;//toggle bit0 every new frame picture_pos = 0; packets_in_frame = (last_jpeg_frame_size/ ((uint16_t)VIDEO_PACKET_SIZE -2))+1;//-2 - без учета заголовка last_packet_size = (last_jpeg_frame_size - ((packets_in_frame-1) * ((uint16_t)VIDEO_PACKET_SIZE-2)) + 2);//+2 - учитывая заголовок } } packet[0] = header[0]; packet[1] = header[1]; //fill payload buffer for (i=2;i<VIDEO_PACKET_SIZE;i++) { packet[i] = read_pointer[picture_pos]; picture_pos++; } if (play_status == 2) { if (packets_cnt< (packets_in_frame - 1)) { DCD_EP_Tx (pdev,USB_ENDPOINT_IN(1), (uint8_t*)&packet, (uint32_t)VIDEO_PACKET_SIZE); } else if (tx_enable_flag == 1)//только если передача разрешена//only if transmisson enabled { //last packet in UVC frame //последний пакет в кадре UVC DCD_EP_Tx (pdev,USB_ENDPOINT_IN(1), (uint8_t*)&packet, (uint32_t)last_packet_size); tx_enable_flag = 0;//stop TX data } else { DCD_EP_Tx (pdev,USB_ENDPOINT_IN(1), (uint8_t*)&header, 2);//header only picture_pos = 0; } } else { packets_cnt = 0xffff; picture_pos = 0; } //STM_EVAL_LEDToggle(LED6); return USBD_OK; }
/** * locking_reserve - reserve a slot in the buffer for an event. * @rchan: the channel * @slot_len: the length of the slot to reserve * @ts: variable that will receive the time the slot was reserved * @tsc: the timestamp counter associated with time * @err: receives the result flags * @interrupting: if this write is interrupting another, set to non-zero * * Returns pointer to the beginning of the reserved slot, NULL if error. * * The err value contains the result flags and is an ORed combination * of the following: * * RELAY_BUFFER_SWITCH_NONE - no buffer switch occurred * RELAY_EVENT_DISCARD_NONE - event should not be discarded * RELAY_BUFFER_SWITCH - buffer switch occurred * RELAY_EVENT_DISCARD - event should be discarded (all buffers are full) * RELAY_EVENT_TOO_LONG - event won't fit into even an empty buffer */ inline char * locking_reserve(struct rchan *rchan, u32 slot_len, struct timeval *ts, u32 *tsc, int *err, int *interrupting) { u32 buffers_ready; int bytes_written; *err = RELAY_BUFFER_SWITCH_NONE; if (slot_len >= rchan->buf_size) { *err = RELAY_WRITE_DISCARD | RELAY_WRITE_TOO_LONG; return NULL; } if (rchan->initialized == 0) { rchan->initialized = 1; get_timestamp(&rchan->buf_start_time, &rchan->buf_start_tsc, rchan); rchan->unused_bytes[0] = 0; bytes_written = rchan->callbacks->buffer_start( rchan->id, cur_write_pos(rchan), rchan->buf_id, rchan->buf_start_time, rchan->buf_start_tsc, using_tsc(rchan)); cur_write_pos(rchan) += bytes_written; *tsc = get_time_delta(ts, rchan); return cur_write_pos(rchan); } *tsc = get_time_delta(ts, rchan); if (in_progress_event_size(rchan)) { interrupted_pos(rchan) = cur_write_pos(rchan); cur_write_pos(rchan) = in_progress_event_pos(rchan) + in_progress_event_size(rchan) + interrupting_size(rchan); *interrupting = 1; } else { in_progress_event_pos(rchan) = cur_write_pos(rchan); in_progress_event_size(rchan) = slot_len; interrupting_size(rchan) = 0; } if (cur_write_pos(rchan) + slot_len > write_limit(rchan)) { if (atomic_read(&rchan->suspended) == 1) { in_progress_event_pos(rchan) = NULL; in_progress_event_size(rchan) = 0; interrupting_size(rchan) = 0; *err = RELAY_WRITE_DISCARD; return NULL; } buffers_ready = rchan->bufs_produced - rchan->bufs_consumed; if (buffers_ready == rchan->n_bufs - 1) { if (!mode_continuous(rchan)) { atomic_set(&rchan->suspended, 1); in_progress_event_pos(rchan) = NULL; in_progress_event_size(rchan) = 0; interrupting_size(rchan) = 0; get_timestamp(ts, tsc, rchan); switch_buffers(*ts, *tsc, rchan, 0, 0, 1); recalc_time_delta(ts, tsc, rchan); rchan->half_switch = 1; cur_write_pos(rchan) = write_buf_end(rchan) - 1; *err = RELAY_BUFFER_SWITCH | RELAY_WRITE_DISCARD; return NULL; } } get_timestamp(ts, tsc, rchan); switch_buffers(*ts, *tsc, rchan, 0, 0, 0); recalc_time_delta(ts, tsc, rchan); *err = RELAY_BUFFER_SWITCH; } return cur_write_pos(rchan); }