File: opal_free_list.c

package info (click to toggle)
openmpi 1.6.5-9.1%2Bdeb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 91,628 kB
  • ctags: 44,305
  • sloc: ansic: 408,966; cpp: 44,454; sh: 27,828; makefile: 10,486; asm: 3,882; python: 1,239; lex: 805; perl: 549; csh: 253; fortran: 232; f90: 126; tcl: 12
file content (129 lines) | stat: -rw-r--r-- 4,317 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
 * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
 *                         University Research and Technology
 *                         Corporation.  All rights reserved.
 * Copyright (c) 2004-2008 The University of Tennessee and The University
 *                         of Tennessee Research Foundation.  All rights
 *                         reserved.
 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, 
 *                         University of Stuttgart.  All rights reserved.
 * Copyright (c) 2004-2005 The Regents of the University of California.
 *                         All rights reserved.
 * Copyright (c) 2010      Cisco Systems, Inc.  All rights reserved.
 * $COPYRIGHT$
 * 
 * Additional copyrights may follow
 * 
 * $HEADER$
 */

#include "opal_config.h"

#include "opal/class/opal_free_list.h"
#include "opal/runtime/opal.h"

static void opal_free_list_construct(opal_free_list_t* fl);
static void opal_free_list_destruct(opal_free_list_t* fl);

OBJ_CLASS_INSTANCE(opal_free_list_t,
                   opal_list_t,
                   opal_free_list_construct,
                   opal_free_list_destruct);
OBJ_CLASS_INSTANCE(opal_free_list_item_t,
                   opal_list_item_t,
                   NULL, NULL);

static void opal_free_list_construct(opal_free_list_t* fl)
{
    OBJ_CONSTRUCT(&fl->fl_lock, opal_mutex_t);
    OBJ_CONSTRUCT(&fl->fl_condition, opal_condition_t);
    fl->fl_max_to_alloc = 0;
    fl->fl_num_allocated = 0;
    fl->fl_num_per_alloc = 0;
    fl->fl_num_waiting = 0;
    fl->fl_elem_size = 0;
    fl->fl_elem_class = 0;
    OBJ_CONSTRUCT(&(fl->fl_allocations), opal_list_t);
}

static void opal_free_list_destruct(opal_free_list_t* fl)
{
    opal_list_item_t *item;

    while (NULL != (item = opal_list_remove_first(&(fl->fl_allocations)))) {
        /* destruct the item (we constructed it), then free the memory chunk */
        OBJ_DESTRUCT(item);
        free(item);
    }

    OBJ_DESTRUCT(&fl->fl_allocations);
    OBJ_DESTRUCT(&fl->fl_condition);
    OBJ_DESTRUCT(&fl->fl_lock);
}

int opal_free_list_init(
    opal_free_list_t *flist,
    size_t elem_size,
    opal_class_t* elem_class,
    int num_elements_to_alloc,
    int max_elements_to_alloc,
    int num_elements_per_alloc)
{
    flist->fl_elem_size = elem_size;
    flist->fl_elem_class = elem_class;
    flist->fl_max_to_alloc = max_elements_to_alloc;
    flist->fl_num_allocated = 0;
    flist->fl_num_per_alloc = num_elements_per_alloc;
    if(num_elements_to_alloc)
        return opal_free_list_grow(flist, num_elements_to_alloc);
    return OPAL_SUCCESS;
}


int opal_free_list_grow(opal_free_list_t* flist, size_t num_elements)
{
    unsigned char* ptr;
    unsigned char* alloc_ptr;
    size_t i;
    size_t mod;

    if (flist->fl_max_to_alloc > 0 && flist->fl_num_allocated + num_elements > flist->fl_max_to_alloc)
        return OPAL_ERR_TEMP_OUT_OF_RESOURCE;

    alloc_ptr = (unsigned char *)malloc((num_elements * flist->fl_elem_size) + 
                                        sizeof(opal_list_item_t) +
                                        opal_cache_line_size);
    if(NULL == alloc_ptr)
        return OPAL_ERR_TEMP_OUT_OF_RESOURCE;

    /* make the alloc_ptr a list item, save the chunk in the allocations list, and
       have ptr point to memory right after the list item structure */
    OBJ_CONSTRUCT(alloc_ptr, opal_list_item_t);
    opal_list_append(&(flist->fl_allocations), (opal_list_item_t*) alloc_ptr);
    ptr = alloc_ptr + sizeof(opal_list_item_t);

    mod = (uintptr_t)ptr % opal_cache_line_size;
    if(mod != 0) {
        ptr += (opal_cache_line_size - mod);
    }

    if (NULL != flist->fl_elem_class) {
        for(i=0; i<num_elements; i++) {
            opal_free_list_item_t* item = (opal_free_list_item_t*)ptr;
            OBJ_CONSTRUCT_INTERNAL(item, flist->fl_elem_class);
            opal_list_append(&(flist->super), &(item->super));
            ptr += flist->fl_elem_size;
        }
    } else {
        for(i=0; i<num_elements; i++) {
            opal_free_list_item_t* item = (opal_free_list_item_t*)ptr;
            opal_list_append(&(flist->super), &(item->super));
            ptr += flist->fl_elem_size;
        }
    }
    flist->fl_num_allocated += num_elements;
    return OPAL_SUCCESS;
}