The ramblings of a disgruntled geek!!

Tuesday, November 25, 2008

A Custom SpinLock based CriticalSection Implementation



Just something I implemented for fun :)


#include "stdafx.h"
#include <intrin.h>
#include <process.h>
#include <vector>
#include <utility>
#include <algorithm>
#include <iostream>
#pragma intrinsic (_InterlockedCompareExchange, _InterlockedExchange)
namespace DotFermion
{
class CCriticalSection
{
enum { LOCK_IS_FREE = 0, LOCK_IS_TAKEN = 1 };
private:
long lock;
long ownerThreadId;
long acquireCount;
public:
CCriticalSection():
lock(LOCK_IS_FREE),ownerThreadId(-1),acquireCount(0){}
~CCriticalSection()
{
Release();
}
//Non-recursive Acquire. Once its called, all threads, even the one owning the lock block on this lock.
//Even a subsequent AcquireRecursive call after this one blocks.
void Acquire()
{
while (_InterlockedExchange(&lock, LOCK_IS_TAKEN) == LOCK_IS_TAKEN);
}
//Recursive Acquire. It doesn't block if called multiple times from the same thread.
void AcquireRecursive(long threadId)
{
if(ownerThreadId != -1 && threadId == ownerThreadId)
{
_InterlockedIncrement(&acquireCount);
return;
}
Acquire ();
_InterlockedExchange(&ownerThreadId, threadId );
_InterlockedIncrement(&acquireCount);
}

void Release()
{
if(acquireCount > 1)
{
_InterlockedDecrement(&acquireCount);
return;
}
_InterlockedExchange(&acquireCount, 0);
_InterlockedExchange(&ownerThreadId, -1);
_InterlockedExchange(&lock, LOCK_IS_FREE);
}
};

}

#define LIST_POS = 4;
#define INDEX_POS = 8;

typedef void (*LPFNTHREADPROC) (void*);
typedef std::vector<uintptr_t> THREADLIST;
typedef THREADLIST* PTHREADLIST;
typedef struct _args_t
{
DotFermion::CCriticalSection* pCs;
PTHREADLIST pThreadList;
int index;
} args_t;

THREADLIST g_ThreadList;
int g_ThreadCount = 0;
int g_SharedCounter = 0;

void ThreadProc(void* argList)
{
args_t* args = (args_t*)argList;
args->pCs->AcquireRecursive((long)args->pThreadList->at(args->index));
g_SharedCounter++;
args->pCs->AcquireRecursive((long)args->pThreadList->at(args->index));
g_SharedCounter++;
args->pCs->Release();
args->pThreadList->at(args->index) = -1L;
g_ThreadCount--;
args->pCs->Release();
delete args;
}

int StartThreads ( int n, PTHREADLIST pThreadList, DotFermion::CCriticalSection* cs )
{
pThreadList->resize(n);
for ( int i = 0 ; i < n ; i ++ )
{
args_t* args = new args_t;
if ( args == NULL ) continue;
args->pCs = cs;
args->pThreadList = pThreadList;
args->index = i;
uintptr_t threadId = _beginthread(ThreadProc, 0, (void*)args);
if ( threadId != -1L )
{
cs->Acquire();
pThreadList->at(i) = threadId;
g_ThreadCount ++;
cs->Release();
}
}
return g_ThreadCount;
}


void Join (int* threadCount)
{
while ( *threadCount );
}

int _tmain(int argc, _TCHAR* argv[])
{
DotFermion::CCriticalSection cs;
StartThreads(100, &g_ThreadList, &cs);
Join(&g_ThreadCount);
std::cout << g_SharedCounter << std::endl;
return 0;
}



Saturday, October 25, 2008

My own GetWsdl tool



I finally figured it out. It was there right in front of my eyes. I stumbled upon it so many times, but I always missed it.

I have been doing web service development for quite some time now. These services are part of pretty complex systems that require a long time to deploy. Imagine, every time there was a build number change and I wanted to modify one of the services. I wrote the code, built it, deployed the services (this step was the longest and most painful), got the wsdl, generated the proxy and updated and built again. The reason it required full redeployment on build number changes is that the assemblies are bound by strong names. It was one heck of a time consuming job. All this work, just to update the proxy; WSDL generation required a live service. :)

Though I still have to do this to verify that the code that I wrote actually works, proxy generation is not that much of a hassle, especially when I am writing code that I know works already and there is minimal need to try it out.

This time has been drastically reduced. Thanks to System.Web.Services.Description.
ServiceDescriptionReflector
.

 

The GetWsdl tool is here. I will publish it soon. Stay tuned.


-UG


Tuesday, October 21, 2008

Update

I haven’t updated my blog for ages. This is a just a refresh post :)

Keyboard

Keyboard
Keyboard

Blog Reading Level

blog readability test
Powered By Blogger

VerveEarth