示例#1
0
int main (int argc, char *argv[]) {

	struct l2atomic l2atomic;
	memset((void*)&l2atomic, 0, sizeof(l2atomic));

	uint32_t tcoord = Kernel_MyTcoord();
	int rc, lineno;

	rc = l2atomic_init(&l2atomic); lineno = __LINE__;
	if (rc) goto err;

	volatile uint64_t * buffer = NULL;
	rc = l2atomic_alloc(&l2atomic, "simple", sizeof(uint64_t)*3, (void**)&buffer, test_init_fn, 0); lineno = __LINE__;
	if (rc) goto err;

	volatile uint64_t * entered = buffer+1;
	volatile uint64_t * exited = buffer+2;
	L2_AtomicLoadIncrement(entered);

	uint32_t i;
	if (tcoord % 2 == 0) {
		for (i=0; i<ITERATIONS; ++i) L2_AtomicLoadIncrement(buffer);
	} else {
		for (i=0; i<ITERATIONS; ++i) L2_AtomicLoadDecrement(buffer);
	}

	L2_AtomicLoadIncrement(exited);
	while (L2_AtomicLoad(exited) != *entered);

	uint64_t np = *entered;
	uint64_t expected = 0;
	if (np % 2 == 1) expected = ITERATIONS;

	if (tcoord == 0) fprintf (stdout, "l2atomic value: %lu (expected %lu)\n", *buffer, expected);
	if (*buffer == expected) {
		if (tcoord == 0) fprintf (stdout, "TEST SUCCESSFUL\n");
	} else {
		if (tcoord == 0) fprintf (stdout, "TEST FAILED\n");
		return 1;
	}
	return 0;
err:
	fprintf (stderr, "Error at line %d\n", lineno);
	return 1;
}
示例#2
0
/*!
 * \brief Allocates a speculative domain. 
 * \note Each additional domain potentially decreases the number of speculative IDs assigned to each domain.
 * \note Domains must have all speculative IDs set to the available state
 */
int Speculation_AllocateDomain(unsigned int* domain)
{
#if 0
    const unsigned char domainmap[17] = { 1, 1, 2, 4, 4, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16};
    if(NodeState.NumSpecDomains >= 16)
    {
        return ENOMEM;
    }
    if(!SPEC_AllAvailOrInvalid())
    {
        // if any ID is speculative or committed, we can not switch
        // \todo this needs to be made safe. 
        // While switching, we can not allow threads to alloce concurrently (race)
        // TM domains need to be made aware of changes to adapt their allocation mask
        // In short, all speculation RTS need to be shut down temporarily while changing number of domains
        return ENOMEM;
    }
    NodeState.NumSpecDomains++;
    SPEC_SetNumberOfDomains( domainmap[NodeState.NumSpecDomains] );
    SPEC_SetDomainMode_priv(NodeState.NumSpecDomains-1, L2C_DOMAINATTR_MODE_STM);
    ppc_msync();
    
    /* \todo Initialize commit, alloc, reclaim pointers??? */
    
    *domain = NodeState.NumSpecDomains-1;
#endif
    uint32_t domainAllocated = L2_AtomicLoadIncrement(&SpecDomainsAllocated);
    if(domainAllocated >= SPEC_GetNumberOfDomains())
    {
        return ENOMEM;
    }
    
    // bqcbugs 1620.
    l2_set_prefetch_enables(0);
    l2_unlock_all_with_address((void *) 0x200000);
    l2_set_overlock_threshold(0xA);                      // set L2 overlock and spec thresholds
    l2_set_spec_threshold(0xA);
    // --
    
    Kernel_WriteFlightLog(FLIGHTLOG_high, FL_SPCALCDOM, domainAllocated,0,0,0);
    *domain = domainAllocated;
    return 0;
}
int main(int argc, char * argv[])
{
    const int n = 1024;
    int count = (argc>1) ? atoi(argv[1]) : 1000000;

    /* this "activates" the L2 atomic data structures */
    uint64_t * l2_counters = NULL;
    int rc = posix_memalign((void**)&l2_counters, 2*1024*1024, n * sizeof(uint64_t) ); 
    assert(rc==0 && l2_counters != NULL);
    uint64_t rc64 = Kernel_L2AtomicsAllocate(l2_counters, n * sizeof(uint64_t) );
    assert(rc64==0);

    for (int i=0; i<n; i++) {
        L2_AtomicStore(&(l2_counters[i]), 0);
    }

    #pragma omp parallel shared(l2_counters)
    {
        int me = omp_get_thread_num();
        int jmax = n/omp_get_num_threads();
        for (int j=0; j<jmax; j++) {
            #pragma omp barrier
            uint64_t t0 = GetTimeBase();
            for (int i=0; i<count; i++) {
                L2_AtomicLoadIncrement(&(l2_counters[j*me]));
            }
            #pragma omp barrier
            uint64_t t1 = GetTimeBase();
            printf("threads = %d, stride = %d, ticks = %llu \n",
                   omp_get_num_threads(), j, t1-t0);
            fflush(stdout);
        }
    }

    for (int i=0; i<n; i++) {
        uint64_t rval = L2_AtomicLoad(&(l2_counters[i]));
        printf("l2_counter[%d]=%llu\n", i, rval);
    }

    return 0;   
}
示例#4
0
void * fight(void * input)
{
    int tid = get_thread_id();

    if (debug) 
        printf("%d: before L2_Barrier 1 \n", tid);
    L2_Barrier(&barrier, num_threads);
    if (debug) {
        printf("%d: after  L2_Barrier 1 \n", tid);
        fflush(stdout);
    }

    int count = 1000000;

    uint64_t rval;

    uint64_t t0 = GetTimeBase();
    for (int i=0; i<count; i++)
        rval = L2_AtomicLoadIncrement(&(counter.atom));
    uint64_t t1 = GetTimeBase();

    if (debug) 
        printf("%d: before L2_Barrier 2 \n", tid);
    L2_Barrier(&barrier, num_threads);
    if (debug) {
        printf("%d: after  L2_Barrier 2 \n", tid);
        fflush(stdout);
    }
    
    uint64_t dt = t1-t0;
    printf("%2d: %d calls to %s took %llu cycles per call \n", 
           tid, count, "L2_AtomicLoadIncrement", dt/count);
    fflush(stdout);

    pthread_exit(NULL);

    return NULL;
}