static int snd_pcm_shm_new_rbptr(snd_pcm_t *pcm, snd_pcm_shm_t *shm, snd_pcm_rbptr_t *rbptr, volatile snd_pcm_shm_rbptr_t *shm_rbptr) { if (!shm_rbptr->use_mmap) { if (&pcm->hw == rbptr) snd_pcm_set_hw_ptr(pcm, &shm_rbptr->ptr, -1, 0); else snd_pcm_set_appl_ptr(pcm, &shm_rbptr->ptr, -1, 0); } else { void *ptr; size_t mmap_size, mmap_offset, offset; int fd; long result; shm->ctrl->cmd = &pcm->hw == rbptr ? SND_PCM_IOCTL_HW_PTR_FD : SND_PCM_IOCTL_APPL_PTR_FD; result = snd_pcm_shm_action_fd0(pcm, &fd); if (result < 0) return result; mmap_size = page_ptr(shm_rbptr->offset, sizeof(snd_pcm_uframes_t), &offset, &mmap_offset); ptr = mmap(NULL, mmap_size, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, mmap_offset); if (ptr == MAP_FAILED || ptr == NULL) { SYSERR("shm rbptr mmap failed"); return -errno; } if (&pcm->hw == rbptr) snd_pcm_set_hw_ptr(pcm, (snd_pcm_uframes_t *)((char *)ptr + offset), fd, shm_rbptr->offset); else snd_pcm_set_appl_ptr(pcm, (snd_pcm_uframes_t *)((char *)ptr + offset), fd, shm_rbptr->offset); } return 0; }
bin_index_t::page_ptr bin_index_t::file_node::create_page() const { return page_ptr(new page_t(aligned_key_len,parent.page_max_size)); }
void Restore::restore_next(Signal* signal, FilePtr file_ptr) { Uint32 *data, len= 0; Uint32 status = file_ptr.p->m_status; Uint32 page_count = file_ptr.p->m_pages.getSize(); do { Uint32 left= file_ptr.p->m_bytes_left; if (left < 8) { jam(); /** * Not enough bytes to read header */ break; } Ptr<GlobalPage> page_ptr(0,0), next_page_ptr(0,0); m_global_page_pool.getPtr(page_ptr, file_ptr.p->m_current_page_ptr_i); List::Iterator it; Uint32 pos= file_ptr.p->m_current_page_pos; if(status & File::READING_RECORDS) { jam(); /** * We are reading records */ len= ntohl(* (page_ptr.p->data + pos)) + 1; ndbrequire(len < GLOBAL_PAGE_SIZE_WORDS); } else { jam(); /** * Section length is in 2 word */ if(pos + 1 == GLOBAL_PAGE_SIZE_WORDS) { jam(); /** * But that's stored on next page... * and since we have atleast 8 bytes left in buffer * we can be sure that that's in buffer */ LocalDataBuffer<15> pages(m_databuffer_pool, file_ptr.p->m_pages); Uint32 next_page = file_ptr.p->m_current_page_index + 1; pages.position(it, next_page % page_count); m_global_page_pool.getPtr(next_page_ptr, * it.data); len= ntohl(* next_page_ptr.p->data); } else { jam(); len= ntohl(* (page_ptr.p->data + pos + 1)); } } if (file_ptr.p->m_status & File::FIRST_READ) { jam(); len= 3; file_ptr.p->m_status &= ~(Uint32)File::FIRST_READ; } if (4 * len > left) { jam(); /** * Not enought bytes to read "record" */ if (unlikely((status & File:: FILE_THREAD_RUNNING) == 0)) { crash_during_restore(file_ptr, __LINE__, 0); } len= 0; break; } /** * Entire record is in buffer */ if(pos + len >= GLOBAL_PAGE_SIZE_WORDS) { jam(); /** * But it's split over pages */ if(next_page_ptr.p == 0) { LocalDataBuffer<15> pages(m_databuffer_pool, file_ptr.p->m_pages); Uint32 next_page = file_ptr.p->m_current_page_index + 1; pages.position(it, next_page % page_count); m_global_page_pool.getPtr(next_page_ptr, * it.data); } file_ptr.p->m_current_page_ptr_i = next_page_ptr.i; file_ptr.p->m_current_page_pos = (pos + len) - GLOBAL_PAGE_SIZE_WORDS; file_ptr.p->m_current_page_index = (file_ptr.p->m_current_page_index + 1) % page_count; if (len <= GLOBAL_PAGE_SIZE_WORDS) { jam(); Uint32 first = (GLOBAL_PAGE_SIZE_WORDS - pos); // wl4391_todo removing valgrind overlap warning for now memmove(page_ptr.p, page_ptr.p->data+pos, 4 * first); memcpy(page_ptr.p->data+first, next_page_ptr.p, 4 * (len - first)); data= page_ptr.p->data; } else { jam(); /** * A table definition can be larger than one page... * when that happens copy it out to side buffer * * First copy part belonging to page_ptr * Then copy full middle pages (moving forward in page-list) * Last copy last part */ Uint32 save = len; assert(len <= NDB_ARRAY_SIZE(m_table_buf)); Uint32 * dst = m_table_buf; /** * First */ Uint32 first = (GLOBAL_PAGE_SIZE_WORDS - pos); memcpy(dst, page_ptr.p->data+pos, 4 * first); len -= first; dst += first; /** * Middle */ while (len > GLOBAL_PAGE_SIZE_WORDS) { jam(); memcpy(dst, next_page_ptr.p, 4 * GLOBAL_PAGE_SIZE_WORDS); len -= GLOBAL_PAGE_SIZE_WORDS; dst += GLOBAL_PAGE_SIZE_WORDS; { LocalDataBuffer<15> pages(m_databuffer_pool, file_ptr.p->m_pages); Uint32 next_page = (file_ptr.p->m_current_page_index + 1) % page_count; pages.position(it, next_page % page_count); m_global_page_pool.getPtr(next_page_ptr, * it.data); file_ptr.p->m_current_page_ptr_i = next_page_ptr.i; file_ptr.p->m_current_page_index = next_page; } } /** * last */ memcpy(dst, next_page_ptr.p, 4 * len); file_ptr.p->m_current_page_pos = len; /** * Set pointer and len */ len = save; data = m_table_buf; } } else { file_ptr.p->m_current_page_pos = pos + len; data= page_ptr.p->data+pos; } file_ptr.p->m_bytes_left -= 4*len; if(status & File::READING_RECORDS) { if(len == 1) { file_ptr.p->m_status = status & ~(Uint32)File::READING_RECORDS; } else { parse_record(signal, file_ptr, data, len); } } else { switch(ntohl(* data)){ case BackupFormat::FILE_HEADER: parse_file_header(signal, file_ptr, data-3, len+3); break; case BackupFormat::FRAGMENT_HEADER: file_ptr.p->m_status = status | File::READING_RECORDS; parse_fragment_header(signal, file_ptr, data, len); break; case BackupFormat::FRAGMENT_FOOTER: parse_fragment_footer(signal, file_ptr, data, len); break; case BackupFormat::TABLE_LIST: parse_table_list(signal, file_ptr, data, len); break; case BackupFormat::TABLE_DESCRIPTION: parse_table_description(signal, file_ptr, data, len); break; case BackupFormat::GCP_ENTRY: parse_gcp_entry(signal, file_ptr, data, len); break; case BackupFormat::EMPTY_ENTRY: // skip break; case 0x4e444242: // 'NDBB' if (check_file_version(signal, ntohl(* (data+2))) == 0) { break; } default: parse_error(signal, file_ptr, __LINE__, ntohl(* data)); } } } while(0); if(file_ptr.p->m_bytes_left == 0 && status & File::FILE_EOF) { file_ptr.p->m_status &= ~(Uint32)File::RESTORE_THREAD_RUNNING; /** * File is finished... */ close_file(signal, file_ptr); return; } /** * We send an immediate signal to continue the restore, at times this * could lead to burning some extra CPU since we might still wait for * input from the disk reading. This code is however only executed * as part of restarts, so it should be ok to spend some extra CPU * to ensure that restarts are quick. */ signal->theData[0] = RestoreContinueB::RESTORE_NEXT; signal->theData[1] = file_ptr.i; sendSignal(reference(), GSN_CONTINUEB, signal, 2, JBB); }