Thread Rating:
  • 2 Vote(s) - 3 Average
  • 1
  • 2
  • 3
  • 4
  • 5
suggestion: make w32pthreads.dll version specific
#1
w32pthreads.dll makes it impossible to keep multiple different versions in the same directory, with the same files and configurations and just differing EXEs...
It would be great if it was somehow possible to keep several of those together.

Maybe have the exe check a subdir with a name identical to the exe for that dll?

ex:
C:\PCSX2\pcsx2.exe will look for w32pthreads.dll in C:\PCSX2\pcsx2\w32pthreads.dll

ex2:
C:\PCSX2\pcsx2-beta bXXXX.exe will look for w32pthreads.dll in C:\PCSX2\pcsx2-beta bXXXX\w32pthreads.dll
I do not have a superman complex; for I am God, not superman!

Rig: Q9400, 4GB DDR2, eVGA GTX260 SC, gigabyte EP35-DS3R. X25-M 80GB G2.

Sponsored links

#2
(note: moved to developer discussion forum)

w32pthreads.dll has not gone through any change that would require versioning to this point. I'm certain of it. Any version of w32pthreads.dll will work with any version of pcsx2 from the trunk svn revisions. The wxgui branch however has changed w32pthreads, and although I haven't done it yet since it's been a private development branch, I planned to version it starting with the merge of the wxgui branch into trunk. And for that matter, the wx and non-wx versions of PCSX2 are different enough that even with correctly versioned w32pthreads.dll, running the EXEs from the same folder interchangably would probably cause all kinds of odd problems.

Also! It's possible that cross-compiling builds of PCSX2 between vs2008 and vs2010 could cause dll compat issues. Technically it shouldn't, but vs2010 is in early beta so it's not really a good idea.


My planned scheme for versioning is like this:

w32pthreads.v2.dll
w32pthreads.v3.dll

I can't easily name the DLL as per SVN revision because it requires some rather "clever" application of pre- and post-build scripts, and it would also require I manually specify the DLL manifest instead of relying on the automatic manifest bindings created by the VC solution (which, honestly, I'm not really sure how it's done -- I tried to do manual DLL versioning crap for PCSX2 some months ago to import the Common Controls v6 library and still failed after some 3-5 hrs of reading MSDN articles, and subsequently pasting crap into project dialogs, source files, and manifest files). So instead I'm going to manually upgrade the name of the project (and it's output file) whenever I make changes to the DLL, which at this rate is likely to never happen again after wxgui becomes trunk. Wink
Jake Stine (Air) - Programmer - PCSX2 Dev Team
#3
Thats pretty awesome. Every time I come up with a good idea it seems you already figured it out too Smile
Your versioning approach sounds like it will work pretty well; good to know that any version of exe should work with any version of dll...

One correction though, what I suggested was not renaming of the DLL as per SVN revision... but to set the exe to automatically look for it in a subdirectory with a name matching its own... this means that renaming the exe will CHANGE the path in which it looks for the DLL without altering its code or the name of the dll.

I am not sure if this is more doable than what you tried to before. But if it was an issue before it be an issue again in the future... It would be cool if this idea solves a problem you encountered before.
I do not have a superman complex; for I am God, not superman!

Rig: Q9400, 4GB DDR2, eVGA GTX260 SC, gigabyte EP35-DS3R. X25-M 80GB G2.
#4
Nah, windows doesn't have any kind of 'search path' options for DLL loading. It has the default locations it searches (current working dir, dir where the executable is located, /windows/system32, and then the assembly registry), and that's about all you get for a say in the matter. Registering a DLL in the assembly registry has its own ugly can of worms, of course, so we'll happily stay far away from that. Wink

So to specify a subfolder would basically require specifying a special filename that includes the subfolder. ie, same thing as changing the filename itself.

The other nice thing about the new wx branch is that you'll be able to keep programs and data files separated. So you won't need to stack 600 copies of PCSX2 on top of each other in the same folder anymore. It'll be possible to keep a few separate installs of PCSX2 binaries that just reference the same shared locations of plugins, savegames, etc.
Jake Stine (Air) - Programmer - PCSX2 Dev Team
#5
I see.
Also, pretty neat about the wx branch seperation of data files and programs.
Thank you for clarifying this for me.
I do not have a superman complex; for I am God, not superman!

Rig: Q9400, 4GB DDR2, eVGA GTX260 SC, gigabyte EP35-DS3R. X25-M 80GB G2.
#6
This is somewhat related so I'll mention it here, I'm working on a library that ignores pthread.h on windows & defaults to it every where else, to avoid the more complicated api of mutexes that pthread.h uses (and probably win32, never checked) I designed an ANSI C version of my own:

Code:
#ifdef _WIN32
SHARED_EXP WHICH    Which() { return GetCurrentThreadId(); }
SHARED_EXP void        Pause() { SwitchToThread(); }
#else
SHARED_EXP WHICH    Which() { return gettid(); }
SHARED_EXP void        Pause() { sched_yield(); }
#endif

LOCK stderr_lock = {0};
LOCK syserr_lock = {0};
allot_cb AllotCB = Allot;

void LockStdErr() { LockSiData( &stderr_lock ); }
dint FreeStdErr() { return FreeSiData( &stderr_lock ); }

void LockSysErr() { LockSiData( &syserr_lock ); }
dint FreeSysErr() { return FreeSiData( &syserr_lock ); }

SHARED_EXP void LockSiData( LOCK *shared )
{
    WHICH tid = Which();
    while ( shared->tid != tid )
    {
        if ( !(shared->tid) )
            shared->tid = tid;
        Pause();
    }
    shared->num++;
}

SHARED_EXP dint FreeSiData( LOCK *shared )
{
    if ( shared->tid == Which() )
    {
        shared->num--;
        if ( !(shared->num) )
            shared->tid = (WHICH)0;
        return 0;
    }
    return EACCES;
}

I believe this method might be of more use for timing critical code, the concept is simple, assume 0 is always an invalid ID - which from my research is always the case anyways - which means the only time it's safe to TRY to take the object is when it's 0, I immediately pause thread execution after to give any threads that detected it within the same time slot a chance to write their own (since the writes will be sorted out by the CPU anyways), when execution resumes if the value is still the current threads id then no other threads identified 0 during the same time slot the system gives the threads, this naturally means that any threads that starts/resumes with the threads that attempted the lock will not have the chance to erroneously detect 0 during the locked state, having looked at the mutex code for pthreads I think that mine is by and far faster, as for the "num" member, that's just because my original method which used pointers combined with my limited minds eye meant I was causing infinite loops by accident, with num I can lock it as many times as I want during a locked state so long as I free it equally as many times, the LockStdErr & LockSysError are meant for avoiding problems with a buggy system implementation of errno/GetLastError, they're supposed to be used only when something is expected to potentially set those values or print text and you need them to be safe until you retrieve those values, for example:

Code:
#define LockErrors() do { LockStdErr(); LockSysErr(); } while(0)
#define FreeErrors() do { FreeSysErr(); FreeStdErr(); } while(0)

#define DO_LOCK( X ) do { X } while(0)

...

#define LOCK_SIDATA( SID, X ) \
    DO_LOCK( LockSiData( SID ); X FreeSiData( SID ); )

...

#define LOCK_ERRORS( X ) \
    DO_LOCK( LockErrors(); X FreeErrors(); )

...

SHARED_EXP dint    Allot( void *ud, void **data, size_t size )
{
    (void)ud;
    if ( size )
    {
        dint err;
        LOCK_ERRORS
        (
            errno = 0;
            *data = *data ? realloc( *data, size ) : malloc( size );
            err = *data ? 0 : errno;
        );
        return err;
    }
    else if ( *data )
    {
        LOCK_ERRORS( free( *data ); );
        *data = NULL;
    }
    return 0;
}

I've also designed a thread messaging system around the same method but I need to 1st decide if I'm happy with the api I've set up for it - which I feel I'm not, something about it feels too complex for what it should be so I'll probably change it when I'm ready for it
#7
The most recent post in this thread is more than 8 months old. Please create a new thread and refrain from posting in threads older than 8 months in the future. Please also review the forum rules. Thank you.
CPU : AMD Ryzen 7 3800X
Mobo : Asus PRIME B450-PLUS
GPU : NVIDIA GeForce RTX 3070
RAM : 16 Go




Users browsing this thread: 1 Guest(s)