RU64
    rInterlocked_set64
    (
        volatile RU64* pRu64,
        RU64 value
    )
{
#ifdef RPAL_PLATFORM_WINDOWS
    return InterlockedExchange64( (LONG64*)pRu64, value );
#elif defined( RPAL_PLATFORM_LINUX ) || defined( RPAL_PLATFORM_MACOSX )
    return __sync_lock_test_and_set( pRu64, value );
#endif
}
Exemplo n.º 2
0
VOID
NTAPI
MmDeleteVirtualMapping(
    PEPROCESS Process,
    PVOID Address,
    BOOLEAN FreePage,
    BOOLEAN* WasDirty,
    PPFN_NUMBER Page)
{
    PFN_NUMBER Pfn;
    PMMPTE Pte;
    MMPTE OldPte;

    Pte = MiGetPteForProcess(Process, Address, FALSE);

    if (Pte)
    {
        /* Atomically set the entry to zero and get the old value. */
        OldPte.u.Long = InterlockedExchange64((LONG64*)&Pte->u.Long, 0);

        if (OldPte.u.Hard.Valid)
        {
            Pfn = OldPte.u.Hard.PageFrameNumber;

            //if (FreePage)
                //MmReleasePageMemoryConsumer(MC_NPPOOL, Pfn);
        }
        else
            Pfn = 0;
    }
    else
    {
        OldPte.u.Long = 0;
        Pfn = 0;
    }

    /* Return information to the caller */
    if (WasDirty)
        *WasDirty = (BOOLEAN)OldPte.u.Hard.Dirty;;

    if (Page)
        *Page = Pfn;

    MiFlushTlb(Pte, Address);
}
Exemplo n.º 3
0
__host__ __device__
typename enable_if<
  sizeof(Integer64) == 8
>::type
atomic_store(Integer64 *x, Integer64 y)
{
#if defined(__CUDA_ARCH__)
  atomicExch(x, y);
#elif defined(__GNUC__)
  return __atomic_store_n(x, y, __ATOMIC_SEQ_CST);
#elif defined(_MSC_VER)
  InterlockedExchange64(x, y); 
#elif defined(__clang__)
  __c11_atomic_store(x, y);
#else
#error "No atomic_store_n implementation."
#endif
}
Exemplo n.º 4
0
void *mempool_node_get(mempool p)
{
    struct node *node;
    int64 num_used;

    if(p->num_nodes_free < p->elem_realloc_thresh)
        racond_signal(l_async_cond);

    while(1) {

        EnterSpinLock(&p->nodeLock);

        node = p->free_list;
        if(node != NULL)
            p->free_list = node->next;

        LeaveSpinLock(&p->nodeLock);

        if(node != NULL)
            break;

        rathread_yield();
    }

    InterlockedDecrement64(&p->num_nodes_free);

    // Update peak value
    num_used = (p->num_nodes_total - p->num_nodes_free);
    if(num_used > p->peak_nodes_used) {
        InterlockedExchange64(&p->peak_nodes_used, num_used);
    }

#ifdef MEMPOOLASSERT
    node->used = true;
#endif

    return NODE_TO_DATA(node);
}//end: mempool_node_get()
Exemplo n.º 5
0
void mempool_destroy(mempool p)
{
    struct  pool_segment *seg, *segnext;
    struct  node *niter;
    mempool piter, pprev;
    char *ptr;
    int64 i;

#ifdef MEMPOOL_DEBUG
    ShowDebug(read_message("Source.common.mempool_debug4"), p->name);
#endif

    // Unlink from global list.
    EnterSpinLock(&l_mempoolListLock);
    piter = l_mempoolList;
    pprev = l_mempoolList;
    while(1) {
        if(piter == NULL)
            break;


        if(piter == p) {
            // unlink from list,
            //
            if(pprev == l_mempoolList) {
                // this (p) is list begin. so set next as head.
                l_mempoolList = p->next;
            } else {
                // replace prevs next wuth our next.
                pprev->next = p->next;
            }
            break;
        }

        pprev = piter;
        piter = piter->next;
    }

    p->next = NULL;
    LeaveSpinLock(&l_mempoolListLock);


    // Get both locks.
    EnterSpinLock(&p->segmentLock);
    EnterSpinLock(&p->nodeLock);


    if(p->num_nodes_free != p->num_nodes_total)
        ShowWarning(read_message("Source.common.mempool_destroy"), p->name, (p->num_nodes_total - p->num_nodes_free));

    // Free All Segments (this will also free all nodes)
    // The segment pointer is the base pointer to the whole segment.
    seg = p->segments;
    while(1) {
        if(seg == NULL)
            break;

        segnext = seg->next;

        // ..
        if(p->ondealloc != NULL) {
            // walk over the segment, and call dealloc callback!
            ptr = (char *)seg;
            ptr += ALIGN_TO_16(sizeof(struct pool_segment));
            for(i = 0; i < seg->num_nodes_total; i++) {
                niter = (struct node *)ptr;
                ptr += sizeof(struct node);
                ptr += p->elem_size;
#ifdef MEMPOOLASSERT
                if(niter->magic != NODE_MAGIC) {
                    ShowError(read_message("Source.common.mempool_destroy2"), p->name, niter);
                    continue;
                }
#endif

                p->ondealloc(NODE_TO_DATA(niter));


            }
        }//endif: ondealloc callback?

        // simple ..
        aFree(seg);

        seg = segnext;
    }

    // Clear node ptr
    p->free_list = NULL;
    InterlockedExchange64(&p->num_nodes_free, 0);
    InterlockedExchange64(&p->num_nodes_total, 0);
    InterlockedExchange64(&p->num_segments, 0);
    InterlockedExchange64(&p->num_bytes_total, 0);

    LeaveSpinLock(&p->nodeLock);
    LeaveSpinLock(&p->segmentLock);

    // Free pool itself :D
    aFree(p->name);
    aFree(p);

}//end: mempool_destroy()
Exemplo n.º 6
0
VOID DokanCompleteWrite(__in PIRP_ENTRY IrpEntry,
                        __in PEVENT_INFORMATION EventInfo) {
  PIRP irp;
  PIO_STACK_LOCATION irpSp;
  NTSTATUS status = STATUS_SUCCESS;
  PDokanCCB ccb;
  PDokanFCB fcb;
  PFILE_OBJECT fileObject;

  fileObject = IrpEntry->FileObject;
  ASSERT(fileObject != NULL);

  DDbgPrint("==> DokanCompleteWrite %wZ\n", &fileObject->FileName);

  irp = IrpEntry->Irp;
  irpSp = IrpEntry->IrpSp;

  ccb = fileObject->FsContext2;
  ASSERT(ccb != NULL);

  fcb = ccb->Fcb;
  ASSERT(fcb != NULL);

  ccb->UserContext = EventInfo->Context;
  // DDbgPrint("   set Context %X\n", (ULONG)ccb->UserContext);

  status = EventInfo->Status;

  irp->IoStatus.Status = status;
  irp->IoStatus.Information = EventInfo->BufferLength;

  if (NT_SUCCESS(status)) {

    //Check if file size changed
    if (fcb->AdvancedFCBHeader.FileSize.QuadPart <
      EventInfo->Operation.Write.CurrentByteOffset.QuadPart) {
      if (!(irp->Flags & IRP_PAGING_IO)) {
        DokanFCBLockRO(fcb);
      }
      DokanNotifyReportChange(fcb, FILE_NOTIFY_CHANGE_SIZE,
        FILE_ACTION_MODIFIED);
      if (!(irp->Flags & IRP_PAGING_IO)) {
        DokanFCBUnlock(fcb);
      }

      //Update size with new offset
      InterlockedExchange64(
        &fcb->AdvancedFCBHeader.FileSize.QuadPart,
        EventInfo->Operation.Write.CurrentByteOffset.QuadPart);
    }
    
    DokanFCBFlagsSetBit(fcb, DOKAN_FILE_CHANGE_LAST_WRITE);

    if (EventInfo->BufferLength != 0 && fileObject->Flags & FO_SYNCHRONOUS_IO &&
        !(irp->Flags & IRP_PAGING_IO)) {
      // update current byte offset only when synchronous IO and not paging IO
      fileObject->CurrentByteOffset.QuadPart =
          EventInfo->Operation.Write.CurrentByteOffset.QuadPart;
      DDbgPrint("  Updated CurrentByteOffset %I64d\n",
                fileObject->CurrentByteOffset.QuadPart);
    }
  }

  DokanCompleteIrpRequest(irp, irp->IoStatus.Status, irp->IoStatus.Information);

  DDbgPrint("<== DokanCompleteWrite\n");
}
int32_t CEncoder::enc_loop(void)
{
	int video_frames = 0;

	int video_index = 0;
	int video_queue_index = 0;
	int last_video_index = -1;
	uint64_t audio_total_write = 0;
	
	uint64_t allow_audio_samples = g_enc_opt.m_VideoDisable ? INT64_MAX : 0;
	int audio_buffer_point = 0;
	int audio_buffer_channels = g_enc_opt.m_EncAudioIsPlanar ? g_enc_opt.m_EncAudioChannels : 1;
	int audio_buffer_max_bytes = AUDIO_BUFFER_SEC * g_enc_opt.m_EncAudioSampleRate * g_enc_opt.m_EncAudioPacketBytes;
	int audio_buffer_frame_bytes = audio_frame_size * g_enc_opt.m_EncAudioPacketBytes;
	uint64_t audio_samples_per_sec = audio_sample_rate;

	int32_t video_eof = g_enc_opt.m_VideoDisable;
	int32_t audio_eof = g_enc_opt.m_AudioDisable;

	while ((video_eof == 0) || (audio_eof == 0))
	{
		if (*m_pAbort) return ABORT_FLAG;
		if (video_eof == 0)
		{
			while ((m_VStream->m_Eof == 0) && (m_VStream->m_Queued == 0))
			{
				if (*m_pAbort) return ABORT_FLAG;
				Sleep(1);
			}

			if (m_VStream->m_Queued == 0)
			{
				assert(m_VStream->m_Eof);
				video_eof = 1;
				ending_video_codec();
				if (m_AStream)
				{
					allow_audio_samples = INT64_MAX;
				}
				else if (audio_eof == 0)
				{
					// 结束静音
					audio_eof = 1;
					ending_audio_codec();
				}
				continue;
			}

			video_index = m_VStream->m_Queue[video_queue_index];
			video_queue_index = (video_queue_index + 1) & (MAX_VIDEO_QUEUE - 1);
			if (write_video_frame(last_video_index == video_index, video_index) < 0)
			{
				return -1;
			}
			if (last_video_index != video_index)
			{
				if (last_video_index != -1)
					InterlockedDecrement(&m_VStream->m_Buffered);
				last_video_index = video_index;
			}
			InterlockedDecrement(&m_VStream->m_Queued);
			video_frames ++;
			allow_audio_samples = (uint64_t)video_frames * audio_samples_per_sec * (uint64_t)g_enc_opt.m_FrameNum / (uint64_t)g_enc_opt.m_FrameDen;
		}

		if (*m_pAbort) return ABORT_FLAG;
		if ((audio_eof == 0) && (m_AStream))
		{
			while (audio_total_write < allow_audio_samples)
			{

				while ((m_AStream->m_Eof == 0) && (m_AStream->m_Buffered < audio_frame_size))
				{
					if (*m_pAbort) return ABORT_FLAG;
					Sleep(1);
				}
				
				if (m_AStream->m_Buffered < audio_frame_size)
				{
					assert(m_AStream->m_Eof);
					m_AStream->m_Buffered = 0;
					audio_eof = 1;
					ending_audio_codec();
					break;
				}

				for(int i = 0; i < audio_buffer_channels; i++)
				{
					audio_frame.data[i] = &m_AStream->m_Buffers[i][audio_buffer_point];
					audio_frame.linesize[i] = audio_buffer_frame_bytes;
				}
				
				if ((audio_buffer_point + audio_buffer_frame_bytes) < audio_buffer_max_bytes)
				{
					audio_buffer_point += audio_buffer_frame_bytes;
				}
				else
				{
					int32_t l = audio_buffer_point + audio_buffer_frame_bytes - audio_buffer_max_bytes;
					for(int i = 0; i < audio_buffer_channels; i++)
					{
						memcpy(&m_AStream->m_Buffers[i][audio_buffer_max_bytes], m_AStream->m_Buffers[i], l);
					}
					audio_buffer_point = l;
				}
				
				if (write_audio_frame() < 0)
				{
					return -1;
				}

				InterlockedExchangeAdd((volatile long *)&m_AStream->m_Buffered, -audio_frame_size);
				audio_total_write += audio_frame_size;
			}
		}
		else if (audio_eof == 0)
		{
			// 写入静音
			while (audio_total_write < allow_audio_samples)
			{
				for(int i = 0; i < audio_buffer_channels; i++)
				{
					audio_frame.data[i] = m_AudioBuffer;
					audio_frame.linesize[i] = audio_buffer_frame_bytes;
				}
				if (write_audio_frame() < 0)
				{
					return -1;
				}
				audio_total_write += audio_frame_size;
			}
		}
				
		if (video_eof == 0)
		{
			uint64_t t = (uint64_t)video_frames * AV_TIME_BASE_LL * (uint64_t)g_enc_opt.m_FrameNum / (uint64_t)g_enc_opt.m_FrameDen;
			InterlockedExchange64(m_Time, t);
		}
		else if (audio_eof == 0)
		{
			int64_t t = audio_total_write * AV_TIME_BASE_LL / audio_samples_per_sec;
			InterlockedExchange64(m_Time,  t);
		}
	}

	return 0;
}
Exemplo n.º 8
0
intptr_t atom_xchg(volatile intptr_t *ptr, intptr_t new_value)
{
	return InterlockedExchange64((LONGLONG *)ptr, new_value);
}
Exemplo n.º 9
0
 static inline Type exchange(volatile Type& storage, Type value) {
   return static_cast<Type>(InterlockedExchange64((__int64*)&storage, (__int64)value));
 }
Exemplo n.º 10
0
HRESULT __stdcall EnlistmentNotifyShim::PrepareRequest(
    BOOL fRetaining, 
    DWORD grfRM, 
    BOOL fWantMoniker,
    BOOL fSinglePhase
    )
{
    HRESULT hr = S_OK;
    IPrepareInfo* pPrepareInfo = NULL;
    BYTE* prepareInfoBuffer = NULL;
    ULONG prepareInfoLength = 0;
    ITransactionEnlistmentAsync* pEnlistmentAsync = NULL;

#if defined(_X86_)
    pEnlistmentAsync = (ITransactionEnlistmentAsync*)InterlockedExchange((LONG volatile*)&this->pEnlistmentAsync, NULL);
#elif defined(_WIN64)
    pEnlistmentAsync = (ITransactionEnlistmentAsync*)InterlockedExchange64((LONGLONG volatile*)&this->pEnlistmentAsync, NULL);
#endif

    if( pEnlistmentAsync == NULL )
    {
        return E_UNEXPECTED;
    }

    hr = pEnlistmentAsync->QueryInterface(
        IID_IPrepareInfo,
        (void**) &pPrepareInfo
        );
    if ( FAILED( hr ) )
    {
        goto ErrorExit;
    }

    hr = pPrepareInfo->GetPrepareInfoSize( &prepareInfoLength );
    if ( FAILED( hr ) )
    {
        goto ErrorExit;
    }

    // This buffer will be freed by Managed code through the CoTaskMemHandle object that is
    // created when the pointer to this buffer is returned from GetNotification.
    prepareInfoBuffer = (BYTE*) CoTaskMemAlloc( prepareInfoLength );

    hr = pPrepareInfo->GetPrepareInfo( prepareInfoBuffer );
    if ( FAILED( hr ) )
    {
        goto ErrorExit;
    }

    this->prepareInfoSize = prepareInfoLength;
    this->pPrepareInfo = prepareInfoBuffer;
    this->isSinglePhase = fSinglePhase;
    this->notificationType = PrepareRequestNotify;
    this->shimFactory->NewNotification( this );

ErrorExit:

    SafeReleaseInterface( (IUnknown**) &pPrepareInfo );
    // We can now release our pEnlistmentAsync reference.  We don't need it any longer
    // and it causes problems if the app responds to SPC with InDoubt.
    SafeReleaseInterface( (IUnknown**) &pEnlistmentAsync );

    // We only delete the prepareinInfoBuffer if we had an error.
    if ( FAILED( hr ) )
    {
        if ( NULL != prepareInfoBuffer )
        {
            CoTaskMemFree( prepareInfoBuffer );
        }
    }

    return hr;
}
Exemplo n.º 11
0
uint64 atomic_exchange_u64( uint64 volatile* target, uint64 src )
{
    return InterlockedExchange64( (LONGLONG volatile*)target, src );
}
Exemplo n.º 12
0
/// @brief 
bool 
FileInfoCache::get_file_information(
	_In_ const wchar_t* file_path,
	_Out_ FileInformation& file_information
	)
{
	_ASSERTE(nullptr != file_path);
	if (nullptr == file_path) return false;

	//
	//	캐시 조회를 위한 기본 정보를 구한다.
	//
	WIN32_FILE_ATTRIBUTE_DATA fad;
	if (!GetFileAttributesExW(file_path,
							  GetFileExInfoStandard,
							  &fad))
	{
		log_err "GetFileAttributesExW() failed. file=%ws, gle=%u",
			file_path,
			GetLastError()
			log_end;
		return false;
	}

	if (fad.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
	{
		log_warn "Not file. path=%ws",
			file_path
		log_end;
		return false;
	}

	uint64_t create_time = file_time_to_int(&fad.ftCreationTime);
	uint64_t write_time = file_time_to_int(&fad.ftLastWriteTime);	
	uint64_t size = ((uint64_t)fad.nFileSizeHigh << 32) | fad.nFileSizeLow;
	
	//
	//	파일 사이즈가 0 이면 그냥 리턴
	//
	if (size == 0) return true;

	//
	//	1st phase, 캐시에서 찾아본다. 
	//
	std::string md5;
	std::string sha2;


	// 캐시 정보가 존재 한다면 캐시 정보를 반환한다.
	if (get_flie_info(file_path,
					  create_time,
					  write_time,
					  size,
					  md5,
					  sha2))
	{
		file_information.size = size;
		file_information.create_time = create_time;
		file_information.write_time = write_time;
		file_information.md5 = md5;
		file_information.sha2 = sha2;

		return true;
	}
	

	//
	//	2nd phase, 파일정보를 구하고, 캐시에 등록한다.
	// 
	if (true != file_util_get_hash(file_path, md5, sha2))
	{
		log_err "file_util_get_hash() failed. file=%ws",
			file_path
		log_end;
		return false;
	}

	//
	// 캐시에 등록 하기전 캐시 사이즈가 일정한 개수(기본값: 5000개, 
	// 사용자가 cache_size를 변경 한 경우 달라 질 수 있다) 를 초과하는 경우 
	// table내의 "hit count"의 평균을 구한 후 평균 이하인 데이터들을
	// 삭제한다.
	//
	if (_cache_size < _size)
	{
		int32_t delete_record_count = 0;
		
		try 
		{
			delete_record_count = _delete_cache_stmt->execDML();
		}
		catch (CppSQLite3Exception& e)
		{
			log_err
				"sqlite exception. get_file_information, code = %d, msg = %s",
				e.errorCode(),
				e.errorMessage()
			log_end;
		}

		//
		// 삭제된 레코드 수가 케시 사이즈보다 큰 경우 0으로 초기화 시킨다.
		//

		if (_size < delete_record_count)
		{
			_ASSERTE(!"oops, deleted record is larger than cache size");
			InterlockedExchange64(&_size, 0);
		}

		//
		// 데이터 삭제 이후 현재 캐시 사이즈에서 삭제된 레코드 수 만큼 
		// 빼준다.
		// =====================참고===========================
		// 현재 코드에서 기본 캐시 사이즈(5000개) 이상의 파일 정보가
		// 캐싱이 되어 레코드가 삭제 되는 코드를 테스트 해보지 못해
		// 다음과 같은 로깅코드를 남겨 두었으며 추후 삭제 할 수 있다.
		// ===================================================
		//
		
		InterlockedAdd64(&_size,-delete_record_count);

		log_dbg
			"delete file info cache record(count:%lu)",
			delete_record_count
		log_end;
	}

	

	if (true != insert_file_info(file_path,
								 create_time,
								 write_time,
								 size,
								 md5.c_str(),
								 sha2.c_str()))
	{
		log_err "insert_file_info() failed. file=%ws",
			file_path
		log_end;
		return false;
	}

	//
	//	파일정보를 리턴한다.
	// 
	file_information.size = size;
	file_information.create_time = create_time;
	file_information.write_time = write_time;
	file_information.md5 = md5;
	file_information.sha2 = sha2;

	log_dbg "File hash registered. file=%ws",
		file_path
		log_end;
	return true;
}