示例#1
0
文件: mp.c 项目: chnlkw/ucore_plus
/* alloc percpu var in the corresponding    NUMA nodes */
void percpu_init(void)
{
	size_t percpu_size = ROUNDUP(__percpu_end - __percpu_start, CACHELINE);
	if(!percpu_size || sysconf.lcpu_count<=1)
		return;
	int i, j;
	for(i=0; i<sysconf.lnuma_count;i++){
		struct numa_node *node = &numa_nodes[i];
		int nr_cpus = node->nr_cpus;
		for(j=0;j<node->nr_cpus;j++){
			if(node->cpu_ids[j] == myid()){
				nr_cpus--;
				break;
			}
		}
		size_t totalsize = percpu_size * nr_cpus;
		unsigned int pages = ROUNDUP_DIV(totalsize, PGSIZE);
		if(!pages)
			continue;
		kprintf("percpu_init: node%d alloc %d pages for percpu variables\n", i, pages);
		struct Page *p = alloc_pages_numa(node, pages);
		assert(p != NULL);
		void *kva = page2kva(p);
		/* zero it out */
		memset(kva, 0, pages * PGSIZE);
		for(j=0;j<node->nr_cpus;j++, kva += percpu_size){
			if(node->cpu_ids[j] == myid())
				continue;
			percpu_offsets[node->cpu_ids[j]] = kva;
		}
	}
	for(i=0;i<sysconf.lcpu_count;i++){
		kprintf("percpu_init: cpu%d get 0x%016llx\n", i, percpu_offsets[i]);
	}
}
示例#2
0
/*
 * sfs_truncfile : reszie the file with new length
 */
static int
sfs_truncfile(struct inode *node, off_t len) {
    if (len < 0 || len > SFS_MAX_FILE_SIZE) {
        return -E_INVAL;
    }
    struct sfs_fs *sfs = fsop_info(vop_fs(node), sfs);
    struct sfs_inode *sin = vop_info(node, sfs_inode);
    struct sfs_disk_inode *din = sin->din;

    int ret = 0;
	//new number of disk blocks of file
    uint32_t nblks, tblks = ROUNDUP_DIV(len, SFS_BLKSIZE);
    if (din->size == len) {
        assert(tblks == din->blocks);
        return 0;
    }

    lock_sin(sin);
	// old number of disk blocks of file
    nblks = din->blocks;
    if (nblks < tblks) {
		// try to enlarge the file size by add new disk block at the end of file
        while (nblks != tblks) {
            if ((ret = sfs_bmap_load_nolock(sfs, sin, nblks, NULL)) != 0) {
                goto out_unlock;
            }
            nblks ++;
        }
    }
    else if (tblks < nblks) {
		// try to reduce the file size
        while (tblks != nblks) {
            if ((ret = sfs_bmap_truncate_nolock(sfs, sin)) != 0) {
                goto out_unlock;
            }
            nblks --;
        }
    }
    assert(din->blocks == tblks);
    din->size = len;
    sin->dirty = 1;

out_unlock:
    unlock_sin(sin);
    return ret;
}
示例#3
0
static int
sfs_truncfile(struct inode *node, off_t len) {
    if (len < 0 || len > SFS_MAX_FILE_SIZE) {
        return -E_INVAL;
    }
    struct sfs_fs *sfs = fsop_info(vop_fs(node), sfs);
    struct sfs_inode *sin = vop_info(node, sfs_inode);
    struct sfs_disk_inode *din = sin->din;
    assert(din->type != SFS_TYPE_DIR);

    int ret = 0;
    uint32_t nblks, tblks = ROUNDUP_DIV(len, SFS_BLKSIZE);
    if (din->fileinfo.size == len) {
        assert(tblks == din->blocks);
        return 0;
    }

    if ((ret = trylock_sin(sin)) != 0) {
        return ret;
    }
    nblks = din->blocks;
    if (nblks < tblks) {
        while (nblks != tblks) {
            if ((ret = sfs_bmap_load_nolock(sfs, sin, nblks, NULL)) != 0) {
                goto out_unlock;
            }
            nblks ++;
        }
    }
    else if (tblks < nblks) {
        while (tblks != nblks) {
            if ((ret = sfs_bmap_truncate_nolock(sfs, sin)) != 0) {
                goto out_unlock;
            }
            nblks --;
        }
    }
    assert(din->blocks == tblks);
    din->fileinfo.size = len;
    sin->dirty = 1;

out_unlock:
    unlock_sin(sin);
    return ret;
}
示例#4
0
文件: ast.c 项目: InSoonPark/asf
/**
 * \brief Function to tune the AST prescalar frequency to the desired frequency
 *
 * \param ast         Base address of the AST (i.e. &AVR32_AST).
 * \param input_freq  Prescaled AST Clock Frequency
 * \param tuned_freq  Desired AST frequency
 *
 * \retval false If invalid frequency is passed
 * \retval true If configuration succeeds
 *
 * \note Parameter Calculation:
 * Formula: \n
 * ADD=0 -> ft= fi(1 - (1/((roundup(256/value) * (2^exp)) + 1))) \n
 * ADD=1 -> ft= fi(1 + (1/((roundup(256/value) * (2^exp)) - 1))) \n
 * Specifications: \n
 * exp > 0, value > 1 \n
 * Let X = (2 ^ exp), Y = roundup(256 / value) \n
 * Tuned Frequency -> ft \n
 * Input Frequency -> fi \n
 *
 * IF ft < fi \n
 * ADD = 0 \n
 * Z = (ft / (fi - ft)) \n
 * ELSE IF ft > fi \n
 * ADD = 1 \n
 * Z = (ft / (ft - fi)) \n
 * ELSE \n
 * exit function -> Tuned Frequency = Input Frequency \n
 *
 * The equation can be reduced to (X * Y) = Z
 *
 * Frequency Limits \n
 * (1/((roundup(256/value) * (2^exp)) + 1)) should be min to get the lowest
 * possible output from Digital Tuner.\n
 * (1/((roundup(256/value) * (2^exp)) - 1)) should be min to get the highest
 * possible output from Digital Tuner.\n
 * For that, roundup(256/value) & (2^exp) should be minimum \n
 * min (EXP) = 1 (Note: EXP > 0) \n
 * min (roundup(256/value)) = 2 \n
 * max (Ft) = (4*fi)/3 \n
 * min (Ft) = (4*fi)/5 \n
 *
 * Using the above details, X & Y that will closely satisfy the equation is
 * found in this function.
 */
bool ast_configure_digital_tuner(volatile avr32_ast_t *ast,
		uint32_t input_freq, uint32_t tuned_freq)
{
	bool add;
	uint8_t value;
	uint8_t exp;
	uint32_t x, y, z;
	uint32_t diff;

	if (tuned_freq < input_freq) {
		/* Check for Frequency Limit */
		if (tuned_freq < ((4 * input_freq) / 5)) {
			return false;
		}

		/* Set the ADD to 0 when freq less than input freq */
		add = false;
		/* Calculate the frequency difference */
		diff = input_freq - tuned_freq;
	} else if (tuned_freq > input_freq) {
		/* Check for Frequency Limit */
		if (tuned_freq > ((4 * input_freq) / 3)) {
			return false;
		}

		/* Set the ADD to 1 when freq greater than input freq */
		add = true;
		/* Calculate the frequency difference */
		diff = tuned_freq - input_freq;
	} else {
		/* required & input freq are equal */
		return true;
	}

	z = (tuned_freq) / (diff);
	if ((tuned_freq % diff) > (diff / 2)) {
		z++;
	}

	/*
	 * Initialize with minimum possible values.
	 * exp value should be greater than zero, min(exp) = 1 -> min(x)= (2^1)
	 *= 2
	 * y should be greater than one -> roundup(256/value) where value- 0 to
	 * 255
	 * min(y) = roundup(256/255) = 2
	 */
	y = 2;
	x = 2;
	exp = 1;

	/*
	 * Keep exp constant and increase y value until it reaches its limit.
	 * Increment exp and follow the same steps until we found the closest
	 * possible match for the required frequency.
	 */
	do {
		if (y < 255) {
			y++;
		} else {
			x = x << 1;
			y = 2;
			exp++;
		}
	} while (z > (x * y));

	/* Decrement y value after exit from loop */
	y = y - 1;
	/* Find VALUE from y */
	value = ROUNDUP_DIV(256, y);
	/* Initialize the Digital Tuner using the required parameters */
	ast_init_digital_tuner(ast, add, value, exp);

	return true;
}