Beispiel #1
0
static int create_segments(unsigned long k_size, unsigned long v_size, yac_shared_segment_mmap **shared_segments_p, int *shared_segments_count, char **error_in) /* {{{ */ {
	yac_shared_segment *shared_segment;
	unsigned long allocate_size, occupied_size =  0;;
	unsigned int i, segment_size, segments_num = 1024;
	yac_shared_segment_mmap first_segment;

	k_size = YAC_SMM_ALIGNED_SIZE(k_size);
	v_size = YAC_SMM_ALIGNED_SIZE(v_size);
	while ((v_size / segments_num) < YAC_SMM_SEGMENT_MIN_SIZE) {
		segments_num >>= 1;
	}

	segment_size = v_size / segments_num;
	++segments_num;

	allocate_size = k_size + v_size;

	first_segment.common.p = mmap(0, allocate_size, PROT_READ | PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
	if (first_segment.common.p == MAP_FAILED) {
		*error_in = "mmap";
		return 0;
	}
	first_segment.size = allocate_size;
	first_segment.common.size = k_size;
	first_segment.common.pos = 0;

	*shared_segments_p = (yac_shared_segment_mmap *)calloc(1, segments_num * sizeof(yac_shared_segment_mmap));
	if (!*shared_segments_p) {
		munmap(first_segment.common.p, first_segment.size);
		*error_in = "calloc";
		return 0;
	} else {
		*shared_segments_p[0] = first_segment;
	}
	*shared_segments_count = segments_num;

	occupied_size = k_size;
	for (i = 1; i < segments_num; i++) {
		(*shared_segments_p)[i].size = 0;
		(*shared_segments_p)[i].common.pos = 0;
		(*shared_segments_p)[i].common.p = first_segment.common.p + occupied_size;
		if ((allocate_size - occupied_size) >= YAC_SMM_ALIGNED_SIZE(segment_size)) {
			(*shared_segments_p)[i].common.size = YAC_SMM_ALIGNED_SIZE(segment_size);
			occupied_size += YAC_SMM_ALIGNED_SIZE(segment_size);
		} else {
			(*shared_segments_p)[i].common.size = (allocate_size - occupied_size);
			break;
		}
	}

	return 1;
}
Beispiel #2
0
int yac_allocator_startup(unsigned long k_size, unsigned long size, char **msg) /* {{{ */ {
	char *p;
	yac_shared_segment *segments = NULL;
	int i, segments_num, segments_array_size, segment_size;
	const yac_shared_memory_handlers *he;

	if ((he = &yac_shared_memory_handler)) {
		int ret = he->create_segments(k_size, size, &segments, &segments_num, msg);

		if (!ret) {
			if (segments) {
				int i;
				for (i = 0; i < segments_num; i++) {
					if (segments[i].p && segments[i].p != (void *)-1) {
						he->detach_segment(&segments[i]);
					}
				}
				free(segments);
			}
			return 0;
		}
	} else {
		return 0;
	}

	segment_size = he->segment_type_size();
	segments_array_size = (segments_num - 1) * segment_size;

	yac_storage = segments[0].p;
	memcpy(&YAC_SG(first_seg), (char *)(&segments[0]), segment_size);

	YAC_SG(segments_num) 		= segments_num - 1;
	YAC_SG(segments_num_mask) 	= YAC_SG(segments_num) - 1;
	YAC_SG(segments)     		= (yac_shared_segment **)((char *)yac_storage + YAC_SMM_ALIGNED_SIZE(sizeof(yac_storage_globals) + segment_size - sizeof(yac_shared_segment)));

	p = (char *)YAC_SG(segments) + (sizeof(void *) * YAC_SG(segments_num));
	memcpy(p, (char *)segments + segment_size, segments_array_size);
	for (i = 0; i < YAC_SG(segments_num); i++) {
		YAC_SG(segments)[i] = (yac_shared_segment *)p;
		p += segment_size;
	}
	YAC_SG(slots) = (yac_kv_key *)((char *)YAC_SG(segments)
			+ (YAC_SG(segments_num) * sizeof(void *)) + YAC_SMM_ALIGNED_SIZE(segments_array_size));

	free(segments);

	return 1;
}
Beispiel #3
0
Datei: shm.c Projekt: 9618211/yac
static int create_segments(size_t k_size, size_t v_size, yac_shared_segment_shm **shared_segments_p, int *shared_segments_count, char **error_in) /* {{{ */ {
	struct shmid_ds sds;
	int shm_id, shmget_flags;
	yac_shared_segment_shm *shared_segments, first_segment;
    unsigned int i, j, allocate_size, allocated_num, segments_num, segment_size;

	shmget_flags = IPC_CREAT|SHM_R|SHM_W|IPC_EXCL;
    segments_num = 1024;
    while ((v_size / segments_num) < YAC_SMM_SEGMENT_MIN_SIZE) {
        segments_num >>= 1;
    }
    segment_size = v_size / segments_num;
    allocate_size = YAC_SMM_SEGMENT_MAX_SIZE;

    while ((shm_id = shmget(IPC_PRIVATE, allocate_size, shmget_flags)) < 0) {
        allocate_size >>= 1;
    }

    if (shm_id < 0) {
        /* this should never happen */
        *error_in = "shmget";
        return 0;
    }

    if (allocate_size < YAC_SMM_SEGMENT_MIN_SIZE) {
        /* this should never happen */
        *error_in = "shmget";
        return 0;
    }

    if (k_size <= allocate_size) {
        first_segment.shm_id = shm_id;
        first_segment.common.pos = 0;
        first_segment.common.size = allocate_size;
        first_segment.common.p = shmat(shm_id, NULL, 0);
        shmctl(shm_id, IPC_RMID, &sds);
        if (first_segment.common.p == (void *)-1) {
            *error_in = "shmat";
            return 0;
        }
    } else {
        shmctl(shm_id, IPC_RMID, &sds);
        *error_in = "shmget";
        return 0;
    }

    allocated_num = (v_size % allocate_size)? (v_size / allocate_size) + 1 : (v_size / allocate_size);
    shared_segments = (yac_shared_segment_shm *)calloc(1, (allocated_num) * sizeof(yac_shared_segment_shm));
    if (!shared_segments) {
        *error_in = "calloc";
        return 0;
    }

    for (i = 0; i < allocated_num; i ++) {
        shm_id = shmget(IPC_PRIVATE, allocate_size, shmget_flags);
        if (shm_id == -1) {
            *error_in = "shmget";
            for (j = 0; j < i; j++) {
                shmdt(shared_segments[j].common.p);
            }
            free(shared_segments);
            return 0;
        }
        shared_segments[i].shm_id = shm_id;
        shared_segments[i].common.pos = 0;
        shared_segments[i].common.size = allocate_size;
        shared_segments[i].common.p = shmat(shm_id, NULL, 0);
        shmctl(shm_id, IPC_RMID, &sds);
        if (shared_segments[i].common.p == (void *)-1) {
            *error_in = "shmat";
            for (j = 0; j < i; j++) {
                shmdt(shared_segments[j].common.p);
            }
            free(shared_segments);
            return 0;
        }
    }

    ++segments_num;
    *shared_segments_p = (yac_shared_segment_shm *)calloc(1, segments_num * sizeof(yac_shared_segment_shm));
    if (!*shared_segments_p) {
		free(shared_segments);
        *error_in = "calloc";
        return 0;
    } else {
        *shared_segments_p[0] = first_segment;
    }
    *shared_segments_count = segments_num;

    j = 0;
    for (i = 1; i < segments_num; i++) {
        if (shared_segments[j].common.pos == 0) {
            (*shared_segments_p)[i].shm_id = shared_segments[j].shm_id;
        }

        if ((shared_segments[j].common.size - shared_segments[j].common.pos) >= (2 * YAC_SMM_ALIGNED_SIZE(segment_size))) {
            (*shared_segments_p)[i].common.pos = 0;
            (*shared_segments_p)[i].common.size = YAC_SMM_ALIGNED_SIZE(segment_size);
            (*shared_segments_p)[i].common.p = shared_segments[j].common.p + YAC_SMM_ALIGNED_SIZE(shared_segments[j].common.pos);
            shared_segments[j].common.pos += YAC_SMM_ALIGNED_SIZE(segment_size);
        } else {
            (*shared_segments_p)[i].common.pos = 0;
            (*shared_segments_p)[i].common.size = shared_segments[j].common.size - shared_segments[j].common.pos;
            (*shared_segments_p)[i].common.p = shared_segments[j].common.p + YAC_SMM_ALIGNED_SIZE(shared_segments[j].common.pos);
            j++;
        }
    }

    free(shared_segments);

	return 1;
}