コード例 #1
0
ファイル: MultiLocker.cpp プロジェクト: dtbinh/Sequitur
bool
MultiLocker::ReadUnlock()
{
#if TIMING
    bigtime_t start = system_time();
#endif

    bool unlocked = false;

    if (IsWriteLocked()) {
        //writers simply decrement the nesting count
        fWriterNest--;
        unlocked = true;
    } else {
        //decrement and retrieve the read counter
        int32 current_count = atomic_add(&fReadCount, -1);
        if (current_count < 0) {
            //a writer is waiting for the lock so release fWriteSem
            unlocked = (release_sem_etc(fWriteSem, 1,
                                        B_DO_NOT_RESCHEDULE) == B_OK);
        } else unlocked = true;

        //unregister if we released the lock and are debugging
        if (fDebugArray && unlocked) unregister_thread();
    }

#if TIMING
    bigtime_t end = system_time();
    ru_time += (end - start);
    ru_count++;
#endif

    return unlocked;
}
コード例 #2
0
ファイル: Destination.cpp プロジェクト: HaikuArchives/MeV
void
CDestination::ReadChunk(
	CIFFReader &reader)
{
	ASSERT(IsWriteLocked());

	switch (reader.ChunkID())
	{
		case DESTINATION_HEADER_CHUNK:
		{
			reader >> m_id;
			reader >> m_latency;
			reader >> m_flags;
			reader >> m_color;
			ColorChanged(m_color);
			break;
		}
		case DESTINATION_NAME_CHUNK:
		{
			reader.MustRead(m_name, MIN((size_t)reader.ChunkLength(),
										DESTINATION_NAME_LENGTH));
			NameChanged(m_name);
			break;
		}
		default:
		{
			CSerializable::ReadChunk(reader);
		}
	}
}
コード例 #3
0
ファイル: MultiLocker.cpp プロジェクト: dtbinh/Sequitur
bool
MultiLocker::WriteLock()
{
#if TIMING
    bigtime_t start = system_time();
#endif

    bool locked = false;

    if (fInit == B_OK) {
        uint32 stack_base = 0;
        thread_id thread = -1;

        if (IsWriteLocked(&stack_base, &thread)) {
            //already the writer - increment the nesting count
            fWriterNest++;
            locked = true;
        } else {
            //new writer acquiring the lock
            if (atomic_add(&fLockCount, 1) >= 1) {
                //another writer in the lock - acquire the semaphore
                locked = (acquire_sem_etc(fWriterLock, 1, B_DO_NOT_RESCHEDULE,
                                          B_INFINITE_TIMEOUT) == B_OK);
            } else locked = true;

            if (locked) {
                //new holder of the lock

                //decrement fReadCount by a very large number
                //this will cause new readers to block on fReadSem
                int32 readers = atomic_add(&fReadCount, -MAX_READERS);

                if (readers > 0) {
                    //readers hold the lock - acquire fWriteSem
                    locked = (acquire_sem_etc(fWriteSem, readers, B_DO_NOT_RESCHEDULE,
                                              B_INFINITE_TIMEOUT) == B_OK);
                }
                if (locked) {
                    ASSERT(fWriterThread == -1);
                    //record thread information
                    fWriterThread = thread;
                    fWriterStackBase = stack_base;
                }
            }
        }
    }

#if TIMING
    bigtime_t end = system_time();
    wl_time += (end - start);
    wl_count++;
#endif

    return locked;
}
コード例 #4
0
ファイル: MultiLocker.cpp プロジェクト: dtbinh/Sequitur
bool
MultiLocker::WriteUnlock()
{
#if TIMING
    bigtime_t start = system_time();
#endif

    bool unlocked = false;

    if (IsWriteLocked()) {
        //if this is a nested lock simply decrement the nest count
        if (fWriterNest > 0) {
            fWriterNest--;
            unlocked = true;
        } else {
            //writer finally unlocking

            //increment fReadCount by a large number
            //this will let new readers acquire the read lock
            //retrieve the number of current waiters
            int32 readersWaiting = atomic_add(&fReadCount, MAX_READERS) + MAX_READERS;

            if (readersWaiting > 0) {
                //readers are waiting to acquire the lock
                unlocked = (release_sem_etc(fReadSem, readersWaiting,
                                            B_DO_NOT_RESCHEDULE) == B_OK);
            } else unlocked = true;

            if (unlocked) {
                //clear the information
                fWriterThread = -1;
                fWriterStackBase = 0;

                //decrement and retrieve the lock count
                if (atomic_add(&fLockCount, -1) > 1) {
                    //other writers are waiting so release fWriterLock
                    unlocked = (release_sem_etc(fWriterLock, 1,
                                                B_DO_NOT_RESCHEDULE) == B_OK);
                }
            }
        }

    } else debugger("Non-writer attempting to WriteUnlock()\n");

#if TIMING
    bigtime_t end = system_time();
    wu_time += (end - start);
    wu_count++;
#endif

    return unlocked;
}
コード例 #5
0
ファイル: Destination.cpp プロジェクト: HaikuArchives/MeV
void
CDestination::SetLatency(
	bigtime_t latency)
{
	D_ACCESS(("CDestination::SetLatency(%Ld)\n", latency));
	ASSERT(IsWriteLocked());

	if (latency != m_latency)
	{
		m_latency = latency;
		Document()->SetModified();
	
		CUpdateHint hint;
		hint.AddInt32("DestID", m_id);
		hint.AddInt32("DestAttrs", Update_Latency);
		PostUpdate(&hint);
	}
}
コード例 #6
0
ファイル: Destination.cpp プロジェクト: HaikuArchives/MeV
void
CDestination::SetName(
	const char *name)
{
	D_ACCESS(("CDestination::SetName(%s)\n", name));
	ASSERT(IsWriteLocked());

	if (strcmp(m_name, name) != 0)
	{
		strncpy(m_name, name, DESTINATION_NAME_LENGTH);

		NameChanged(name);
		Document()->SetModified();
		
		CUpdateHint hint;
		hint.AddInt32("DestID", m_id);
		hint.AddInt32("DestAttrs", Update_Name);
		PostUpdate(&hint);
	}
}
コード例 #7
0
ファイル: MultiLocker.cpp プロジェクト: SummerSnail2014/haiku
MultiLocker::~MultiLocker()
{
	//become the writer
	if (!IsWriteLocked()) WriteLock();
	
	//set locker to be uninitialized
	fInit = B_NO_INIT;

	//delete the semaphores
	delete_sem(fReadSem);
	delete_sem(fWriteSem);
	delete_sem(fWriterLock);
	
	#if DEBUG
		//we are in debug mode!
		//clear and delete the reader tracking list
		free(fDebugArray);
	#endif
	#if TIMING	
		//let's produce some performance numbers
		printf("MultiLocker Statistics:\n"
				"Avg ReadLock: %lld\n"
				"Avg ReadUnlock: %lld\n"
				"Avg WriteLock: %lld\n"
				"Avg WriteUnlock: %lld\n"
				"Avg IsWriteLocked: %lld\n",
				rl_count > 0 ? rl_time / rl_count : 0,
				ru_count > 0 ? ru_time / ru_count : 0,
				wl_count > 0 ? wl_time / wl_count : 0,
				wu_count > 0 ? wu_time / wu_count : 0,
				islock_count > 0 ? islock_time / islock_count : 0
		);
		#if DEBUG
			printf(	"Avg register_thread: %lld\n"
					"Avg unregister_thread: %lld\n",
					reg_count > 0 ? reg_time / reg_count : 0,
					unreg_count > 0 ? unreg_time / unreg_count : 0
			);
		#endif
	#endif	
}
コード例 #8
0
ファイル: MultiLocker.cpp プロジェクト: SummerSnail2014/haiku
bool 
MultiLocker::ReadLock()
{
	#if TIMING
		bigtime_t start = system_time();
	#endif

	bool locked = false;	

	//the lock must be initialized
	if (fInit == B_OK) {
		if (IsWriteLocked()) {
			//the writer simply increments the nesting
			fWriterNest++;
			locked = true;
		} else {
			//increment and retrieve the current count of readers
			int32 current_count = atomic_add(&fReadCount, 1);	
			if (current_count < 0) {
				//a writer holds the lock so wait for fReadSem to be released
				locked = (acquire_sem_etc(fReadSem, 1, B_DO_NOT_RESCHEDULE,
										  B_INFINITE_TIMEOUT) == B_OK);
			} else locked = true;			
		#if DEBUG
			//register if we acquired the lock
			if (locked) register_thread();
		#endif
		}
		
	}
	
	#if TIMING
		bigtime_t end = system_time();
		rl_time += (end - start);
		rl_count++;
	#endif

	return locked;	
}
コード例 #9
0
ファイル: Destination.cpp プロジェクト: HaikuArchives/MeV
void
CDestination::SetColor(
	rgb_color color)
{
	D_ACCESS(("CDestination::SetColor(%d, %d, %d, %d)\n",
			  color.red, color.green, color.blue, color.alpha));
	ASSERT(IsWriteLocked());

	if ((color.red != m_color.red)
	 || (color.green != m_color.green)
	 || (color.blue != m_color.blue))
	{
		m_color = color;
		
		ColorChanged(color);
		Document()->SetModified();
	
		CUpdateHint hint;
		hint.AddInt32("DestID", m_id);
		hint.AddInt32("DestAttrs", Update_Color);
		PostUpdate(&hint);
	}
}
コード例 #10
0
ファイル: Destination.cpp プロジェクト: HaikuArchives/MeV
void
CDestination::SetSolo(
	bool solo)
{
	D_ACCESS(("CDestination::SetSolo(%s)\n", solo ? "true" : "false"));
	ASSERT(IsWriteLocked());

	bool changed = false;
	if (solo)
		changed = _addFlag(SOLO);
	else
		changed = _removeFlag(SOLO);

	if (changed)
	{
		Soloed(solo);
		Document()->SetModified();

		CUpdateHint hint;
		hint.AddInt32("DestID", m_id);
		hint.AddInt32("DestAttrs", Update_Flags);
		PostUpdate(&hint);
	}
}
コード例 #11
0
ファイル: Destination.cpp プロジェクト: HaikuArchives/MeV
void
CDestination::SetMuted(
	bool muted)
{
	D_ACCESS(("CDestination::SetMuted(%s)\n", muted ? "true" : "false"));
	ASSERT(IsWriteLocked());

	bool changed = false;
	if (muted)
		changed = _addFlag(MUTED);
	else
		changed = _removeFlag(MUTED);

	if (changed)
	{
		Muted(muted);
		Document()->SetModified();

		CUpdateHint hint;
		hint.AddInt32("DestID", m_id);
		hint.AddInt32("DestAttrs", Update_Flags);
		PostUpdate(&hint);
	}
}