int
mutex_try_enter (dk_mutex_t *mtx)
{
#ifndef MTX_DEBUG
#if HAVE_SPINLOCK
  if (MUTEX_TYPE_SPIN == mtx->mtx_type)
    return pthread_spin_trylock (&mtx->l.spinl) == TRYLOCK_SUCCESS ? 1 : 0;
  else
#endif
    return pthread_mutex_trylock ((pthread_mutex_t *) &mtx->mtx_mtx) == TRYLOCK_SUCCESS ? 1 : 0;
#else

  if (
#if HAVE_SPINLOCK
      MUTEX_TYPE_SPIN == mtx->mtx_type 
      ? pthread_spin_trylock (&mtx->l.spinl) == TRYLOCK_SUCCESS
      : 
#endif
      pthread_mutex_trylock ((pthread_mutex_t*) &mtx->mtx_mtx) == TRYLOCK_SUCCESS)
    {
      assert (mtx->mtx_owner == NULL);
      mtx->mtx_owner = thread_current ();
      return 1;
    }
  return 0;
#endif
}
Exemplo n.º 2
0
int main()
{
   pthread_t thread_id;
   int seconds = 3;
   int rc;

   printf("will init\n");
   pthread_spin_init(&lock, -1);

   printf("1\n");
   pthread_spin_lock(&lock);
   sleep(1);
   printf("2\n");


   rc =  pthread_create(&thread_id, NULL, g_start_timer, (void *) &seconds);
   if (rc)
      printf("=== Failed to create thread\n");

   printf("4\n");
   pthread_spin_unlock(&lock);
   sleep(1);
   if(0 != pthread_spin_trylock(&lock))
   {
      printf("6 failed to get trylock, as expected\n");
   }

#if 0
#endif
   pthread_join(thread_id, NULL);

   printf("=== End of Program - all threads in ===\n");

   return 0;
}
Exemplo n.º 3
0
/*
    Try to attain a lock. Do not block! Returns true if the lock was attained.
 */
PUBLIC bool mprTrySpinLock(MprSpin *lock)
{
    int     rc;

    if (lock == 0) return 0;

#if USE_MPR_LOCK
    mprTryLock(&lock->cs);
#elif MACOSX
    rc = !OSSpinLockTry(&lock->cs);
#elif ME_UNIX_LIKE && ME_COMPILER_HAS_SPINLOCK
    rc = pthread_spin_trylock(&lock->cs) != 0;
#elif ME_UNIX_LIKE
    rc = pthread_mutex_trylock(&lock->cs) != 0;
#elif ME_WIN_LIKE
    rc = (lock->freed) ? 0 : (TryEnterCriticalSection(&lock->cs) == 0);
#elif VXWORKS
    rc = semTake(lock->cs, NO_WAIT) != OK;
#endif
#if ME_DEBUG && COSTLY
    if (rc == 0) {
        assert(lock->owner != mprGetCurrentOsThread());
        lock->owner = mprGetCurrentOsThread();
    }
#endif
    return (rc) ? 0 : 1;
}
Exemplo n.º 4
0
void node_del_data_event(struct node *node)
{
	int ret;

	log_error("%s: del data event for node %d", __func__, node->id);
	ret = pthread_spin_trylock(&node->spinlock);
	if(ret != 0) {
		log_error("%s: del data event get lock failed", __func__);
		return;
	}

	if(node->data_event == NULL) {
		log_error("%s: null data_event for node %d, cancel", __func__, node->id);
		goto err;
	}

	shutdown(node->dfd, SHUT_RDWR);
	sock_close(node->dfd);
	node->dfd = -1;
	node->data_conn_state = NODE_DFD_DISCONNECTED;

	event_free(node->data_event);
	node->data_event = NULL;

	pthread_spin_unlock(&node->spinlock);

	clean_packet_queue(node->data_q);

	node_disconnect(node);

	return;

err:
	pthread_spin_unlock(&node->spinlock);
}
Exemplo n.º 5
0
bool locker::try_lock()
{
#ifdef	ACL_HAS_SPINLOCK
	if (spinlock_)
	{
		if (pthread_spin_trylock(spinlock_) != 0)
			return false;
	}
	else
#endif
	if (mutex_)
	{
		if (acl_pthread_mutex_trylock(mutex_) != 0)
			return false;
	}

	if (fHandle_ == ACL_FILE_INVALID)
		return true;

	int operation = ACL_FLOCK_OP_EXCLUSIVE | ACL_FLOCK_OP_NOWAIT;
	if (acl_myflock(fHandle_, ACL_FLOCK_STYLE_FCNTL, operation) == 0)
		return true;

	if (mutex_)
		acl_assert(acl_pthread_mutex_unlock(mutex_) == 0);
	return false;
}
Exemplo n.º 6
0
static void * func(void * arg)
{
  assert(pthread_spin_trylock(&lock) == EBUSY);

  washere = 1;

  return 0; 
}
Exemplo n.º 7
0
// funzione del thread
void *do_something(long int who_i_am) {
    int i;

    // finche' non vuoi uscire
    while (!wanna_exit) {
        i=rand()%9+1;
        // genera un intervallo casuale di tempo
        printf("Thread %ld: going to sleep for %d sec...\n",who_i_am,i);
        // se devi uscire
        if (wanna_exit) {
            printf("Thread %ld: exit...\n",who_i_am);
            // esci
            break;
        }
        // dormi per un intervallo casuale
        sleep(i);
        // se ti hanno svegliato per uscire
        if (wanna_exit) {
            printf("Thread %ld: exit...\n",who_i_am);
            // esci
            break;
        }
        // prova se lo spinlock e' libero
        if (pthread_spin_trylock(&spinlock)) {
            // in caso contrario avvisa
            printf("Thread %ld: wait for the spinlock...\n",who_i_am);
            // e aspetta
            pthread_spin_lock(&spinlock);
        }
        // da qui si ha il possesso dello spinlock
        // genera un intervallo casuale
        i=rand()%9+1;
        // esci se devi
        if (wanna_exit) {
            // non prima di aver sbloccato il mutex per l'altro processo
            pthread_spin_unlock(&spinlock);
            printf("Thread %ld: exit...\n",who_i_am);
            break;
        }
        // avvisi vari
        printf("Thread %ld: spinlock obtained and now wait for %d sec...\n",who_i_am,i);
        // dormi
        sleep(i);
        // se ti hanno svegliato per uscire
        if (wanna_exit) {
            // sblocca il mutex
            pthread_spin_unlock(&spinlock);
            printf("Thread %ld: exit...\n",who_i_am);
            // ed esci
            break;
        }
        // altrimenti rilascia il mutex
        printf("Thread %ld: unlock spinlock...\n",who_i_am);
        pthread_spin_unlock(&spinlock);
    }
    return NULL;
}
Exemplo n.º 8
0
int
devil_spinlock_trylock(devil_spinlock_t* spinlock)
{
  int ret = pthread_spin_trylock(spinlock);
  if (0 != ret && EBUSY != ret && EAGAIN != ret)
    abort();

  return ret;
}
Exemplo n.º 9
0
bool spinlock_trylock(spinlock_t *lock)
{
    const int err = pthread_spin_trylock(lock);
    if (err == 0) return true;
    else if (err == EBUSY) return false;
    else {
        error("spinlock error: %s", errno_error(err));
        return false;
    }
}
Exemplo n.º 10
0
void *reader( void *ptr)
{
    struct timespec start, end;
    int tid = *((int *) ptr);
    uint64_t seed = 0xdeadbeef + tid;
    int sum = 0, i;

    /** < The node and lock to use in an iteration */
    int node_id, lock_id;

    /** < Total number of iterations (for measurement) */
    int num_iters = 0;

    clock_gettime(CLOCK_REALTIME, &start);

    while(1) {
        if(num_iters == ITERS_PER_MEASUREMENT) {
            clock_gettime(CLOCK_REALTIME, &end);
            double seconds = (end.tv_sec - start.tv_sec) +
                             (double) (end.tv_nsec - start.tv_nsec) / GHZ_CPS;

            printf("Reader thread %d: rate = %.2f M/s. Sum = %d\n", tid,
                   num_iters / (1000000 * seconds), sum);

            num_iters = 0;
            clock_gettime(CLOCK_REALTIME, &start);
        }

        node_id = fastrand(&seed) & NUM_NODES_;
        lock_id = node_id & NUM_LOCKS_;

#if USE_SKIP == 1
        while(pthread_spin_trylock(&locks[lock_id].lock) == EBUSY) {
            lock_id = (lock_id + 1) & NUM_LOCKS_;
        }
#else
        pthread_spin_lock(&locks[lock_id].lock);

        /** < Critical section begin */
        if(nodes[node_id].b != nodes[node_id].a + 1) {
            red_printf("Invariant violated\n");
        }
#endif
        for(i = 0; i < WRITER_COMPUTE; i ++) {
            sum += CityHash32((char *) &nodes[node_id].a, 4);
            sum += CityHash32((char *) &nodes[node_id].b, 4);
        }

        /** < Critical section end */

        pthread_spin_unlock(&locks[lock_id].lock);

        num_iters ++;
    }
}
Exemplo n.º 11
0
int _starpu_spin_trylock(starpu_spinlock_t *lock)
{
#ifdef HAVE_PTHREAD_SPIN_LOCK
	int ret =  pthread_spin_trylock(&lock->lock);
	STARPU_ASSERT(!ret || (ret == EBUSY));
	return ret;
#else
	uint32_t prev;
	prev = STARPU_TEST_AND_SET(&lock->taken, 1);
	return (prev == 0)?0:EBUSY;
#endif
}
Exemplo n.º 12
0
	bool try_lock() {
		int ret;
		do {
			ret = pthread_spin_trylock(&spin);
		} while (OXT_UNLIKELY(ret == EINTR));
		if (ret == 0) {
			return true;
		} else if (ret == EBUSY) {
			return false;
		} else {
			throw boost::thread_resource_error(ret, "Cannot lock spin lock");
		}
	}
Exemplo n.º 13
0
rtems_task SpinlockThread(rtems_task_argument arg)
{
  int  status;

  puts( "pthread_spin_trylock( &Spinlock ) -- EBUSY" );
  status = pthread_spin_trylock( &Spinlock );
  rtems_test_assert(  status == EBUSY );

  puts( "pthread_spin_unlock( &Spinlock ) -- EPERM" );
  status = pthread_spin_unlock( &Spinlock );
  rtems_test_assert(  status == EPERM );

  rtems_task_delete( RTEMS_SELF );
}
Exemplo n.º 14
0
static void 
faultd_signal_handler__(int signal, siginfo_t* siginfo, void* context)
{
    int rv; 

    /*
     * Make sure we syncronize properly with other threads that
     * may *also* be faulting
     */
    rv = pthread_spin_trylock(&thread_lock__); 

    if (rv == EBUSY) { 
        sigset_t mask; 
        sigemptyset(&mask); 
        pselect(0, NULL, NULL, NULL, NULL, &mask); 
    }
    
    /*
     * Generate our fault information. 
     */ 
    faultd_info__.pid = getpid(); 
    faultd_info__.tid = 0; 
    faultd_info__.signal = signal; 
    faultd_info__.signal_code = siginfo->si_code; 
    faultd_info__.fault_address = siginfo->si_addr; 
    faultd_info__.last_errno = errno; 

    faultd_info__.backtrace_size = signal_backtrace__(faultd_info__.backtrace, 
                                                      AIM_ARRAYSIZE(faultd_info__.backtrace),
                                                      context, 0); 
    faultd_info__.backtrace_symbols = (void*)1; 
    if(faultd_client__) { 
        faultd_client_write(faultd_client__, &faultd_info__); 
    }
    if(localfd__ >= 0) { 
        char* signame = strsignal(faultd_info__.signal); 
        char* nl = "\n"; 
        write(localfd__, signame, strlen(signame)+1); 
        write(localfd__, nl, 2); 
        backtrace_symbols_fd(faultd_info__.backtrace, 
                             faultd_info__.backtrace_size, 
                             localfd__); 
    }

    /* 
     * Unlock spinlock, in case this signal wasn't fatal
     */
    pthread_spin_unlock(&thread_lock__); 
}
Exemplo n.º 15
0
	Bool HawkSpinLock::TryLock(const AString& sFile,Int32 iLine)
	{
		HawkAssert(m_pSpinLock);

		if (pthread_spin_trylock((pthread_spinlock_t*)m_pSpinLock) == HAWK_OK)
		{
#ifdef _DEBUG
			m_bLocked = true;
			m_sFile   = sFile;
			m_iLine   = iLine;
			m_iThread = HawkOSOperator::GetThreadId();
#endif
			return true;
		}
		return false;
	}
Exemplo n.º 16
0
Arquivo: 1-1.c Projeto: jiezh/h5vcc
int main()
{
	pthread_t child_thread;
	
	if(pthread_spin_init(&spinlock, PTHREAD_PROCESS_PRIVATE) != 0)
	{
		printf("main: Error at pthread_spin_init()\n");
		return PTS_UNRESOLVED;
	}

	printf("main: attempt to trylock\n");

	/* We should get the lock */	
	if(pthread_spin_trylock(&spinlock) != 0)
	{
		printf("Test FAILED: main cannot get spin lock when no one owns the lock\n");
		return PTS_FAIL;
	} 
	printf("main: acquired spin lock\n");
	
	thread_state = NOT_CREATED_THREAD;
	printf("main: create thread\n");
	if(pthread_create(&child_thread, NULL, fn_chld, NULL) != 0)
	{
		printf("main: Error creating child thread\n");
		return PTS_UNRESOLVED;
	}
	
	/* Wait for thread to end execution */
	pthread_join(child_thread, NULL);

	/* Check the return code of pthread_spin_trylock */
	if(rc != EBUSY)
	{
		printf("Test FAILED: pthread_spin_trylock should return EBUSY, instead got error code:%d\n" , rc);
		return PTS_FAIL;
	} 
	
	printf("thread: correctly returned EBUSY on trylock\n");
	printf("Test PASSED\n");
	return PTS_PASS;
	
}
Exemplo n.º 17
0
int core_lock_trylock(struct core_lock *self)
{
#if defined(CORE_LOCK_USE_COMPARE_AND_SWAP)
    int old_value = 0;
    int new_value = 1;

    if (core_atomic_compare_and_swap_int(&self->lock, old_value, new_value) == old_value) {
        /* successful */
        return CORE_LOCK_SUCCESS;
    }

    /* not successful
     */
    return CORE_LOCK_ERROR;

#elif defined(CORE_LOCK_USE_SPIN_LOCK)
    return pthread_spin_trylock(&self->lock);
#elif defined(CORE_LOCK_USE_MUTEX)
    return pthread_mutex_trylock(&self->lock);
#endif
}
Exemplo n.º 18
0
// funzione realtiva allo spinlock
void *do_something(long int who_i_am) {
    int i;
    int dummy;

    // imposta la cancellazione asincrona
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,&dummy);
    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,&dummy);

    // aspetta che pure l'altro thread l'abbia fatto
    pthread_barrier_wait(&pbarrier);
    // sblocca il segnale SIGUSR1
    pthread_sigmask(SIG_UNBLOCK,&block_sig,NULL);

    while (1) {
        // selezione un intervallo casuale di tempo
        i=rand()%9+1;
        // avvisa
        printf("Thread %ld: going to sleep for %d sec...\n",who_i_am,i);
        // e dormi
        sleep(i);
        // prova ad acquisire lo spinlock
        if (pthread_spin_trylock(&spinlock)) {
            // in caso contrario avvisa
            printf("Thread %ld: wait for the spinlock...\n",who_i_am);
            // e attendi
            pthread_spin_lock(&spinlock);
        }
        // da qui ho acquisito lo spinlock
        // seleziona un intervallo casuale di tempo
        i=rand()%9+1;
        // avvisa
        printf("Thread %ld: spinlock obtained and now wait for %d sec...\n",who_i_am,i);
        // e dormi
        sleep(i);
        printf("Thread %ld: unlock spinlock...\n",who_i_am);
        // rilascia lo spinlock
        pthread_spin_unlock(&spinlock);
    }
    return NULL;
}
Exemplo n.º 19
0
Arquivo: 1-1.c Projeto: jiezh/h5vcc
static void* fn_chld(void *arg)
{ 
	struct sigaction act;
	thread_state = ENTERED_THREAD;

	rc = 0;
	
	/* Set up child thread to handle SIGALRM */
	act.sa_flags = 0;
	act.sa_handler = sig_handler;
	sigfillset(&act.sa_mask);
	sigaction(SIGALRM, &act, 0);
	
	/* thread: send SIGALRM to me after 2 seconds in case in spins on trylock */
	alarm(2);

	printf("thread: attempt trylock\n");
	rc = pthread_spin_trylock(&spinlock);

	pthread_exit(0);
	return NULL;
}
Exemplo n.º 20
0
static int
do_test (void)
{
  pthread_spinlock_t s;

  if (pthread_spin_init (&s, PTHREAD_PROCESS_PRIVATE) != 0)
    {
      puts ("spin_init failed");
      return 1;
    }

  if (pthread_spin_lock (&s) != 0)
    {
      puts ("1st spin_lock failed");
      return 1;
    }

  /* Set an alarm for 1 second.  The wrapper will expect this.  */
  alarm (1);

#ifdef ORIGINAL_TEST /* ORIGINAL */
  /* This call should never return.  */
  pthread_spin_lock (&s);

  puts ("2nd spin_lock returned");
#else /* !ORIGINAL */
  int r = pthread_spin_lock (&s);
  if (!r) {
    puts ("2nd spin_lock succeeded");
  } else if (r != EDEADLOCK) {
    puts ("2nd spin_lock failed but did not EDEADLOCKed");
  }
// needed to avoid freezing linux
  pthread_soft_real_time_np();
  while (pthread_spin_trylock (&s) == EBUSY) rt_sleep(nano2count(10000));
#endif /* ORIGINAL */
  return 1;
}
Exemplo n.º 21
0
 inline bool TryLock()
 {
     return pthread_spin_trylock(&m_raw_lock) == 0;
 }
Exemplo n.º 22
0
	bool try_lock() { return pthread_spin_trylock(&_psl) == 0; }
Exemplo n.º 23
0
int main()
{
	
	/* Make sure there is process-shared capability. */ 
	#ifndef PTHREAD_PROCESS_SHARED
	  fprintf(stderr,"process-shared attribute is not available for testing\n");
	  return PTS_UNSUPPORTED;	
	#endif

	int pshared = PTHREAD_PROCESS_SHARED;
	
	char shm_name[] = "tmp_pthread_spinlock_getpshared";
	int shm_fd;
	int pid;
	
	/* Create shared object */
	shm_unlink(shm_name);
	shm_fd = shm_open(shm_name, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
	if(shm_fd == -1)
	{
		perror("Error at shm_open()");
		return PTS_UNRESOLVED;
	}
     
        if(ftruncate(shm_fd, sizeof(struct shmstruct)) != 0) {
                perror("Error at ftruncate()");
                shm_unlink(shm_name);
                return PTS_UNRESOLVED;
        }
	
	/* Map the shared memory object to parent's memory */
	spinlock_data = mmap(NULL, sizeof(struct shmstruct), PROT_READ|PROT_WRITE, 
				MAP_SHARED, shm_fd, 0);

	if(spinlock_data == MAP_FAILED)
	{
		perror("Error at first mmap()");
                shm_unlink(shm_name);
		return PTS_UNRESOLVED;
	}

	/* Initialize spinlock */	
	if((pthread_spin_init(&(spinlock_data->spinlock), pshared)) != 0)
	{
		printf("Test FAILED: Error at pthread_rwlock_init()\n");
		return PTS_FAIL;
	}
	
	printf("main: attempt spin lock\n");	
	if((pthread_spin_lock(&(spinlock_data->spinlock))) != 0)
	{
		printf("Error at pthread_spin_lock()\n");
		return PTS_UNRESOLVED;
	}
	printf("main: acquired spin lock\n");

	/* Initialize spinlock data */
	spinlock_data->data = 0;

	/* Fork a child process */	
	pid = fork();
	if(pid == -1)
	{
		perror("Error at fork()");
		return PTS_UNRESOLVED;
	}
	else if(pid > 0)
	{
		/* Parent */
		/* wait until child writes to spinlock data */
		while(spinlock_data->data != 1)
			sleep(1);
		
		printf("main: unlock spin lock\n");
		if(pthread_spin_unlock(&(spinlock_data->spinlock)) != 0)
		{
			printf("Parent: error at pthread_spin_unlock()\n");
			return PTS_UNRESOLVED;
		}
	
		/* Tell child that parent unlocked the spin lock */
		spinlock_data->data = 2;
	
		/* Wait until child ends */
		wait(NULL);
		
		if((shm_unlink(shm_name)) != 0)
		{
			perror("Error at shm_unlink()");
			return PTS_UNRESOLVED;
		}	
		
		printf("Test PASSED\n");
		return PTS_PASS;
	}
	else
	{
		/* Child */
		/* Map the shared object to child's memory */
		spinlock_data = mmap(NULL, sizeof(struct shmstruct), PROT_READ|PROT_WRITE, 
				MAP_SHARED, shm_fd, 0);

		if(spinlock_data == MAP_FAILED)
		{
			perror("child : Error at mmap()");
			return PTS_UNRESOLVED;
		}
		
		printf("child: attempt spin lock\n");
		if((pthread_spin_trylock(&(spinlock_data->spinlock))) != EBUSY)
		{
			printf("Test FAILED: Child expects EBUSY\n");
			return PTS_FAIL;
		} 
		printf("child: correctly got EBUSY\n");	
		
		/* Tell parent it can unlock now */
		spinlock_data->data = 1;
	
		/* Wait for parent to unlock spinlock */	
		while(spinlock_data->data != 2)
			sleep(1);
		
		/* Child tries to get spin lock after parent unlock, 
		 * it should get the lock. */
		printf("child: attempt spin lock\n");
		if((pthread_spin_trylock(&(spinlock_data->spinlock))) != 0)
		{
			printf("Test FAILED: Child should get the lock\n");
			return PTS_FAIL;
		} 
		printf("child: acquired spin lock\n");	

		printf("child: unlock spin lock\n");	
		if(pthread_spin_unlock(&(spinlock_data->spinlock)) != 0)
		{
			printf("Child: error at pthread_spin_unlock()\n");
			return PTS_UNRESOLVED;
		}

		if(pthread_spin_destroy(&(spinlock_data->spinlock)) != 0)
		{
			printf("Child: error at pthread_spin_destroy()\n");
			return PTS_UNRESOLVED;
		}
	}
}
Exemplo n.º 24
0
	int trylock()
	{
		return pthread_spin_trylock(&locker);
	}
Exemplo n.º 25
0
static int swSpinLock_trylock(swLock *lock)
{
	return pthread_spin_trylock(&lock->object.spinlock.lock_t);
}
Exemplo n.º 26
0
int main(int argc, char ** argv){

	pthread_spinlock_t * sl1;
	int rv,fd;
	int * count;
	short rv_short;
	int i,x=0;
	void * map_region;
	char * file;

	if (argc!=2){
		fprintf(stderr, "USAGE: guestlock <file>\n");
		exit(-1);	
	}
	
	file=strdup(argv[1]);	
	
	printf("[GUESTLOCK] locking on file %s\n", file);

	if ((fd=open(file, O_RDWR)) < 0){
		fprintf(stderr, "ERROR: cannot open file\n");
		exit(-1);
	}

	if ((map_region=mmap(NULL, 1024, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0))<0){
		fprintf(stderr, "ERROR: cannot mmap file\n");
	} else {
		printf("[GRABLOCK] mapped to %p\n", map_region);
	}

	sl1=map_region;
	count=map_region + sizeof(pthread_spinlock_t);

	printf("[GRABLOCK] init locking (0x%x)\n", sl1);
//	pthread_spin_init(sl1, PTHREAD_PROCESS_SHARED);

	/* this would lock the lock */

	rv=pthread_spin_trylock(sl1);

	printf("rv=%d\n",rv);
	sleep(1);

	/* close the file and unmap the region */
	pthread_spin_destroy(sl1);
	munmap(map_region,1024);
	close(fd);

	printf("[GRABLOCK] exiting\n");
/*	
	rv=pthread_spin_trylock(sl1);
	printf("retval is %d\n", rv);

	rv=pthread_spin_lock(sl1);
	printf("retval is %d\n", rv); 
*/

/*	rv=pthread_spin_lock(sl1);
	printf("retval is %d\n", rv);

	rv=pthread_spin_lock(sl1);
	printf("retval is %d\n", rv);
*/
}
Exemplo n.º 27
0
int main(
  int    argc,
  char **argv
)
#endif
{
  pthread_spinlock_t    spinlock;
  int                   status;
  rtems_status_code     rstatus;
  rtems_id              taskid;

  puts( "\n\n*** POSIX SPINLOCK TEST 01 ***" );

  puts( "pthread_spin_init( NULL, PTHREAD_PROCESS_PRIVATE ) -- EINVAL" );
  status = pthread_spin_init( NULL, PTHREAD_PROCESS_PRIVATE );
  rtems_test_assert( status == EINVAL );

  puts( "pthread_spin_init( NULL, PTHREAD_PROCESS_SHARED ) -- EINVAL" );
  status = pthread_spin_init( NULL, PTHREAD_PROCESS_PRIVATE );
  rtems_test_assert( status == EINVAL );

  puts( "pthread_spin_init( &spinlock, 0x1234 ) -- EINVAL" );
  status = pthread_spin_init( &spinlock, 0x1234 );
  rtems_test_assert( status == EINVAL );

  puts( "pthread_spin_init( &spinlock, PTHREAD_PROCESS_SHARED ) -- EINVAL" );
  status = pthread_spin_init( &spinlock, PTHREAD_PROCESS_SHARED );
  rtems_test_assert( status == EINVAL );

  /* This successfully creates one */
  puts( "pthread_spin_init( &Spinlock, PTHREAD_PROCESS_PRIVATE ) -- OK" );
  status = pthread_spin_init( &Spinlock, PTHREAD_PROCESS_PRIVATE );
  rtems_test_assert( status == 0 );

  puts( "pthread_spin_init( &spinlock, PTHREAD_PROCESS_PRIVATE ) -- EAGAIN" );
  status = pthread_spin_init( &spinlock, PTHREAD_PROCESS_PRIVATE );
  rtems_test_assert( status == EAGAIN );

  puts( "pthread_spin_init( &spinlock, PTHREAD_PROCESS_PRIVATE ) -- EAGAIN" );
  status = pthread_spin_init( &spinlock, PTHREAD_PROCESS_PRIVATE );
  rtems_test_assert( status == EAGAIN );

  puts( "pthread_spin_lock( NULL ) -- EINVAL" );
  status = pthread_spin_lock( NULL );
  rtems_test_assert( status == EINVAL );

  puts( "pthread_spin_trylock( NULL ) -- EINVAL" );
  status = pthread_spin_trylock( NULL );
  rtems_test_assert( status == EINVAL );

  puts( "pthread_spin_unlock( NULL ) -- EINVAL" );
  status = pthread_spin_unlock( NULL );
  rtems_test_assert( status == EINVAL );

  puts( "pthread_spin_destroy( NULL ) -- EINVAL" );
  status = pthread_spin_destroy( NULL );
  rtems_test_assert( status == EINVAL );

  spinlock = 0;

  puts( "pthread_spin_lock( &spinlock ) -- EINVAL" );
  status = pthread_spin_lock( &spinlock );
  rtems_test_assert( status == EINVAL );

  puts( "pthread_spin_trylock( &spinlock ) -- EINVAL" );
  status = pthread_spin_trylock( &spinlock );
  rtems_test_assert( status == EINVAL );

  puts( "pthread_spin_unlock( &spinlock ) -- EINVAL" );
  status = pthread_spin_unlock( &spinlock );
  rtems_test_assert( status == EINVAL );

  puts( "pthread_spin_destroy( &spinlock ) -- EINVAL" );
  status = pthread_spin_destroy( &spinlock );
  rtems_test_assert( status == EINVAL );

  puts( "pthread_spin_unlock( &Spinlock ) -- already unlocked OK" );
  status = pthread_spin_unlock( &Spinlock );
  rtems_test_assert( status == 0 );

  /* Now some basic locking and unlocking with a deadlock verification */
  puts( "pthread_spin_lock( &Spinlock ) -- OK" );
  status = pthread_spin_lock( &Spinlock );
  rtems_test_assert( status == 0 );

  puts( "pthread_spin_lock( &Spinlock ) -- EDEADLK" );
  status = pthread_spin_lock( &Spinlock );
  rtems_test_assert( status == EDEADLK );

  puts( "pthread_spin_trylock( &Spinlock ) -- EDEADLK" );
  status = pthread_spin_trylock( &Spinlock );
  rtems_test_assert( status == EDEADLK );

  puts( "pthread_spin_unlock( &Spinlock ) -- OK" );
  status = pthread_spin_unlock( &Spinlock );
  rtems_test_assert( status == 0 );

  /* Try lock/unlock pair */
  puts( "pthread_spin_trylock( &Spinlock ) -- OK" );
  status = pthread_spin_trylock( &Spinlock );
  rtems_test_assert( status == 0 );

  puts( "pthread_spin_unlock( &Spinlock ) -- OK" );
  status = pthread_spin_unlock( &Spinlock );
  rtems_test_assert( status == 0 );

  /* Let another thread lock a spinlock and we contend with it */

  mainThreadSpinning = 0;

  /*  Create a helper task */
  rstatus = rtems_task_create(
     rtems_build_name( 'S', 'P', 'I', 'N' ),
     1,
     RTEMS_MINIMUM_STACK_SIZE,
     RTEMS_DEFAULT_MODES,
     RTEMS_DEFAULT_ATTRIBUTES,
     &taskid
  );
  rtems_test_assert( rstatus == RTEMS_SUCCESSFUL );

  rstatus = rtems_task_start( taskid, SpinlockThread, 0 );
  rtems_test_assert( rstatus == RTEMS_SUCCESSFUL );
  /* We should be preempted immediately.  The thread is expected to:
   *    + verify we haven't set the main thread spinning flag
   *    + lock the spinlock
   *    + delay
   */

  mainThreadSpinning = 1;
  puts( "pthread_spin_lock( &Spinlock ) -- OK" );
  status = pthread_spin_lock( &Spinlock );
  rtems_test_assert( status == 0 );

  /* The thread wakes up, unlocks spin lock, and deletes itself.
   * So when we get back here, about a second has passed and we now
   * have the spinlock locked.
   */

  /* spin lock should be locked when we return so destroying it gives busy */
  puts( "pthread_spin_destroy( &Spinlock ) -- EBUSY" );
  status = pthread_spin_destroy( &Spinlock );
  rtems_test_assert( status == EBUSY );

  /* Unlock it for a normal destroy */
  puts( "pthread_spin_unlock( &Spinlock ) -- OK" );
  status = pthread_spin_unlock( &Spinlock );
  rtems_test_assert( status == 0 );

  puts( "pthread_spin_destroy( &Spinlock ) -- OK" );
  status = pthread_spin_destroy( &Spinlock );
  rtems_test_assert( status == 0 );

  /*************** END OF TEST *****************/
  puts( "*** END OF POSIX SPINLOCK TEST 01 ***" );
  exit(0);
}
Exemplo n.º 28
0
int
mutex_enter (dk_mutex_t *mtx)
#endif
{
#ifdef MTX_DEBUG
  du_thread_t * self = thread_current ();
#endif
  int rc;

#ifdef MTX_DEBUG
  assert (mtx->mtx_owner !=  self || !self);
  if (mtx->mtx_entry_check
      && !mtx->mtx_entry_check (mtx, self, mtx->mtx_entry_check_cd))
    GPF_T1 ("Mtx entry check fail");
#endif
#ifdef MTX_METER
#if HAVE_SPINLOCK
  if (MUTEX_TYPE_SPIN == mtx->mtx_type)
    rc = pthread_spin_trylock (&mtx->l.spinl);
  else 
#endif
    rc = pthread_mutex_trylock ((pthread_mutex_t*) &mtx->mtx_mtx);
  if (TRYLOCK_SUCCESS != rc)
    {
      long long wait_ts = rdtsc ();
      static int unnamed_waits;
#if HAVE_SPINLOCK
      if (MUTEX_TYPE_SPIN == mtx->mtx_type)
	rc = pthread_spin_lock (&mtx->l.spinl);
      else
#endif
	rc = pthread_mutex_lock ((pthread_mutex_t*) &mtx->mtx_mtx);
      mtx->mtx_wait_clocks += rdtsc () - wait_ts;
      mtx->mtx_waits++;
      if (!mtx->mtx_name)
	unnamed_waits++; /*for dbg breakpoint */
      mtx->mtx_enters++;
    }
  else
    mtx->mtx_enters++;
#else
#if HAVE_SPINLOCK
  if (MUTEX_TYPE_SPIN == mtx->mtx_type)
    rc = pthread_spin_lock (&mtx->l.spinl);
  else
#endif
    rc = pthread_mutex_lock ((pthread_mutex_t*) &mtx->mtx_mtx);
#endif
  CKRET (rc);
#ifdef MTX_DEBUG
  assert (mtx->mtx_owner == NULL);
  mtx->mtx_owner = self;
  mtx->mtx_entry_file = (char *) file;
  mtx->mtx_entry_line = line;
#endif
  return 0;

failed:
  GPF_T1 ("mutex_enter() failed");
  return -1;
}
Exemplo n.º 29
0
/* The fault handler function.
*
* OK. The rules of the battle are those:
*
* 1. Can't use any function that relies on malloc and friends working as the malloc arena may be corrupt.
* 2. Can only use a the POSIX.1-2003 list of async-safe functions.
* 3. Some of the functions on the list are not always safe (like fork when atfork() is used),
* so need to avoid these also.
* 4. No locking allowed. We don't know in what state the process/thread was when the exception
* occured.
*/
void fault_handler (int signal, siginfo_t * siginfo, void *context) {
	int i, ret;

#ifdef USE_THREADS

	ret=pthread_spin_trylock(&g_thread_lock);
	if (EBUSY==ret) {
		/* Think of the following as an async-signal safe super sched_yield that
		* yields even to threads with lower real-time priority */
		sigset_t smask;
		sigemptyset(&smask);
		pselect(0, NULL, NULL, NULL, NULL, &smask);
	}

#endif /* USE_THREADS */

	/* Get the backtrace. See signal_backtrace for the parameters */

	g_crash_msg.num_backtrace_frames=signal_backtrace(g_crash_msg.backtrace,
			CRASH_MAX_BACKTRACE_DEPTH, context, 0);

	/* Grab the kernel thread id. Because signal handler are shared between all
	* threads of the same process, this can only be doen in fault time. */

	g_crash_msg.thread_id=gettid();

	/* Grab the signal number */
	g_crash_msg.signal_number=signal;

	/* Grab time stamp */
	clock_gettime(CLOCK_REALTIME, &g_crash_msg.timestamp);

	/* Copy the assert buffer without using strings.h fucntions. */
	for(i=0; i< CRASH_ASSERT_BUFFER_SIZE; ++i) {
		g_crash_msg.assert_buffer[i]=*(g_assert_buf_ptr++);
	}

	if (siginfo) /* No reasons for this to be NULL, but still... */
	{
		/* See description of these in crash_msg.h */
		g_crash_msg.signal_code=siginfo->si_code;
		g_crash_msg.fault_address=siginfo->si_addr;
		g_crash_msg.signal_errno=siginfo->si_errno;
		g_crash_msg.handler_errno=errno;
	}

retry_write:

	ret=write(g_logfd, &g_crash_msg, sizeof(g_crash_msg));

	/* If we got interrupt by a signal, retry the write.
	* This shouldn't really happen since we mask all signals
	* during the handler run via sigaction sa_mask field but
	* it can't hurt to test.
	*
	* It's useless to test for any other condition since we
	* can't do anything if we fail
	*/
	if(ret && EINTR==errno) goto retry_write;

	/* We use backtrace_symbols_fd rather then backtrace_symbols since
	* the latter uses malloc to allocate memory and if we got here
	* because of malloc arena curroption we'll double fault.
	*/
	backtrace_symbols_fd(g_crash_msg.backtrace, g_crash_msg.num_backtrace_frames, g_logfd);

	close(g_logfd);

	/* Produce a core dump for post morteum debugging */
	abort();

	assert(0 /* Not Reached */);

	return;
}
Exemplo n.º 30
0
static int
do_test (void)
{
  size_t ps = sysconf (_SC_PAGESIZE);
  char tmpfname[] = "/tmp/tst-spin2.XXXXXX";
  char data[ps];
  void *mem;
  int fd;
  pthread_spinlock_t *s;
  pid_t pid;
  char *p;
  int err;

  fd = mkstemp (tmpfname);
  if (fd == -1)
    {
      printf ("cannot open temporary file: %m\n");
      return 1;
    }

  /* Make sure it is always removed.  */
  unlink (tmpfname);

  /* Create one page of data.  */
  memset (data, '\0', ps);

  /* Write the data to the file.  */
  if (write (fd, data, ps) != (ssize_t) ps)
    {
      puts ("short write");
      return 1;
    }

  mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  if (mem == MAP_FAILED)
    {
      printf ("mmap failed: %m\n");
      return 1;
    }

  s = (pthread_spinlock_t *) (((uintptr_t) mem
			       + __alignof (pthread_spinlock_t))
			      & ~(__alignof (pthread_spinlock_t) - 1));
  p = (char *) (s + 1);

  if (pthread_spin_init (s, PTHREAD_PROCESS_SHARED) != 0)
    {
      puts ("spin_init failed");
      return 1;
    }

  if (pthread_spin_lock (s) != 0)
    {
      puts ("spin_lock failed");
      return 1;
    }

  err = pthread_spin_trylock (s);
  if (err == 0)
    {
      puts ("1st spin_trylock succeeded");
      return 1;
    }
  else if (err != EBUSY)
    {
      puts ("1st spin_trylock didn't return EBUSY");
      return 1;
    }

  err = pthread_spin_unlock (s);
  if (err != 0)
    {
      puts ("parent: spin_unlock failed");
      return 1;
    }

  err = pthread_spin_trylock (s);
  if (err != 0)
    {
      puts ("2nd spin_trylock failed");
      return 1;
    }

  *p = 0;

  puts ("going to fork now");
  pid = fork ();
  if (pid == -1)
    {
      puts ("fork failed");
      return 1;
    }
  else if (pid == 0)
    {
      /* Play some lock ping-pong.  It's our turn to unlock first.  */
      if ((*p)++ != 0)
	{
	  puts ("child: *p != 0");
	  return 1;
	}

      if (pthread_spin_unlock (s) != 0)
	{
	  puts ("child: 1st spin_unlock failed");
	  return 1;
	}

      puts ("child done");
    }
  else
    {
      if (pthread_spin_lock (s) != 0)
	{
	  puts ("parent: 2nd spin_lock failed");
	  return 1;
	}

      puts ("waiting for child");

      waitpid (pid, NULL, 0);

      puts ("parent done");
    }

  return 0;
}