Example #1
0
File: Mutex.C Project: makamuy/frob
status_t
Mutex::unlock()
{
    int result = pthread_mutex_unlock ( & getMutexData() );
    switch ( result )
    {
    case 0:  /* It worked */
        return ::SUCCESS;

    case EINVAL:
        FLUSHALL();
        cerr << "[Mutex:unlock]  Error:  [EINVAL]  "
             << "Unable to unlock improperly initialized mutex."
             << endl;
        break;

    case EPERM:  /* Mutex::ERROR_CHECK only */
        FLUSHALL();
        cerr << "[Mutex:unlock]  Error:  [EPERM]  "
             << "Unable to unlock Mutex:  Calling thread does not own the mutex."
             << endl;
        break;

    default:
        FLUSHALL();
        cerr << "[Mutex:lock]  Error:  pthread_mutex_unlock(.) returned: "
             << result << "." << endl;
        break;
    }

    return ::FAILURE;
}
Example #2
0
File: Mutex.C Project: makamuy/frob
status_t
Mutex::lock()
{
    int result = pthread_mutex_lock ( & getMutexData() );
    switch ( result )
    {
    case 0:  /* It worked */
        return ::SUCCESS;

    case EINVAL:
        FLUSHALL();
        cerr << "[Mutex:lock]  Error:  [EINVAL]  "
             << "Unable to lock improperly initialized mutex."
             << endl;
        break;

    case EDEADLK:  /* Mutex::ERROR_CHECK only */
        FLUSHALL();
        cerr << "[Mutex:lock]  Error:  [EDEADLK]  "
             << "Unable to lock mutex:  Mutex already locked by calling thread."
             << endl;
        break;

    default:
        FLUSHALL();
        cerr << "[Mutex:lock]  Error:  pthread_mutex_lock(.) returned: "
             << result << "." << endl;
        break;
    }

    return ::FAILURE;
}
Example #3
0
File: Mutex.C Project: makamuy/frob
Mutex::TRY_LOCK_STATUS_T
Mutex::trylock()
{
    int result = pthread_mutex_trylock ( & getMutexData() );
    switch ( result )
    {
    case 0:  /* It worked */
        return Mutex::SUCCESS;

    case EINVAL:
        FLUSHALL();
        cerr << "[Mutex:trylock]  Error:  [EINVAL]  "
             << "Unable to lock improperly initialized mutex."
             << endl;
        break;

    case EBUSY:  /* Already locked */
        return Mutex::ALREADY_LOCKED;

    default:
        FLUSHALL();
        cerr << "[Mutex:lock]  Error:  pthread_mutex_trylock(.) returned: "
             << result << "." << endl;
        break;
    }

    return Mutex::FAILURE;
}
Example #4
0
File: Mutex.C Project: makamuy/frob
/*virtual*/
Mutex::~Mutex()
{
    int result;

    pthread_mutexattr_destroy ( & getMutexAttributes() );

    result = pthread_mutex_destroy ( & getMutexData() );
    switch ( result )
    {
    case 0:  /* It worked */
        break;

    case EBUSY:
        FLUSHALL();
        cerr << "[Mutex:~Mutex]  Error:  (" << (void*)this << ") [EBUSY]  "
             << "Unable to properly destroy currently lock()'ed Mutex!."
             << endl;
        break;

    default:
        FLUSHALL();
        cerr << "[Mutex:~Mutex]  Error: (" << (void *)this
             << ")  pthread_mutex_destroy(.) returned: "
             << result << "." << endl;
        break;
    }
}
Example #5
0
double benchmark_cache_memory_set(REGISTER void *x, REGISTER long bytes, long *oloops, double *ous)
{
  REGISTER long loops = 0;
  
  FLUSHALL(1);
  keepgoing = 1;
  assert(signal(SIGALRM,handler) != SIG_ERR);

  alarm(duration);
  TIMER_START;

  while (keepgoing)
    {
      memset(x,0xf0,bytes);
      loops++;
    }

  TIMER_STOP;

  fake_out_optimizations(x,bytes);

  *ous = TIMER_ELAPSED;
  *oloops = loops;
  return((double)loops*(double)bytes);
}
Example #6
0
double benchmark_cache(REGISTER DATATYPE *x, REGISTER long limit, long *oloops, double *ous)
{
  REGISTER long index = 0, loops = 0;
  
  FLUSHALL(1);
  keepgoing = 1;
  assert(signal(SIGALRM,handler) != SIG_ERR);

  alarm(duration);
  TIMER_START;

  while (keepgoing)
    {
      for (index = 0; index < limit; index++)
	x[index]++;
      loops++;
    }

  TIMER_STOP;

  fake_out_optimizations(x,limit*sizeof(DATATYPE));

  *oloops = loops;
  *ous = TIMER_ELAPSED;
  {
    double refcnt = ((double)loops*(double)limit);
    DBG(fprintf(stderr,"T: %ld loops at limit %ld took %f us, %f refs.\n",loops,limit,*ous,refcnt));
    return(refcnt);
  }
}
Example #7
0
     /* Thread two calls this method, which wakes up thread one.
      * This method does **NOT** block!
      *
      * Use wakeupOtherThread(TRUE) if one is uncertain as to
      * whether another thread is already waiting.  Do not do:
      *   if ( getIsThreadWaiting() == TRUE ) wakeupOtherThread();
      * As this could lead to a race condition wherein a thread
      * starts waiting after the getIsThreadWaiting() function.
      *
      * The argument name is complex.  But I wanted to be able
      * to use TRUE/TRUE for waitForSignal()/wakeupOtherThread()
      * in the case where waitForSignal() occurs prior to 
      * the wakeupOtherThread().
      *
      * So, use FALSE to report when no other thread is present,
      * and TRUE to prevent such reporting.
      */
status_t
Semaphore::wakeupOtherThread( BOOLEAN theDoNotReportIfNoOtherThread /*=FALSE*/)
{
  lock("Semaphore:wakeupOtherThread");

  setWakeupAlreadyReceivedNoMutex(); /* Race conditions are a bitch! */

  if ( getIsThreadWaitingNoMutex() == FALSE )
  {
    if ( theDoNotReportIfNoOtherThread == FALSE )
    {
      FLUSHALL();
      cerr << "[Semaphore:waitForSignal]  Warning:  "
	   << "No thread is waiting on this Semaphore." << endl;
    }
    unlock("Semaphore::waitForSignal");    
    return FAILURE;
  }

	/* Only doing sem_post if we have a thread waiting... */
  if ( sem_post ( & getSemaphoreDataNoMutex() ) != 0 )
  {
    PERROR ( "[Semaphore:waitForSignal]  Error:  sem_post() failed.   " );
    unlock("Semaphore:wakeupOtherThread");
    return FAILURE;
  }

  unlock("Semaphore:wakeupOtherThread");
  return SUCCESS;
}
Example #8
0
int main(int argc, char **argv) 
{
  DATATYPE *x;
  long *sizes;
  double *times, *bws, *percents;

  type = usage(argc, argv);

  assert(sizes = (long *)malloc(timeslots*sizeof(long)));
  memset(sizes,0x00,(timeslots*sizeof(long)));
  assert(times = (double *)malloc(timeslots*repeat_count*sizeof(double)));
  memset(times,0x00,(timeslots*repeat_count*sizeof(double)));
  assert(bws = (double *)malloc(timeslots*repeat_count*sizeof(double)));
  memset(bws,0x00,(timeslots*repeat_count*sizeof(double)));
  assert(percents = (double *)malloc(timeslots*repeat_count*sizeof(double)));
  memset(percents,0x00,(timeslots*repeat_count*sizeof(double)));
  assert(x = (DATATYPE *)malloc((size_t)memsize));
  memset((void *)x,0x00,memsize);

  initialize_sizes(sizes);

  /* Measure cache */

  if (type & MEMORYSET)
    {
      do_memory_set(sizes,x,times,bws,percents);
    }

  if (type & MEMORYCOPY)
    {
      do_memory_copy(sizes,x,times,bws,percents);
    }

  if (type & READONLY)
    {
      do_read_only(sizes,x,times,bws,percents);
    }

  if (type & WRITEONLY)
    {
      do_write_only(sizes,x,times,bws,percents);
    }

  if (type & READWRITE)
    {
      do_read_write(sizes,x,times,bws,percents);
    }

  FLUSHALL(0);

  exit(0);
}
Example #9
0
File: Mutex.C Project: makamuy/frob
BOOLEAN
Mutex::isLocked()
{
    Mutex::TRY_LOCK_STATUS_T  tryLockStatus;
    switch ( tryLockStatus = trylock() )
    {
    case Mutex::SUCCESS:
        /* We just locked ourself.  If unlock fails... *
         * Well, we are locked...  And probably hosed. */
        switch ( unlock() )
        {
        case ::SUCCESS:
            return FALSE;

        /* If this happens, something truly odd is going on... */
        case ::FAILURE:
        default:
            FLUSHALL();
            cerr << "[Mutex:isLocked]  Internal Failure:  "
                 << "trylock() returned SUCCESS.   unlock() returned FAILURE.  "
                 << "(So we've just locked the mutex.)" << endl;
            return TRUE;
        }

    case Mutex::FAILURE:
        return FALSE;

    case Mutex::ALREADY_LOCKED:
        return TRUE;

    default:
        FLUSHALL();
        cerr << "[Mutex:isLocked]  Impossible Error: tryLock() returned: "
             << int4(tryLockStatus) << ".  Assuming we are locked..." << endl;
        return TRUE; /* Worst case scenario: Assume we are locked. */
    }
}
Example #10
0
File: Mutex.C Project: makamuy/frob
/* Convenience method */
Mutex::TRY_LOCK_STATUS_T
Mutex::trylock ( const char * theErrorLocation )
{
    Mutex::TRY_LOCK_STATUS_T returnValue = trylock();

    if ( returnValue == Mutex::FAILURE )
    {
        if ( theErrorLocation == (const char *) NULL )
            theErrorLocation = "";

        FLUSHALL();
        cerr << "[" << theErrorLocation << "]  Error:  "
             << "Problems while trylock()'ing mutex." << endl;
    }

    return returnValue;
}
Example #11
0
File: Mutex.C Project: makamuy/frob
/* Convenience method */
status_t
Mutex::unlock( const char * theErrorLocation)
{
    status_t returnValue = unlock();

    if ( returnValue != ::SUCCESS )
    {
        if ( theErrorLocation == (const char *) NULL )
            theErrorLocation = "";

        FLUSHALL();
        cerr << "[" << theErrorLocation << "]  Error:  "
             << "Unable to unlock mutex." << endl;
    }

    return returnValue;
}
Example #12
0
double hand_benchmark_cache_wonly(REGISTER DATATYPE *x, REGISTER long limit, long *oloops, double *ous)
{
  REGISTER long index = 0, loops = 0;
  REGISTER DATATYPE wval = (DATATYPE)0xf;

  FLUSHALL(1);
  keepgoing = 1;
  assert(signal(SIGALRM,handler) != SIG_ERR);
  limit -= 8; wval = (DATATYPE)limit;

  alarm(duration);
  TIMER_START;

again:
  x[index] = wval;
  x[index+1] = wval;
  x[index+2] = wval;
  x[index+3] = wval;
  x[index+4] = wval;
  x[index+5] = wval;
  x[index+6] = wval;
  x[index+7] = wval;
  if ((index+=8) < limit)
    goto again;
  else if (keepgoing)
    {
      index = 0;
      loops++;
      goto again;
    }

  TIMER_STOP;
  index += 8;

  fake_out_optimizations(x,limit*sizeof(DATATYPE));

  *oloops = loops;
  *ous = TIMER_ELAPSED;
  {
    double refcnt = ((double)loops*(double)limit);
    DBG(fprintf(stderr,"T: %ld loops at limit %ld took %f us, %f refs.\n",loops,limit,*ous,refcnt));
    return(refcnt);
  }
}
Example #13
0
double benchmark_cache_ronly(REGISTER DATATYPE *x, REGISTER long limit, long *oloops, double *ous)
{
  REGISTER long index = 0, loops = 0;
  REGISTER DATATYPE sum = (DATATYPE)0;

  FLUSHALL(1);
  keepgoing = 1;
  assert(signal(SIGALRM,handler) != SIG_ERR);

  alarm(duration);
  TIMER_START;

#ifdef SOLARIS
  while (go(-1))
#else
  while (keepgoing)
#endif  
    {
      for  (index = 0; index < limit; index++)
	{
	  sum += x[index];
	}
      loops++;
    }

  TIMER_STOP;

  x[0] = (DATATYPE)sum;
  x[1] = (DATATYPE)index;
  fake_out_optimizations(x,2*sizeof(DATATYPE));

  *oloops = loops;
  *ous = TIMER_ELAPSED;
  {
    double refcnt = ((double)loops*(double)limit);
    DBG(fprintf(stderr,"T: %ld loops at limit %ld took %f us, %f refs.\n",loops,limit,*ous,refcnt));
    return(refcnt);
  }
}
Example #14
0
File: Mutex.C Project: makamuy/frob
Mutex::Mutex ( Mutex::TYPE  theMutexType /* = Mutex::RECURSIVE */ )
    : threadIostreamBase (              ),
      mutexType          ( theMutexType )
{
    int mutexAttributeKind;
    int result;

    /* It's not paranoia if the computer is really out to get you... */
    memset ( & getMutexAttributes(), 0, sizeof(pthread_mutexattr_t) );
    memset ( & getMutexData(),       0, sizeof(pthread_mutex_t)     );

    /* Create the Mutex Attributes */
    pthread_mutexattr_init ( & getMutexAttributes() );

    /* Decide how we are configuring it. */
    switch ( theMutexType )
    {
    case Mutex::FAST:
        mutexAttributeKind = PTHREAD_MUTEX_FAST_NP;
        break;

    case Mutex::RECURSIVE:
        mutexAttributeKind = PTHREAD_MUTEX_RECURSIVE_NP;
        break;

    case Mutex::ERROR_CHECK:
        mutexAttributeKind = PTHREAD_MUTEX_ERRORCHECK_NP;
        break;

    default:
        FLUSHALL();
        cerr << "[Mutex:Mutex]  Error:  Bad MutexType value:  "
             << int4(theMutexType) << ".  Defaulting to RECURSIVE Mutex."
             << endl;
        mutexType = Mutex::RECURSIVE;
        mutexAttributeKind = PTHREAD_MUTEX_RECURSIVE_NP;
    }


    /* Configure it appropriately.                  *
     * PTHREAD_MUTEX_SETKIND is defined in Mutex.H. */
    result = PTHREAD_MUTEX_SETKIND ( & getMutexAttributes(),
                                     mutexAttributeKind    );
    switch ( result )
    {
    case 0:  /* It worked */
        break;

    case EINVAL:
        FLUSHALL();
        cerr << "[Mutex:Mutex(Mutex::TYPE)]  Programmer Error:  "
             << "pthread_mutexattr_setkind_np(., " << mutexAttributeKind
             << ") failed with EINVAL.  Attempting to continue as FAST MUTEX."
             << endl;
        mutexType = Mutex::FAST;
        break;

    default:  /* What the hell? */
        FLUSHALL();
        cerr << "[Mutex:Mutex(Mutex::TYPE)]  UNKNOWN Error:  "
             << "pthread_mutexattr_setkind_np(., " << mutexAttributeKind
             << ") failed with: " << result
             << ".  Attempting to continue as FAST MUTEX."
             << endl;
        mutexType = Mutex::FAST;
        break;
    }

    /* And finally, initialize the mutex itself... */
    pthread_mutex_init ( & getMutexData(),
                         (   (result == 0)
                             ? & getMutexAttributes()
                             : (const pthread_mutexattr_t *)NULL ) );
}