예제 #1
0
파일: buffer.c 프로젝트: necto/verifast
void consumer(struct buffer *b)
  /*@ requires [_]b->m |-> ?m &*&
               [_]b->v |-> ?v &*& 
               [_]mutex(m) &*& 
               inv(m) == buffer(b) &*& 
               [_]b->gid |-> ?gid &*&
               obs(?O) &*&
               tic(gid) &*&
               no_cycle(v,O) == true &*&
               no_cycle(m,O) == true; @*/
  /*@ ensures  [_]b->m |-> m &*&
               [_]b->v |-> v &*& 
               [_]mutex(m) &*& 
               obs(O); @*/
{
  //@ close mutex_inv(m,buffer(b));
  mutex_acquire(b->m);
  //@ open buffer(b)(?Wt1,?Ot1);
  //@ leak [_]b->v |-> v;
  
  while (size_of(b->q)==0)
  /*@ invariant [_]b->m |-> m &*& 
                [_]b->v |-> v &*& 
                b->q |-> ?q &*& 
                [_]b->gid |-> gid &*& 
                queue(q,?s) &*& 
                s>=0 &*& 
                mutex_held(m, _, ?Wt, ?Ot) &*& 
                ctr(gid,?Ct) &*&
                Wt(v) + Ct <= Ot(v) + s &*&
                Wt(v) <= Ot(v) &*&
                obs(cons(m,O)) &*&
                tic(gid); @*/
  {
    //@ dec_ctr(gid);
    //@ close buffer(b)(finc(Wt,v),Ot);
    //@ close mutex_inv(m,buffer(b));
    //@ close condvar_trn(v,vtrn(gid));
    condvar_wait(b->v, b->m);
    //@ open buffer(b)(_,_);
    //@ open vtrn(gid)();
  }
  dequeue(b->q);
  //@ dec_ctr(gid);
  //@ close buffer(b)(Wt, Ot);
  //@ close mutex_inv(m,buffer(b));
  mutex_release(b->m);
  //@ leak [_]mutex(m);
}
예제 #2
0
파일: Platform.c 프로젝트: ATLTed/wonder
void WA_lock(WA_recursiveLock _lock)
#endif
{
   NSAPIThreadRecursiveLock *lock = (NSAPIThreadRecursiveLock *)_lock;
   SYS_THREAD self = systhread_current();
#ifdef EXTRA_DEBUGGING_LOGS
   if (_lock != logMutex)
      WOLog(WO_DBG, "  locking %s from %s:%d", lock->name, file, line);
#endif
   crit_enter(lock->crit);
   while (lock->lockingThread != self && lock->lockCount != 0)
      condvar_wait(lock->condvar);
   lock->lockingThread = self;
   lock->lockCount++;
   crit_exit(lock->crit);
}
/*
 * This method sends packets from the queue
 *
 * @param send_func Function pointer to radio send function
 * @p Parameters of environment
 */
void bs_send(void* send_func, bs_params_t* p) {
  message_t m;
  message_t* m_ptr;

  for(;;) {
    mutex_lock( &(p->mutex) );
	    while( (m_ptr = dequeueMsg(p)) == NULL )
	      condvar_wait( &(p->condvar), &(p->mutex) );
	    m = *m_ptr;
	  mutex_unlock( &(p->mutex) );
	  condvar_signalAll( &(p->condvar) );

	  if(TOS_NODE_ID == 0) {
	    // we just received a serial msg
	    sendSerialMsg(&m);
	  } else {
	    // we just receive a radio msg
	    sendRadioMsg(&m);
	  }
  }
}
/*
 * This method is called when a packet is received
 *
 * @param recv_func Function pointer to either serial or radio receive function
 * @p Parameters of environment
 */
void bs_receive(error_t (*recv_func)(message_t*, uint32_t, am_id_t), bs_params_t* p) {
  message_t m;
  BlinkToRadioMsg_t* btrpkt;

  for(;;) {
    if( (*(recv_func))(&m, 0, AM_RECEIVE_FROM_ANY) == SUCCESS ) {
      btrpkt = (BlinkToRadioMsg_t*)radioGetPayload(&m, sizeof(BlinkToRadioMsg_t));
      if( isValidMsgID(btrpkt->msgID) ) { //only accept if new msgID
        messageID = btrpkt->msgID;  //save newest msgID
        if(isValidDestination(btrpkt->destMask)){ //check if current mote is addressed
          setLeds(btrpkt->ledID);
        }
	      mutex_lock( &(p->mutex) );
	        while( enqueueMsg(p, &m) == FAIL )
	          condvar_wait( &(p->condvar), &(p->mutex) );
	      mutex_unlock( &(p->mutex) );
	      condvar_signalAll( &(p->condvar) );
      }
	  }
  }
}
예제 #5
0
파일: bitc_ui.c 프로젝트: jma127/bitc-rpc
int bitcui_start(bool withui) {
  int res;

  btcui->inuse = withui;
  btcui->lock = mutex_alloc();
  btcui->cv = condvar_alloc();
  btcui->blockProdIdx = -1;
  btcui->blockConsIdx = -1;

  if (btcui->inuse == 0) {
    return 0;
  }

  Log(LGPFX " starting ui thread.\n");

  res = pthread_create(&btcui->tid, NULL, bitcui_main, NULL);
  ASSERT(res == 0);

  mutex_lock(btcui->lock);
  condvar_wait(btcui->cv, btcui->lock);
  mutex_unlock(btcui->lock);

  return res;
}
예제 #6
0
파일: frame.c 프로젝트: jvesely/helenos
/** Allocate frames of physical memory.
 *
 * @param count      Number of continuous frames to allocate.
 * @param flags      Flags for host zone selection and address processing.
 * @param constraint Indication of physical address bits that cannot be
 *                   set in the address of the first allocated frame.
 * @param pzone      Preferred zone.
 *
 * @return Physical address of the allocated frame.
 *
 */
uintptr_t frame_alloc_generic(size_t count, frame_flags_t flags,
    uintptr_t constraint, size_t *pzone)
{
	ASSERT(count > 0);
	
	size_t hint = pzone ? (*pzone) : 0;
	pfn_t frame_constraint = ADDR2PFN(constraint);
	
	/*
	 * If not told otherwise, we must first reserve the memory.
	 */
	if (!(flags & FRAME_NO_RESERVE))
		reserve_force_alloc(count);
	
loop:
	irq_spinlock_lock(&zones.lock, true);
	
	/*
	 * First, find suitable frame zone.
	 */
	size_t znum = find_free_zone(count, FRAME_TO_ZONE_FLAGS(flags),
	    frame_constraint, hint);
	
	/*
	 * If no memory, reclaim some slab memory,
	 * if it does not help, reclaim all.
	 */
	if ((znum == (size_t) -1) && (!(flags & FRAME_NO_RECLAIM))) {
		irq_spinlock_unlock(&zones.lock, true);
		size_t freed = slab_reclaim(0);
		irq_spinlock_lock(&zones.lock, true);
		
		if (freed > 0)
			znum = find_free_zone(count, FRAME_TO_ZONE_FLAGS(flags),
			    frame_constraint, hint);
		
		if (znum == (size_t) -1) {
			irq_spinlock_unlock(&zones.lock, true);
			freed = slab_reclaim(SLAB_RECLAIM_ALL);
			irq_spinlock_lock(&zones.lock, true);
			
			if (freed > 0)
				znum = find_free_zone(count, FRAME_TO_ZONE_FLAGS(flags),
				    frame_constraint, hint);
		}
	}
	
	if (znum == (size_t) -1) {
		if (flags & FRAME_ATOMIC) {
			irq_spinlock_unlock(&zones.lock, true);
			
			if (!(flags & FRAME_NO_RESERVE))
				reserve_free(count);
			
			return 0;
		}
		
		size_t avail = frame_total_free_get_internal();
		
		irq_spinlock_unlock(&zones.lock, true);
		
		if (!THREAD)
			panic("Cannot wait for %zu frames to become available "
			    "(%zu available).", count, avail);
		
		/*
		 * Sleep until some frames are available again.
		 */
		
#ifdef CONFIG_DEBUG
		log(LF_OTHER, LVL_DEBUG,
		    "Thread %" PRIu64 " waiting for %zu frames "
		    "%zu available.", THREAD->tid, count, avail);
#endif
		
		/*
		 * Since the mem_avail_mtx is an active mutex, we need to
		 * disable interrupts to prevent deadlock with TLB shootdown.
		 */
		ipl_t ipl = interrupts_disable();
		mutex_lock(&mem_avail_mtx);
		
		if (mem_avail_req > 0)
			mem_avail_req = min(mem_avail_req, count);
		else
			mem_avail_req = count;
		
		size_t gen = mem_avail_gen;
		
		while (gen == mem_avail_gen)
			condvar_wait(&mem_avail_cv, &mem_avail_mtx);
		
		mutex_unlock(&mem_avail_mtx);
		interrupts_restore(ipl);
		
#ifdef CONFIG_DEBUG
		log(LF_OTHER, LVL_DEBUG, "Thread %" PRIu64 " woken up.",
		    THREAD->tid);
#endif
		
		goto loop;
	}
	
	pfn_t pfn = zone_frame_alloc(&zones.info[znum], count,
	    frame_constraint) + zones.info[znum].base;
	
	irq_spinlock_unlock(&zones.lock, true);
	
	if (pzone)
		*pzone = znum;
	
	return PFN2ADDR(pfn);
}