Exemple #1
0
/** @internal Shut down stack. */
void nua_stack_shutdown(nua_t *nua)
{
  nua_handle_t *nh, *nh_next;
  int busy = 0;
  sip_time_t now = sip_now();
  int status;
  char const *phrase;

  enter;

  if (!nua->nua_shutdown)
    nua->nua_shutdown = now;

  for (nh = nua->nua_handles; nh; nh = nh_next) {
    nua_dialog_state_t *ds = nh->nh_ds;

    nh_next = nh->nh_next;

    busy += nua_dialog_repeat_shutdown(nh, ds);

    if (nh->nh_soa) {
      soa_destroy(nh->nh_soa), nh->nh_soa = NULL;
    }

    if (nua_client_request_pending(ds->ds_cr))
      busy++;

    if (nh_notifier_shutdown(nh, NULL, NEATAG_REASON("noresource"), TAG_END()))
      busy++;
  }

  if (!busy)
    SET_STATUS(200, "Shutdown successful");
  else if (now == nua->nua_shutdown)
    SET_STATUS(100, "Shutdown started");
  else if (now - nua->nua_shutdown < 30)
    SET_STATUS(101, "Shutdown in progress");
  else
    SET_STATUS(500, "Shutdown timeout");

  if (status >= 200) {
    for (nh = nua->nua_handles; nh; nh = nh_next) {
      nh_next = nh->nh_next;
      while (nh->nh_ds && nh->nh_ds->ds_usage) {
	nua_dialog_usage_remove(nh, nh->nh_ds, nh->nh_ds->ds_usage, NULL, NULL);
      }
    }
    su_timer_destroy(nua->nua_timer), nua->nua_timer = NULL;
    nta_agent_destroy(nua->nua_nta), nua->nua_nta = NULL;
  }

  nua_stack_event(nua, NULL, NULL, nua_r_shutdown, status, phrase, NULL);
}
Exemple #2
0
/*
 * Used below.
 */
static
void
cpu_irqonoff(void)
{
        uint32_t x, xon, xoff;

        GET_STATUS(x);
        xon = x | CST_IEc;
        xoff = x & ~(uint32_t)CST_IEc;
        SET_STATUS(xon);
	__asm volatile("nop; nop; nop; nop");
        SET_STATUS(xoff);
}
static int nua_publish_client_response(nua_client_request_t *cr,
				       int status, char const *phrase,
				       sip_t const *sip)
{
  nua_handle_t *nh = cr->cr_owner;
  nua_dialog_usage_t *du = cr->cr_usage;

  if (!cr->cr_terminated && du && sip) {
    struct publish_usage *pu = nua_dialog_usage_private(du);
    sip_expires_t const *ex = sip->sip_expires;

    /* Reset state */
    pu->pu_published = 0;
    if (pu->pu_etag)
      su_free(nh->nh_home, pu->pu_etag), pu->pu_etag = NULL;

    if (status < 300) {
      pu->pu_published = 1;
      pu->pu_etag = sip_etag_dup(nh->nh_home, sip->sip_etag);

      if (!ex || ex->ex_delta == 0 || !pu->pu_etag) {
	cr->cr_terminated = 1;

	if (!ex || ex->ex_delta == 0)
	  SET_STATUS(900, "Received Invalid Expiration Time");
	else
	  SET_STATUS1(NUA_ERROR_AT(__FILE__, __LINE__));
      }
      else
	nua_dialog_usage_set_refresh(du, ex->ex_delta);
    }
  }

  return nua_base_client_response(cr, status, phrase, sip, NULL);
}
Exemple #4
0
/*
 * Interrupts on.
 */
void
cpu_irqon(void)
{
        uint32_t x;

        GET_STATUS(x);
        x |= CST_IEc;
        SET_STATUS(x);
}
Exemple #5
0
/*
 * Interrupts off.
 */
void
cpu_irqoff(void)
{
        uint32_t x;

        GET_STATUS(x);
        x &= ~(uint32_t)CST_IEc;
        SET_STATUS(x);
}
Exemple #6
0
/*
 * Check if transaction must block.
 */
static inline int stm_check_quiesce(stm_tx_t *tx)
{
  stm_word_t s;

  /* Must be called upon start (while already active but before acquiring any lock) */
  assert(IS_ACTIVE(tx->status));

  ATOMIC_MB_FULL;
  if (ATOMIC_LOAD_ACQ(&quiesce) == 2) {
    s = ATOMIC_LOAD(&tx->status);
    SET_STATUS(tx->status, TX_IDLE);
    while (ATOMIC_LOAD_ACQ(&quiesce) == 2) {
      sched_yield();
    }
    SET_STATUS(tx->status, GET_STATUS(s));
    return 1;
  }
  return 0;
}
Exemple #7
0
nn_primitive_handle_t NN_API_CALL_CONVENTION nn_primitives_loss_f32_create_0(
    nn_device_t *device, /* IDLF device handle */
    NN_LOSS_FUNCTION function,
    size_t input_size_x,
    size_t input_size_y,
    size_t input_size_z,
    size_t batch_size,
    NN_API_STATUS *status /* NN_API_STATUS_OK on success */
    ) {
    SET_STATUS(NN_API_STATUS_OK);
    return new layer::loss_function_f32(
        function, input_size_x, input_size_y, input_size_z, batch_size, reinterpret_cast<nn_device_internal *>(device));
}
Exemple #8
0
nn_primitive_handle_t NN_API_CALL_CONVENTION nn_primitives_dropout_f32_create_0(
    nn_device_t *device, /* IDLF device handle */
    size_t input_size_x,
    size_t input_size_y,
    size_t input_size_z,
    size_t batch_size,
    float drop_rate,
    NN_API_STATUS *status /* NN_API_STATUS_OK on success */
    ) {
    SET_STATUS(NN_API_STATUS_OK);
    return new layer::dropout_f32(
        input_size_x, input_size_y, input_size_z, batch_size, drop_rate, reinterpret_cast<nn_device_internal *>(device));
}
/*
 * Inserts a token in the hierarchical list.
 * \param local_ctx pointer to the structure holding all the information needed 
 * by the algorithm
 * \param x the position in x of the concerned pixel
 * \param y the position in y of the concerned pixel
 * \param z the position in y of the concerned pixel
 * \param value the value determines in which list to insert it
 */
static INLINE void MB3D_InsertInHierarchicalList(
    MB3D_Watershed8_Ctx *local_ctx,
    int x, int y, int z,
    PIX8 value)
{
    int position;
    PIX32 *p;
    int lx, ly, lz;
    MB_Image *im;
    
    /* The token corresponding to the pixel process is */
    /* updated/created. */
    position = x + y*local_ctx->width + z*local_ctx->width*local_ctx->height;
    local_ctx->TokensArray[position].nextx = MB_LIST_END;
    local_ctx->TokensArray[position].nexty = MB_LIST_END;
    local_ctx->TokensArray[position].nextz = MB_LIST_END;
    
    /* Insertion in the hierarchical list */
    /* The value is normed as we do not want to process */
    /* already flooded level */
    value = (value < (local_ctx->current_water_level)) ? (local_ctx->current_water_level) : value;
    
    /* The token is inserted after the last value in the list */
    lx = local_ctx->HierarchicalList[value].lastx;
    ly = local_ctx->HierarchicalList[value].lasty;
    lz = local_ctx->HierarchicalList[value].lastz;
    position = lx+ly*local_ctx->width+lz*local_ctx->width*local_ctx->height;
    if (position>=0) {
        /* There is a last value, the list is not empty*/
        local_ctx->TokensArray[position].nextx = x;
        local_ctx->TokensArray[position].nexty = y;
        local_ctx->TokensArray[position].nextz = z;
        local_ctx->HierarchicalList[value].lastx = x;
        local_ctx->HierarchicalList[value].lasty = y;
        local_ctx->HierarchicalList[value].lastz = z;
    }
    else {
        /* The list is empty, so we create it.*/
        local_ctx->HierarchicalList[value].firstx = x;
        local_ctx->HierarchicalList[value].firsty = y;
        local_ctx->HierarchicalList[value].firstz = z;
        local_ctx->HierarchicalList[value].lastx = x;
        local_ctx->HierarchicalList[value].lasty = y;
        local_ctx->HierarchicalList[value].lastz = z;
    }
    
    /* The marker image is updated with the tag value in the pixel position */
    im = local_ctx->seq_marker[z];
    p = (PIX32 *) (im->plines[y] + x*4);
    *p = SET_STATUS(p,QUEUED);
}
nn_primitive_handle_t NN_API_CALL_CONVENTION nn_primitives_softmax_loss_f32_create_0(
    nn_device_t *device,  /* IDLF device handle */
    size_t num_features,  /* number of input feature maps */
    size_t batch_size,    /* size of input batch */
    const nn_primitives_softmax_hints_t *hints,
    NN_API_STATUS *status /* NN_API_STATUS_OK on success */
    ) {
    SET_STATUS(NN_API_STATUS_OK);

    std::remove_const<std::remove_pointer<decltype(hints)>::type>::type hints_ = {};
    if (hints != nullptr)
        hints_ = *hints;

    return new layer::softmax_loss_f32(num_features, batch_size, reinterpret_cast<nn_device_internal *>(device));
}
Exemple #11
0
int
hytm_commit(TXPARAM)
{
    stm_word_t t;
    w_entry_t *w;
    int i;
    TX_GET;

    /* Release irrevocability */
#ifdef IRREVOCABLE_ENABLED
    if (tx->irrevocable) {
        ATOMIC_STORE(&_tinystm.irrevocable, 0);
        if ((tx->irrevocable & 0x08) != 0)
            stm_quiesce_release(tx);
        tx->irrevocable = 0;
        goto commit_end;
    }
#endif /* IRREVOCABLE_ENABLED */

    t = FETCH_INC_CLOCK + 1;

    /* Set new timestamp in locks */
    w = tx->w_set.entries;
    for (i = tx->w_set.nb_entries; i > 0; i--, w++) {
        /* XXX Maybe no duplicate entries can improve perf? */
        asf_lock_store64((long unsigned int *)w->lock, LOCK_SET_TIMESTAMP(t));
    }
    /* Commit the hytm transaction */
    asf_commit();

commit_end:
    tx->retries = 0;
    /* Set status to COMMITTED */
    SET_STATUS(tx->status, TX_COMMITTED);

    /* TODO statistics */
    return 1;
}
/*
 * Controls that all the pixels are tagged and if not tags them as being part of 
 * the watershed (at this point, untagged pixels are pixels completely surrounded
 * by watershed pixels).
 * \param local_ctx pointer to the structure holding all the information needed 
 * by the algorithm
 */
static INLINE void MB3D_ControlPass(MB3D_Watershed8_Ctx *local_ctx)
{
    Uint32 x,y,z;
    PIX32 *p;
    MB_Image *im;
    
    /* All the pixels are checked */
    for(z=0; z<local_ctx->length; z++) {
        for(y=0; y<local_ctx->height; y++) {
            for(x=0; x<local_ctx->bytes_marker; x+=4) {
                im = local_ctx->seq_marker[z];
                p = (PIX32 *) (im->plines[y] + x);
                switch ((*p)&0xFF000000) {
                case CANDIDATE:
                    /* Untagged pixel */
                    *p = SET_STATUS(p,WTS_LAB);
                    break;
                default:
                    break;
                }
            }
        }
    }
}
Exemple #13
0
void
verify_next_assertion(val_context_t * ctx,
                      struct val_digested_auth_chain *as,
                      struct val_digested_auth_chain *the_trust,
                      u_int32_t flags)
{
    struct rrset_rec *the_set;
    struct rrset_rr  *the_sig;
    u_char       *signby_name_n;
    u_int16_t       signby_footprint_n;
    val_dnskey_rdata_t dnskey;
    int             is_a_wildcard;
    struct rrset_rr  *nextrr;
    struct rrset_rr  *keyrr;
    u_int16_t       tag_h;
    char            name_p[NS_MAXDNAME];

    if ((as == NULL) || (as->val_ac_rrset.ac_data == NULL) || (the_trust == NULL)) {
        val_log(ctx, LOG_INFO, "verify_next_assertion(): Cannot verify assertion - no data");
        return;
    }

    the_set = as->val_ac_rrset.ac_data;
    dnskey.public_key = NULL;


    if (-1 == ns_name_ntop(the_set->rrs_name_n, name_p, sizeof(name_p)))
        snprintf(name_p, sizeof(name_p), "unknown/error");

    if (the_set->rrs_sig == NULL) {
        val_log(ctx, LOG_INFO, "verify_next_assertion(): RRSIG is missing");
        as->val_ac_status = VAL_AC_RRSIG_MISSING;
        return;
    }

    if (the_set->rrs_type_h != ns_t_dnskey) {
        /*
         * trust path contains the key 
         */
        if (the_trust->val_ac_rrset.ac_data == NULL) {
            val_log(ctx, LOG_INFO, "verify_next_assertion(): Key is empty");
            as->val_ac_status = VAL_AC_DNSKEY_MISSING;
            return;
        }
        keyrr = the_trust->val_ac_rrset.ac_data->rrs_data;
    } else {
        /*
         * data itself contains the key 
         */
        if (the_set->rrs_data == NULL) {
            val_log(ctx, LOG_INFO, "verify_next_assertion(): Key is empty");
            as->val_ac_status = VAL_AC_DNSKEY_MISSING;
            return;
        }
        keyrr = the_set->rrs_data;
    }

    for (the_sig = the_set->rrs_sig;
         the_sig; the_sig = the_sig->rr_next) {

        /*
         * do wildcard processing 
         */
        if (!check_label_count(the_set, the_sig, &is_a_wildcard)) {
            SET_STATUS(as->val_ac_status, the_sig,
                       VAL_AC_WRONG_LABEL_COUNT);
            val_log(ctx, LOG_INFO, "verify_next_assertion(): Incorrect RRSIG label count");
            continue;
        }

        /*
         * for each sig, identify key, 
         */
        if (VAL_NO_ERROR != identify_key_from_sig(the_sig, &signby_name_n,
                              &signby_footprint_n)) {
            SET_STATUS(as->val_ac_status, the_sig,
                       VAL_AC_INVALID_RRSIG);
            val_log(ctx, LOG_INFO, "verify_next_assertion(): Cannot extract key footprint from RRSIG");
            continue;
        }

        tag_h = ntohs(signby_footprint_n);
        for (nextrr = keyrr; nextrr; nextrr = nextrr->rr_next) {
            int             is_verified = 0;
            if (VAL_NO_ERROR != val_parse_dnskey_rdata(nextrr->rr_rdata,
                                             nextrr->rr_rdata_length,
                                             &dnskey)) {
                val_log(ctx, LOG_INFO, "verify_next_assertion(): Cannot parse DNSKEY data");
                nextrr->rr_status = VAL_AC_INVALID_KEY;
                continue;
            }

            dnskey.next = NULL;
            if (dnskey.key_tag != tag_h) {
                if (dnskey.public_key != NULL) {
                    FREE(dnskey.public_key);
                    dnskey.public_key = NULL;
                }
                continue;
            }

            val_log(ctx, LOG_DEBUG, "verify_next_assertion(): Found potential matching DNSKEY for RRSIG");

            /*
             * check the signature 
             */
            is_verified = do_verify(ctx, signby_name_n,
                      &nextrr->rr_status,
                      &the_sig->rr_status,
                      the_set, the_sig, &dnskey, is_a_wildcard, flags);

            /*
             * There might be multiple keys with the same key tag; set this as
             * the signing key only if we dont have other status for this key
             */
            SET_STATUS(as->val_ac_status, the_sig, the_sig->rr_status);
            if (nextrr->rr_status == VAL_AC_UNSET) {
                nextrr->rr_status = VAL_AC_SIGNING_KEY;
            }

            if (is_verified) {

                val_log(ctx, LOG_INFO, "verify_next_assertion(): Verified a RRSIG for %s (%s) using a DNSKEY (%d)",
                        name_p, p_type(the_set->rrs_type_h),
                        dnskey.key_tag);

                if ( as->val_ac_status == VAL_AC_TRUST ||
                    nextrr->rr_status == VAL_AC_TRUST_POINT) {
                    /* we've verified a trust anchor */
                    as->val_ac_status = VAL_AC_TRUST; 
                    val_log(ctx, LOG_INFO, "verify_next_assertion(): verification traces back to trust anchor");
                    if (dnskey.public_key != NULL) {
                        FREE(dnskey.public_key);
                        dnskey.public_key = NULL;
                    }
                    return;
                }
            
                /* Check if we're trying to verify some key in the authentication chain */
                if ( the_set->rrs_type_h == ns_t_dnskey && 
                    as != the_trust) {
                    /* Check if we have reached our trust key */
                    /*
                     * If this record contains a DNSKEY, check if the DS record contains this key 
                     * DNSKEYs cannot be wildcard expanded, so VAL_AC_WCARD_VERIFIED does not
                     * count as a good sig
                     * Create the link even if the DNSKEY algorithm is unknown since this 
                     * may be the provably insecure case
                     */
                    /*
                     * follow the trust path 
                     */
                    struct rrset_rr  *dsrec =
                        the_trust->val_ac_rrset.ac_data->rrs_data;
                    while (dsrec) {
                        val_ds_rdata_t  ds;
                        ds.d_hash = NULL;
                        int retval = val_parse_ds_rdata(dsrec->rr_rdata,
                                       dsrec->rr_rdata_length, &ds);
                        if(retval == VAL_NOT_IMPLEMENTED) {
                            val_log(ctx, LOG_INFO, "verify_next_assertion(): DS hash not supported");
                            dsrec->rr_status = VAL_AC_ALGORITHM_NOT_SUPPORTED;
                        } else if (retval != VAL_NO_ERROR) {
                            val_log(ctx, LOG_INFO, "verify_next_assertion(): DS parse error");
                            dsrec->rr_status = VAL_AC_INVALID_DS;
                        } else if (DNSKEY_MATCHES_DS(ctx, &dnskey, &ds, 
                                    the_set->rrs_name_n, nextrr, 
                                    &dsrec->rr_status)) {
                            val_log(ctx, LOG_DEBUG, 
                                    "verify_next_assertion(): DNSKEY tag (%d) matches DS tag (%d)",
                                    (&dnskey)->key_tag,                                         
                                    (&ds)->d_keytag);
                            /*
                             * the first match is enough 
                             */
                            nextrr->rr_status = VAL_AC_VERIFIED_LINK;
                            FREE(ds.d_hash);
                            ds.d_hash = NULL;
                            if (dnskey.public_key) {
                                FREE(dnskey.public_key);
                                dnskey.public_key = NULL;
                            }
                            val_log(ctx, LOG_INFO, "verify_next_assertion(): Key links upward");
                            return;
                        } else {
                            /*
                             * Didn't find a valid entry in the DS record set 
                             * Not necessarily a problem, since there is no requirement that a DS be present
                             * If none match, then we set the status accordingly. See below.
                             */
                            nextrr->rr_status = VAL_AC_DS_NOMATCH;
                        } 

                        if (ds.d_hash != NULL)
                            FREE(ds.d_hash);

                        dsrec = dsrec->rr_next;
                    }
                }
            } 

            if (dnskey.public_key != NULL) {
                FREE(dnskey.public_key);
            }
            dnskey.public_key = NULL;
        }

        val_log(ctx, LOG_INFO, "verify_next_assertion(): Could not link this RRSIG to a DNSKEY");
        SET_STATUS(as->val_ac_status, the_sig, VAL_AC_DNSKEY_NOMATCH);
    }
        
    /* 
     * If we reach here and we're a keyset, we either didn't verify the keyset or
     * didn't verify the link from the key to the DS 
     */ 
    if (the_set->rrs_type_h == ns_t_dnskey){
        as->val_ac_status = VAL_AC_NO_LINK;
    }
}
Exemple #14
0
/*
 * Called by the CURRENT thread to commit a transaction.
 */
int stm_commit(TXPARAM)
{
  w_entry_t *w;
  stm_word_t t;
  int i;
  TX_GET;

  PRINT_DEBUG("==> stm_commit(%p[%lu-%lu])\n", tx, (unsigned long)tx->start, (unsigned long)tx->end);

  /* Decrement nesting level */
  if (--tx->nesting > 0)
    return 1;

  assert(IS_ACTIVE(tx->status));

  /* A read-only transaction can commit immediately */
  if (tx->w_set.nb_entries == 0)
    goto end;


  /* Update transaction */

  /* Get commit timestamp (may exceed VERSION_MAX by up to MAX_THREADS) */
  t = FETCH_INC_CLOCK + 1;

  /* Try to validate (only if a concurrent transaction has committed since tx->start) */
  if (tx->start != t - 1 && !stm_validate(tx)) {
    /* Cannot commit */
    tx->aborts_validate_commit++;
    stm_rollback(tx, STM_ABORT_VALIDATE);
    return 0;
  }

  /* Install new versions, drop locks and set new timestamp */
  w = tx->w_set.entries;
  for (i = tx->w_set.nb_entries; i > 0; i--, w++) {
    if (w->mask != 0)
      ATOMIC_STORE(w->addr, w->value);
    /* Only drop lock for last covered address in write set */
    if (w->next == NULL)
      ATOMIC_STORE_REL(w->lock, LOCK_SET_TIMESTAMP(t));
  }

 end:
  tx->retries = 0;



  /* Callbacks */
  if (nb_commit_cb != 0) {
    int cb;
    for (cb = 0; cb < nb_commit_cb; cb++)
      commit_cb[cb].f(TXARGS commit_cb[cb].arg);
  }


  /* Set status to COMMITTED */
  SET_STATUS(tx->status, TX_COMMITTED);

  return 1;
}
Exemple #15
0
/*
 * Rollback transaction.
 */
static inline void stm_rollback(stm_tx_t *tx, int reason)
{
  w_entry_t *w;
  int i;

  PRINT_DEBUG("==> stm_rollback(%p[%lu-%lu])\n", tx, (unsigned long)tx->start, (unsigned long)tx->end);

  assert(IS_ACTIVE(tx->status));

  /* Drop locks */
  i = tx->w_set.nb_entries;
  if (i > 0) {
    w = tx->w_set.entries;
    for (; i > 0; i--, w++) {
      if (w->next == NULL) {
        /* Only drop lock for last covered address in write set */
        ATOMIC_STORE(w->lock, LOCK_SET_TIMESTAMP(w->version));
      }
    }
    /* Make sure that all lock releases become visible */
    ATOMIC_MB_WRITE;
  }


  tx->retries++;
  tx->aborts++;
  if (tx->retries == 1)
    tx->aborts_1++;
  else if (tx->retries == 2)
    tx->aborts_2++;
  if (tx->max_retries < tx->retries)
    tx->max_retries = tx->retries;

  /* Callbacks */
  if (nb_abort_cb != 0) {
    int cb;
    for (cb = 0; cb < nb_abort_cb; cb++)
      abort_cb[cb].f(TXARGS abort_cb[cb].arg);
  }

  /* Set status to ABORTED */
  SET_STATUS(tx->status, TX_ABORTED);

  /* Reset nesting level */
  tx->nesting = 1;


  /* Wait until contented lock is free */
  if (tx->c_lock != NULL) {
    /* Busy waiting (yielding is expensive) */
    while (LOCK_GET_OWNED(ATOMIC_LOAD(tx->c_lock))) {
      sched_yield();
    }
    tx->c_lock = NULL;
  }

  /* Reset field to restart transaction */
  stm_prepare(tx);

  /* Jump back to transaction start */
  if (tx->attr == NULL || !tx->attr->no_retry)
    siglongjmp(tx->env, reason);
}
/*
 * Inserts the neighbors of pixel (x,y,z) in the hierarchical list so that they
 * can be flooded when the water reaches their level (FACE CENTERED CUBIC 
 * GRID). Also evaluates to which basin the pixel belongs or if it is a point
 * of the watershed.
 * \param ctx pointer to the structure holding all the information needed 
 * by the algorithm
 * \param x the x position of the pixel processed
 * \param y the x position of the pixel processed
 * \param z the z position of the pixel processed
 *
 * \return the function return the next token (pixel) that must be process
 */
static MB3D_Token MB3D_InsertNeighbors_fcc(void *ctx, int x, int y, int z)
{
    Uint32 neighbor;
    PIX32 *p, *pix, tag;
    int nbx,nby,nbz,pos,dirSelect;
    MB_Image *im;
    MB3D_Watershed8_Ctx *local_ctx = (MB3D_Watershed8_Ctx *) ctx;
    
    /* Computing the directions to use depending on the y and z of the */
    /* pixel */
    dirSelect = ((z%3)<<1)+(y%2);
    
    /* The tag value is the value of the marker image in x,y */
    im = local_ctx->seq_marker[z];
    pix = (PIX32 *) (im->plines[y] + x*4);
    *pix = SET_STATUS(pix,RG_LAB);
    
    /* We will then look at its neighbors and it will help us decide to which */
    /* marker the pixel belongs and also evaluates if the pixel might be in */
    /* the watershed. The neighbors not yet processed or inserted will be put */
    /* in the reinsert list to insert them later if the pixel is taggued at the */
    /* end. */
    
    /* The reinsert list is emptied */
    MB3D_ClearReinsertList(local_ctx);
    
    /* For the 12 neighbors of the pixel */
    for(neighbor=1; neighbor<13; neighbor++) {
        /* Position and value in the marker image */
        nbx = x+fccNbDir[dirSelect][neighbor][0];
        nby = y+fccNbDir[dirSelect][neighbor][1];
        nbz = z+fccNbDir[dirSelect][neighbor][2];
        
        /* The neighbor must be in the image*/
        if (nbx>=0 && nbx<((int) local_ctx->width) && 
            nby>=0 && nby<((int) local_ctx->height) &&
            nbz>=0 && nbz<((int) local_ctx->length) ) {
            im = local_ctx->seq_marker[nbz];
            p = (PIX32 *) (im->plines[nby] + nbx*4);
            
            if( IS_PIXEL(p, CANDIDATE) ) {
                /* The neighbor is not inserted into the list yet */
                /* For the time being it is only put into the reinsert list */
                MB3D_InsertInReinsertList(local_ctx, nbx, nby, nbz);
            } else if ( IS_PIXEL(p, RG_LAB) ) {
                /* The neighbor has already been processed and tagged */
                tag = READ_LABEL(pix);
                if (tag==0) {
                    /* First neighbor we met with a tag, we take it */
                    /* for our pixel */
                    *pix |= READ_LABEL(p);
                } else if ( tag!=READ_LABEL(p) ) {
                    /* The tag of the neighbor is different that ours */
                    /* and the neighbor is not on the watershed */
                    /* the pixel belongs to the watershed */
                    *pix = SET_STATUS(pix,WTS_LAB);
                } 
            }
            /* Other case means that the neighbor is in the list but not processed */
        }
    }
    
    /* At this point, if the pixel does not belong to the watershed */
    /* we insert its unprocessed and unlisted neighbor into the */
    /* hierarchical list */
    if( !IS_PIXEL(pix, WTS_LAB) ) {
        MB3D_ReinsertFromList(local_ctx);
    }

    /* What is the next token to process */
    pos = x+y*local_ctx->width+z*local_ctx->width*local_ctx->height;
    return local_ctx->TokensArray[pos];
}
Exemple #17
0
sigjmp_buf *
hytm_start(TXPARAMS stm_tx_attr_t attr)
{
    TX_GET;
    unsigned long err;

    tx->retries = 0;
    /* Set status */
    UPDATE_STATUS(tx->status, TX_ACTIVE);
    stm_check_quiesce(tx);
    /* copy attributes if need to switch to software mode */
    tx->attr = attr;
    tx->start = rdtsc();

hytm_restart:
    /* All registers are lost when ASF aborts, thus we discard registers */
    asm volatile (ASF_SPECULATE
                  :"=a" (err)
                  :
                  :"memory","rbp","rbx","rcx","rdx","rsi","rdi",
                  "r8", "r9","r10","r11","r12","r13","r14","r15" );

    tx = tls_get_tx();
    if (unlikely(asf_status_code(err) != 0)) {
        /* Set status to ABORTED */
        SET_STATUS(tx->status, TX_ABORTED);
        tx->retries++;
        /* Error management */
        if (asf_status_code(err) == ASF_STATUS_CONTENTION) {
            if (tx->retries > ASF_ABORT_THRESHOLD) {
                /* There is too many conflicts, software will not help, start irrevocability. */
                stm_set_irrevocable(TXARGS 1);  /* Set irrevocable serial */
#if defined(TM_DTMC) || defined(TM_GCC)
                stm_set_irrevocable(TXARGS -1); /* Acquire irrevocability */
                UPDATE_STATUS(tx->status, TX_IRREVOCABLE);
                LONGJMP(tx->env, 0x02); /* ABI 0x02 = runUninstrumented */
#else /* ! defined(TM_DTMC) && ! defined(TM_GCC) */
                /* Non-tm compiler doesn't have path without instrumentation. */
                tx->software = 1;
#endif /* ! defined(TM_DTMC) && ! defined(TM_GCC) */
            }
        } else if (asf_status_code(err) == ASF_STATUS_ABORT) {
            if (asf_abort_code(err) == ASF_FORCE_SOFTWARE) {
                tx->software = 1;
#ifdef IRREVOCABLE_ENABLED
            } else if(asf_abort_code(err) == ASF_RETRY_IRREVOCABLE) {
# if defined(TM_DTMC) || defined(TM_GCC)
                if (tx->irrevocable != 0) {
                    stm_set_irrevocable(TXARGS -1);
                    UPDATE_STATUS(tx->status, TX_IRREVOCABLE);
                    LONGJMP(tx->env, 0x02); /* ABI 0x02 = runUninstrumented */
                }
# else /* ! defined(TM_DTMC) || defined(TM_GCC) */
                /* Non-tm compiler doesn't have path without instrumentation. */
                tx->software = 1;
# endif /* ! defined(TM_DTMC) || defined(TM_GCC) */
#endif /* IRREVOCABLE_ENABLED */
            } else {
                if (tx->retries > ASF_ABORT_THRESHOLD) {
                    tx->software = 1;
                }
            }
        } else {
            /* Other cases are critical and needs software mode */
            tx->software = 1;
        }
        if (tx->software) {
            /* Start a software transaction (it cannot use attr since the register/stack can be corrupted) */
            stm_start(TXARGS tx->attr);
            /* Restoring the context */
#if defined(TM_DTMC)
            LONGJMP(tx->env, 0x01); /* ABI 0x01 = runInstrumented, DTMC explicitly needs 1 */
#else /* ! defined(TM_DTMC) */
            LONGJMP(tx->env, 0x09); /* ABI 0x09 = runInstrumented + restoreLiveVariable */
#endif /* ! defined(TM_DTMC) */
        } else {
            uint64_t cur = (uint64_t)rdtsc();
            uint64_t wait = cur + (random() % (cur - tx->start)); /* XXX random but maybe not reliable */
            /* Waiting... */
            while (rdtsc() < wait);
            UPDATE_STATUS(tx->status, TX_ACTIVE);
            /* Check quiesce before to restart */
            stm_check_quiesce(tx);
            goto hytm_restart;
        }
    }

    /* Reset write set */
    tx->w_set.nb_entries = 0;

    if (tx->retries > 0) {
        /* Restoring registers for retry */
#if defined(TM_DTMC)
        LONGJMP(tx->env, 0x01); /* ABI 0x01 = runInstrumented, DTMC explicitly needs 1 */
#else /* ! defined(TM_DTMC) */
        LONGJMP(tx->env, 0x09); /* ABI 0x09 = runInstrumented + restoreLiveVariable */
#endif /* ! defined(TM_DTMC) */
    }

    return &tx->env;
}