[hsflinux] hsfconfig fails to compile on RedHat 9

Wig vv1gg1 at yahoo.co.uk
Fri Apr 11 12:34:23 EDT 2003


I had the same problems, replace your ostime.c file with the one ive 
attached. This makes it compile fine but its a complete hack so might 
not be too reliable. That said ive not had any problems yet... but still 
when an official version/patch for RH9.0 comes out use that instead of 
my bodge job.

VViGGi

R. A. Rivas Diaz wrote:
> MY pc is configured to dualboot Windows XP and Redhat Linux 9, both
> recently instaled on a recently acquired PC.
> I have a Conexant HSF Modem and it's correctly installed and working
> perfectly under Windows XP.
> I downloaded the last available drivers for the mothem as an src.rpm...
> it get compiled and installed without problems, but when I run
> hsfconfig, I get compilation errors.
> I have attached the log generated by hsfconfig.
> Any idea of what it's happening?
> Thanks,
> Rivas.
> 
-------------- next part --------------
/*osTime.c

This file includes os specific code for timing related functionalities.

*/

/*
 * Copyright (c) 2001 Conexant Systems, Inc.
 * 
 * 1.   Permitted use. Redistribution and use in source and binary forms,
 * with or without modification, are permitted under the terms set forth
 * herein.
 * 
 * 2.   Disclaimer of Warranties. CONEXANT AND OTHER CONTRIBUTORS MAKE NO
 * REPRESENTATION ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE.
 * IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTIES OF ANY KIND.
 * CONEXANT AND OTHER CONTRIBUTORS DISCLAIMS ALL WARRANTIES WITH REGARD TO
 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE, GOOD TITLE AND AGAINST INFRINGEMENT.
 * 
 * This software has not been formally tested, and there is no guarantee that
 * it is free of errors including, but not limited to, bugs, defects,
 * interrupted operation, or unexpected results. Any use of this software is
 * at user's own risk.
 * 
 * 3.   No Liability.
 * 
 * (a) Conexant or contributors shall not be responsible for any loss or
 * damage to Company, its customers, or any third parties for any reason
 * whatsoever, and CONEXANT OR CONTRIBUTORS SHALL NOT BE LIABLE FOR ANY
 * ACTUAL, DIRECT, INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL, OR CONSEQUENTIAL
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED, WHETHER IN CONTRACT, STRICT OR OTHER LEGAL THEORY OF
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
 * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 * 
 * (b) User agrees to hold Conexant and contributors harmless from any
 * liability, loss, cost, damage or expense, including attorney's fees,
 * as a result of any claims which may be made by any person, including
 * but not limited to User, its agents and employees, its customers, or
 * any third parties that arise out of or result from the manufacture,
 * delivery, actual or alleged ownership, performance, use, operation
 * or possession of the software furnished hereunder, whether such claims
 * are based on negligence, breach of contract, absolute liability or any
 * other legal theory.
 * 
 * 4.   Notices. User hereby agrees not to remove, alter or destroy any
 * copyright, trademark, credits, other proprietary notices or confidential
 * legends placed upon, contained within or associated with the Software,
 * and shall include all such unaltered copyright, trademark, credits,
 * other proprietary notices or confidential legends on or in every copy of
 * the Software.
 * 
 */
#include "oscompat.h"
#include <linux/timer.h>
#include <linux/time.h>
#include <linux/ptrace.h>
#include <linux/interrupt.h>
#include <asm/semaphore.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <asm/system.h>
#include <linux/smp_lock.h>
#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7) )
#include <linux/completion.h>
#endif

#include "oscompat.h"
#include "ossysenv.h"
#include "ostime_ex.h"
#include "osmemory_ex.h"
#include "osstring_ex.h"
#include "linuxres.h"


#define TICKS_TO_MSECS(ticks) (ticks*(1000/HZ))

static inline long MSECS_TO_TICKS(UINT32 msecs)
{
	long ticks = (msecs)/(1000/HZ);

	// round up to next tick
	if ((!ticks && msecs) || (msecs % (1000/HZ)) >= ((1000/HZ) / 2))
		ticks++;

	return ticks;
}

typedef struct TIME_OUT_INSTANCE_TYPE
{
	struct tq_struct	TaskQueue;
	struct wait_queue	*WaitQueue;
	struct timer_list	Timer;
	BOOL                active;
	int					SchedCount;

	UINT32			mSec;
	BOOL			bLocked;

	PFREE_FUNC		pFuncFree;
	PVOID			pRefData;

	PCBFUNC			pTimeOutCallBack;

}TIME_OUT_INSTANCE_T, *PTIME_OUT_INSTANCE_T;
 
typedef struct TIMER_TAG
{
	UINT32 msec;
	struct timer_list timer;
} TIMER_T, *PTIMER_T;

/********************************************************************/

STATIC	VOID TimerThreadFunction(PVOID pData)
{
	PTIME_OUT_INSTANCE_T	pTimeOutInstance = (PTIME_OUT_INSTANCE_T)pData;

	if (pTimeOutInstance->active == TRUE )
	{
	    	/* beware: some callback functions use FPU instructions */
		pTimeOutInstance->pTimeOutCallBack(pTimeOutInstance->pRefData);

		// callback might have set active to FALSE
		if (pTimeOutInstance->active == TRUE ) {
			mod_timer(&pTimeOutInstance -> Timer, jiffies + MSECS_TO_TICKS(pTimeOutInstance -> mSec));
		}
	}

	pTimeOutInstance->SchedCount--;
}

STATIC VOID TimeOutHandler(	unsigned long Data )
{
	PTIME_OUT_INSTANCE_T	pTimeOutInstance = (PTIME_OUT_INSTANCE_T)Data;

	if (pTimeOutInstance->active == FALSE )
	{
		return;
	}

	pTimeOutInstance->SchedCount++;
	if (OsModemThreadSchedule(&(pTimeOutInstance -> TaskQueue)) == 0)
	{
		//printk(KERN_ERR "%s: TimeOutHandler(%d) - schedule_task FAILED (jiffies=%ld)\n", __FUNCTION__, pTimeOutInstance->SchedCount, jiffies);
		pTimeOutInstance->SchedCount--;
	}
}

static DECLARE_TASK_QUEUE(tq_mdmthrd);
static DECLARE_WAIT_QUEUE_HEAD(mdmthrd_wait);
#ifdef DECLARE_COMPLETION
static DECLARE_COMPLETION(mdmthrd_exited);
#endif
static int mdmthrd_pid;

int OsModemThreadSchedule(PVOID task)
{
	int ret;

	if(mdmthrd_pid <= 0) {
		printk(KERN_ERR"%s: WARNING: modem thread not present\n", __FUNCTION__);
	}
#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,19) )
	ret = queue_task((struct tq_struct *)task, &tq_mdmthrd);
#else
	{
		struct tq_struct *bh_pointer = (struct tq_struct *)task;
		task_queue *bh_list = &tq_mdmthrd;

		ret = 0;
		if (!test_and_set_bit(0,&bh_pointer->sync)) {
			unsigned long flags;
			spin_lock_irqsave(&tqueue_lock, flags);
			bh_pointer->next = *bh_list;
			*bh_list = bh_pointer;
			spin_unlock_irqrestore(&tqueue_lock, flags);
			ret = 1;
		}
	}
#endif
	wake_up(&mdmthrd_wait);
	return ret;
}

/* lock_kernel() must be called before this function */
static void thrd_daemonize(void)
{
#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) )
	exit_files(current);  /* daemonize doesn't do exit_files */
	current->files = init_task.files;
	atomic_inc(&current->files->count);
#endif
#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18) ) && !defined(daemonize)
	{
		struct fs_struct *fs;

		exit_mm(current);

		current->session = 1;
		current->pgrp = 1;

		exit_fs(current);	/* current->fs->count--; */
		fs = init_task.fs;
		current->fs = fs;
		atomic_inc(&fs->count);
	}
#else
	daemonize();
#endif

#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,10) ) && \
		( LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) )
	reparent_to_init();
#endif
}

#ifndef DECLARE_COMPLETION
static int mdmthrd_running;
#endif

static int mdmthrd(void *startup)
{
  	register struct task_struct *curtask = current;

	lock_kernel();

	/*  this thread doesn't need any user-level access,
	 *  so get rid of all our resources.
	 */
	thrd_daemonize();

	strncpy(curtask->comm, __FUNCTION__, sizeof(curtask->comm));

	unlock_kernel();

	//spin_lock_irq(&curtask->sigmask_lock);
	sigemptyset(&curtask->blocked);
	flush_signals(curtask);
	{ // flush_signal_handlers
		int i;
		//struct k_sigaction *ka = &curtask->sig->action[0];
		for (i = _NSIG ; i != 0 ; i--) {
			//if (ka->sa.sa_handler != SIG_IGN)
			//	ka->sa.sa_handler = SIG_DFL;
			//ka->sa.sa_flags = 0;
			//sigemptyset(&ka->sa.sa_mask);
			//ka++;
		}
	}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
	recalc_sigpending();
#endif
	spin_unlock_irq(&curtask->sigmask_lock);

#ifdef DECLARE_COMPLETION
	complete((struct completion *)startup);
#else
	mdmthrd_running = 1;
#endif

	/* beware: this thread executes floating-point instructions! */

	while(1) {
	    	set_current_state(TASK_RUNNING);
		run_task_queue(&tq_mdmthrd);
		if(signal_pending(curtask))
		    break;
		interruptible_sleep_on(&mdmthrd_wait);
	}

	//spin_lock_irq(&curtask->sigmask_lock);
	flush_signals(curtask);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
	recalc_sigpending();
#endif
	spin_unlock_irq(&curtask->sigmask_lock);

#ifdef DECLARE_COMPLETION
#if defined(complete_and_exit) || ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,9) )
	complete_and_exit(&mdmthrd_exited, 0);
#else
	complete(&mdmthrd_exited);
	up_and_exit(NULL, 0);
#endif
#else
	mdmthrd_running = 0;
	return 0;
#endif
}

static INT32 ntimers;

/********************************************************************/
/* Construct a periodic time out instance.RunTime manager does not	*/
/* simply use global timers , since these are called with the		*/
/* same thread handle as the ring3 application. This prevent		*/
/* synchronization between passive and async calls with semaphores	*/
/* or mutexes.                                                      */
/* Parameters :                                                     */
/* Irql - run time IQRL in which the timeout call back              */  
/*        should be called. In Wi95 this parameter in ignored,      */
/*        and all timeout are called at dispatch level.             */
/* InitialTimeout - Initial timeout interval in ms pRefData         */
/*                  should be passed as a parameter to this function*/
/* PTimeOutCallBack - CallBack to be call every timeout duration.   */
/* pFuncAlloc - alloc function,pRefData should be passed as         */ 
/*              parameter for thids function. function should       */
/*              allocate memory in non-paged pool                   */
/* pFuncFree - free function,pRefData should be passed as           */
/*             parameter for thids function                         */
/* pRefData -  reference data to be passed to pTimeOutCallBack      */
/*             pFuncAllc and pFuncFree                              */
/********************************************************************/
// @@@@ Irql unreferenced

GLOBAL	HANDLE	OSCreatePeriodicTimeOut	(	IN	TIMER_IRQL_TYPE	Irql,
											IN	UINT32			InitialTimeOut,
											IN	PCBFUNC			pTimeOutCallBack,
											IN	PALLOC_FUNC		pFuncAlloc,
											IN	PFREE_FUNC		pFuncFree,
											IN	PVOID			pRefData)
{
	PTIME_OUT_INSTANCE_T	pTimeOutInstance;
	if(pFuncAlloc) {
		pTimeOutInstance= pFuncAlloc(sizeof(TIME_OUT_INSTANCE_T), pRefData);
	} else {
		ASSERT(OSContextAllowsSleeping());
		pTimeOutInstance= kmalloc(sizeof(TIME_OUT_INSTANCE_T), GFP_KERNEL);
	}
	if (NULL == pTimeOutInstance )
		return(NULL);
	pTimeOutInstance->pFuncFree			= pFuncFree;
	pTimeOutInstance->pRefData			= pRefData;
	pTimeOutInstance->pTimeOutCallBack	= pTimeOutCallBack;
	pTimeOutInstance->bLocked			= FALSE;
	pTimeOutInstance->mSec				= InitialTimeOut;
 
	INIT_TQUEUE(&pTimeOutInstance -> TaskQueue, TimerThreadFunction, pTimeOutInstance);

	init_timer(&pTimeOutInstance -> Timer);
	pTimeOutInstance -> Timer.function = TimeOutHandler;
	pTimeOutInstance -> Timer.data = (unsigned long)pTimeOutInstance;
	pTimeOutInstance -> Timer.expires = jiffies + MSECS_TO_TICKS(100);
	pTimeOutInstance -> SchedCount = 0;

	if(OsAtomicIncrement(&ntimers) == 1) {
#ifdef COMPLETION_INITIALIZER
		static struct completion startup = COMPLETION_INITIALIZER(startup);
#endif

		MOD_INC_USE_COUNT;
#ifdef COMPLETION_INITIALIZER
		mdmthrd_pid = kernel_thread(mdmthrd, &startup, 0);
		wait_for_completion(&startup);
#else
		mdmthrd_running = 0;
		mdmthrd_pid = kernel_thread(mdmthrd, NULL, 0);
		{
			int i;

			/* wait 5 seconds maximum for modem thread to start */
			for (i=5000; !mdmthrd_running && (i > 0); i -= 50) {
				OsSleep(50);
			}
			if(i <= 0) {
				printk(KERN_ERR"%s: giving up on modem thread\n", __FUNCTION__);
			}
		}
#endif

		if(mdmthrd_pid <= 0) {
			MOD_DEC_USE_COUNT;
			OsAtomicDecrement(&ntimers);
			if(pTimeOutInstance->pFuncFree) {
				pTimeOutInstance->pFuncFree(pTimeOutInstance,pTimeOutInstance->pRefData);
			} else {
				kfree(pTimeOutInstance);
			}
			return NULL;
		}
	}

	if(InitialTimeOut != 0) {
		pTimeOutInstance -> active = TRUE;
		add_timer(&(pTimeOutInstance -> Timer));
	} else
		pTimeOutInstance -> active = FALSE;

	return( (HANDLE)pTimeOutInstance);
}

/********************************************************************/
GLOBAL	VOID	OSDestroyPeriodicTimeOut	(IN	HANDLE	hTimeOut)
{
	PTIME_OUT_INSTANCE_T	pTimeOutInstance = (PTIME_OUT_INSTANCE_T)hTimeOut;

	ASSERT(OSContextAllowsSleeping());

	pTimeOutInstance -> bLocked	= TRUE;
	pTimeOutInstance -> active = FALSE;

#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) )
	del_timer_sync(&pTimeOutInstance -> Timer);
#else
	del_timer(&pTimeOutInstance -> Timer);
#endif

	while(pTimeOutInstance->SchedCount > 0) {
	    schedule();
	}

	if(OsAtomicDecrement(&ntimers) == 0) {
		if(mdmthrd_pid > 0) {
			int r = kill_proc(mdmthrd_pid, SIGKILL, 1);
			if(r) {
				printk(KERN_ERR"%s: kill_proc mdmthrd_pid=%d r=%d\n", __FUNCTION__, mdmthrd_pid, r);
			}
#ifdef DECLARE_COMPLETION
			wait_for_completion(&mdmthrd_exited);
#else
			{
				int i;

				/* wait 5 seconds maximum for modem thread to terminate */
				for (i=5000; mdmthrd_running && (i > 0); i -= 50) {
					OsSleep(50);
				}
				if(i <= 0) {
					printk(KERN_ERR"%s: giving up on modem thread\n", __FUNCTION__);
				}
			}
#endif
			MOD_DEC_USE_COUNT;
		}
	}

	if(pTimeOutInstance->pFuncFree) {
		pTimeOutInstance->pFuncFree(pTimeOutInstance,pTimeOutInstance->pRefData);
	} else {
		kfree(pTimeOutInstance);
	}

}
/********************************************************************/
GLOBAL	BOOL	OSSetPeriodicTimeOut		(	IN	HANDLE			hTimeOut,
												IN	UINT32			NewTimeOut)
{
	PTIME_OUT_INSTANCE_T	pTimeOutInstance = (PTIME_OUT_INSTANCE_T)hTimeOut;

	pTimeOutInstance->mSec = NewTimeOut;
	if(NewTimeOut != 0) {
		pTimeOutInstance -> active = TRUE;
		mod_timer(&pTimeOutInstance -> Timer, jiffies + MSECS_TO_TICKS(pTimeOutInstance -> mSec));
	} else {
		pTimeOutInstance -> active = FALSE;
		del_timer(&pTimeOutInstance -> Timer);
	}
	return TRUE;
}

static time_t epoch = 0;

/********************************************************************/
GLOBAL	UINT32	OSGetSystemTime(			VOID	)
{
	struct timeval timestamp;
	do_gettimeofday(&timestamp);
	// result returned in milliseconds
	return ((UINT32)(((timestamp.tv_sec-epoch)*1000) + (timestamp.tv_usec/1000)));
}

/********************************************************************/

HANDLE OSCreateTimer(UINT32 msec, PVOID pCBFunc, PVOID pRefData)
{
	PTIMER_T pTimer;

	if ( pCBFunc == NULL )
	{
		ASSERT(pCBFunc);
		return (NULL);
	}

	ASSERT(OSContextAllowsSleeping());
	pTimer = kmalloc(sizeof(TIMER_T),GFP_KERNEL);
	if ( NULL == pTimer )
	{
		ASSERT(pTimer);
		return (NULL);
	}

	memset(pTimer,0,sizeof(TIMER_T));

	init_timer(&(pTimer->timer));
	pTimer->timer.function = pCBFunc ;
	pTimer->timer.data = (unsigned long)pRefData;
	pTimer->timer.expires = jiffies + MSECS_TO_TICKS(msec);
	pTimer->msec = msec;
	return ((HANDLE)pTimer);
}

void OSSetTimer(PVOID pTimer)
{
	struct timer_list*	pTimerH;
	PTIMER_T pTimerS = (PTIMER_T)pTimer;
	if ( pTimer == NULL )
	{
		ASSERT(pTimer);
		return;
	}
	pTimerH = &(pTimerS->timer);
	mod_timer(pTimerH, jiffies + MSECS_TO_TICKS(pTimerS->msec));
}

void OSCancelTimer(PVOID pTimer)
{
	struct timer_list*	pTimerH;
	if ( pTimer == NULL )
	{
		ASSERT(pTimer);
		return;
	}
	pTimerH = &((PTIMER_T)pTimer)->timer;
	
	del_timer(pTimerH);
}

void OSChangeTimerTimeOut(PVOID pTimer, UINT32 msec)
{
	PTIMER_T pTimerS = (PTIMER_T)pTimer;
	if ( pTimer == NULL )
	{
		ASSERT(pTimer);
		return;
	}
	pTimerS->msec = msec;
}

void OSDestroyTimer(PVOID pTimer)
{
	if ( pTimer == NULL )
	{
		ASSERT(pTimer);
		return;
	}

#if ( LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) )
	del_timer_sync(&((PTIMER_T)pTimer)->timer);
#else
	del_timer(&((PTIMER_T)pTimer)->timer);
#endif
	kfree(pTimer);
}

/********************************************************************/
/* Utilities                                                        */
/********************************************************************/

static spinlock_t atomic_lock __attribute__((unused)) = SPIN_LOCK_UNLOCKED;

/****************************************************************************************
    The OsAtomicCompareAndSwap function compares the value at the specified address with 
	oldVal. The value of newValue is written to the address only if oldValue and the 
	value at the address are equal. OSCompareAndSwap returns true if newValue is written 
	to the address; otherwise, it returns false. 
    
    Params:
        oldValue The value to compare at address.
        newValue The value to write to address if oldValue compares true.
        address The 4-byte aligned address of the data to update atomically.
    Result: true if newValue was written to the address. 
****************************************************************************************/
BOOL OsAtomicCompareAndSwap (PVOID oldValue, PVOID newValue, PVOID* address)
{
#ifdef __HAVE_ARCH_CMPXCHG
	return (cmpxchg(address, oldValue, newValue) == oldValue);
#else
	unsigned long flags;

	spin_lock_irqsave(&atomic_lock, flags);
  	if (*(PUINT32)address ==  (UINT32)oldValue)
  	{
		*(PUINT32)address = (UINT32)newValue;
		spin_unlock_irqrestore(&atomic_lock, flags);
  		return TRUE;
  	}
	spin_unlock_irqrestore(&atomic_lock, flags);

	return FALSE;
#endif
}
/****************************************************************************************
    OsAtomicAdd
   
    OsAtomicAdd function adds the specified amount to the value at the specified 
    address and returns the result.
    Params:
        amount  The amount to add.
        address The 4-byte aligned address of the value to update atomically.
    Result: The result of the addition.
****************************************************************************************/
INT32	OsAtomicAdd   (INT32 amount, PINT32 address)
{
	unsigned long flags;
	atomic_t *v = (atomic_t *)address;

	spin_lock_irqsave(&atomic_lock, flags);
	atomic_add(amount, v);
	amount = atomic_read(v);
	spin_unlock_irqrestore(&atomic_lock, flags);

	return amount;
}

INT32	OsAtomicIncrement (PINT32 address)
{
	unsigned long flags;
	atomic_t *v = (atomic_t *)address;
	INT32 amount;

	spin_lock_irqsave(&atomic_lock, flags);
	atomic_inc(v);
	amount = atomic_read(v);
	spin_unlock_irqrestore(&atomic_lock, flags);

	return amount;
}

INT32	OsAtomicDecrement (PINT32 address)
{
	unsigned long flags;
	atomic_t *v = (atomic_t *)address;
	INT32 amount;

	spin_lock_irqsave(&atomic_lock, flags);
	atomic_dec(v);
	amount = atomic_read(v);
	spin_unlock_irqrestore(&atomic_lock, flags);

	return amount;
}

void OsSleep(UINT32 ms)
{
	if(!OSContextAllowsSleeping()) {
		printk(KERN_ERR"%s(%lu): cannot sleep in this context!\n", __FUNCTION__, ms);
		ASSERT(OSContextAllowsSleeping());
		return;
	}

	if(ms > TICKS_TO_MSECS(1)) {
		UINT32 start, end;
		long timeout = MSECS_TO_TICKS(ms);
		//long ort = timeout;

		start = OSGetSystemTime();
		do {
			set_current_state(TASK_UNINTERRUPTIBLE);
		} while ((timeout = schedule_timeout(timeout)));
		end = OSGetSystemTime() - start;
		if(end < ms) {
			//printk(KERN_ERR"OsSleep: short timeout; wanted %ld got %ldms ort=%ld\n", ms, end, ort);
			OsSleep(end);
		}
		//else if(end > ms) {
		//	printk(KERN_ERR"OsSleep: timeout %ldms (%ldms too much) ort=%ld\n", ms, end - ms, ort);
		//}
	} else {
		// short delay
		mdelay(ms);
	}
}

DWORD OsGlobalProcessorFreq;

tMuSecTimeStamp OsGetMuSecStartStamp(void)
{
  tMuSecTimeStamp  StartCnt;
  rdtscl(StartCnt);
  if(0==StartCnt)
        StartCnt=1;

  return StartCnt;
}

tMuSecTimeStamp OsDeltaTimeMuSec(tMuSecTimeStamp PrevStamp, tMuSecTimeStamp NextStamp)
{
  tMuSecTimeStamp Delta=0;
  if(PrevStamp)
  {
    if(0==NextStamp)
    {
      NextStamp=OsGetMuSecStartStamp();
    }

    Delta=NextStamp - PrevStamp;
  
    Delta/=OsGlobalProcessorFreq;
  }
  return Delta;

}

void OsBusyLoopMuSec(DWORD DelayInMicroSecs)
{
  tMuSecTimeStamp StartCnt=OsGetMuSecStartStamp();
  while( OsDeltaTimeMuSec(StartCnt, 0) < (tMuSecTimeStamp)DelayInMicroSecs );
}


void OsBusyLoopMilliSec(DWORD DelayInMilliSecs)
{
    int Cnt;

    for(Cnt=0;Cnt<1000;Cnt++)
	OsBusyLoopMuSec(DelayInMilliSecs);
}



static atomic_t locksHeld;

void OsObtainedLock(void)
{
	atomic_inc(&locksHeld);
}

void OsReleasedLock(void)
{
	atomic_dec(&locksHeld);
}

int OsLocksHeld(void)
{
	return atomic_read(&locksHeld);
}

/* Semaphores */
/********************************************************************/
GLOBAL HANDLE	OSSemaphoreCreate(	IN	int InitCount)
{
	struct semaphore *pSemaphore;
	
	ASSERT(OSContextAllowsSleeping());
	pSemaphore = kmalloc(sizeof(struct semaphore), GFP_KERNEL);
	if (NULL == pSemaphore)
	{
		ASSERT(pSemaphore);
		return (NULL);
	}
	sema_init(pSemaphore, InitCount);
	return ((HANDLE)pSemaphore);
}

/********************************************************************/
GLOBAL VOID	OSSemaphoreDestroy(		IN	HANDLE hSemaphore)
{
	if (NULL != hSemaphore)
		kfree((void *)hSemaphore);
}

/********************************************************************/
GLOBAL VOID	OSSemaphoreWait(		IN	HANDLE hSemaphore)
{
	struct semaphore *pSemaphore = (struct semaphore *)hSemaphore;
	if (NULL == hSemaphore) {
		ASSERT(hSemaphore);
		return;
	}
	ASSERT(OSContextAllowsSleeping());
	down(pSemaphore);
}

/********************************************************************/
GLOBAL VOID	OSSemaphoreSignal(		IN	HANDLE hSemaphore)
{
	struct semaphore *pSemaphore = (struct semaphore *)hSemaphore;
	if (NULL == hSemaphore) {
		ASSERT(hSemaphore);
		return;
	}
	up(pSemaphore);
}

/* Critical Section (Mutex) */
/********************************************************************/
typedef struct {
	spinlock_t spinlock;
	unsigned long flags;
#ifdef DEBUG
	void *pmutex, *pfrom;
#endif
	void *owner;
	unsigned long nestcnt;
} CRIT_T;

GLOBAL HANDLE __OSCriticalSectionCreate( char *file, int line )
{
    CRIT_T *mutex;

	ASSERT(OSContextAllowsSleeping());
    mutex  = kmalloc(sizeof(CRIT_T), GFP_KERNEL);
	if(!mutex) {
		ASSERT(mutex);
		return NULL;
	}

	spin_lock_init(&mutex->spinlock);
#ifdef DEBUG
	mutex->pmutex = NULL;
	mutex->pfrom = NULL;
#endif
	mutex->owner = NULL;
	mutex->nestcnt = 0;

    return ((HANDLE)mutex);
}

/********************************************************************/
GLOBAL VOID	OSCriticalSectionDestroy(	IN	HANDLE hMutex)
{
	if ( NULL == hMutex )
	{
		ASSERT(hMutex);
		return;
	}
	kfree((CRIT_T *)hMutex);
}

#ifdef DEBUG
static CRIT_T *pmutex;
static void *pfrom;
#endif

/********************************************************************/
GLOBAL VOID	OSCriticalSectionAcquire(	IN	HANDLE hMutex)
{
	CRIT_T *mutex = (CRIT_T *) hMutex;
	unsigned long flags;

#ifdef local_irq_save
	local_irq_save(flags);
#else
	save_flags(flags);
	cli();
#endif
	if(!spin_trylock(&mutex->spinlock)) {
		if(!in_interrupt() && mutex->owner == current) {
			mutex->nestcnt++;
#ifdef local_irq_restore
			local_irq_restore(flags);
#else
			restore_flags(flags);
#endif
			return;
		}
		spin_lock(&mutex->spinlock);
	}
	mutex->flags = flags;
#ifdef DEBUG
	mutex->pmutex = pmutex;
	mutex->pfrom = pfrom;
	pmutex = mutex;
	pfrom = __builtin_return_address(0);
#endif
	if(!in_interrupt())
		mutex->owner = current;
	else
		mutex->owner = 0;
	OsObtainedLock();
}

/********************************************************************/
GLOBAL VOID	OSCriticalSectionRelease(	IN	HANDLE hMutex)
{
	CRIT_T *mutex = (CRIT_T *) hMutex;

#ifdef DEBUG
	ASSERT(pmutex == mutex);
	pmutex = mutex->pmutex;
	pfrom  = mutex->pfrom;
#endif
	if(mutex->nestcnt) {
		mutex->nestcnt--;
		return;
	}

	spin_unlock_irqrestore(&mutex->spinlock, mutex->flags);
	OsReleasedLock();
}

/********************************************************************/
GLOBAL	VOID	OSSetTimeSensitivity(	IN	UINT32				Interval)			
{
}
/********************************************************************/
GLOBAL	VOID	OSRestoreTimeSensitivity(		IN	UINT32				Interval)
{
}

/********************************************************************/

GLOBAL	VOID	OSInitTime(			VOID	)
{
	struct timeval timestamp;
	do_gettimeofday(&timestamp);

	epoch = timestamp.tv_sec;

	OsGlobalProcessorFreq = LinuxCalcCpuRate()/1000000;
}



More information about the hsflinux mailing list