OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [io/] [fileio/] [v2_0/] [src/] [inocache.cxx] - Blame information for rev 308

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//=============================================================================
2
//
3
//      inocache.cxx
4
//
5
//      Implementation of inode cache
6
//
7
//=============================================================================
8
//####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under
14
// the terms of the GNU General Public License as published by the Free
15
// Software Foundation; either version 2 or (at your option) any later version.
16
//
17
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20
// for more details.
21
//
22
// You should have received a copy of the GNU General Public License along
23
// with eCos; if not, write to the Free Software Foundation, Inc.,
24
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25
//
26
// As a special exception, if other files instantiate templates or use macros
27
// or inline functions from this file, or you compile this file and link it
28
// with other works to produce a work based on this file, this file does not
29
// by itself cause the resulting work to be covered by the GNU General Public
30
// License. However the source code for this file must still be made available
31
// in accordance with section (3) of the GNU General Public License.
32
//
33
// This exception does not invalidate any other reasons why a work based on
34
// this file might be covered by the GNU General Public License.
35
//
36
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37
// at http://sources.redhat.com/ecos/ecos-license/
38
// -------------------------------------------
39
//####ECOSGPLCOPYRIGHTEND####
40
//=============================================================================
41
//#####DESCRIPTIONBEGIN####
42
//
43
// Author(s):     jlarmour
44
// Contributors:  
45
// Date:          2002-01-18
46
// Purpose:       
47
// Description:   
48
// Usage:
49
//              #include <cyg/fileio/inode.h>
50
//              ...
51
//              
52
//
53
//####DESCRIPTIONEND####
54
//
55
//=============================================================================
56
 
57
#include <pkgconf/system.h>
58
#include <cyg/infra/cyg_type.h>
59
#include <stdlib.h>
60
#include <cyg/fileio/inode.h>
61
 
62
#ifdef CYGPKG_KERNEL
63
# include <pkgconf/kernel.h>
64
# include <cyg/kernel/mutex.hxx>
65
# if 0
66
# define LOCK_ICACHE(_ic_)        \
67
  CYG_MACRO_START                 \
68
  (_ic_)->icmutex.lock();         \
69
  CYG_MACRO_END
70
 
71
# define UNLOCK_ICACHE(_ic_)      \
72
  CYG_MACRO_START                 \
73
  (_ic_)->icmutex.unlock();       \
74
  CYG_MACRO_END
75
# define LOCK_INO(_ic_,_ino_)     \
76
  CYG_MACRO_START                 \
77
  (_ic_)->icmutex.lock();         \
78
  CYG_MACRO_END
79
# define UNLOCK_INO(_ic_,_ino_)   \
80
  CYG_MACRO_START                 \
81
  (_ic_)->icmutex.unlock();       \
82
  CYG_MACRO_END
83
# endif
84
#endif
85
 
86
# define LOCK_ICACHE(_ic_)         CYG_EMPTY_STATEMENT
87
# define UNLOCK_ICACHE(_ic_)       CYG_EMPTY_STATEMENT
88
# define LOCK_INO(_ic_,_ino_)      CYG_EMPTY_STATEMENT
89
# define UNLOCK_INO(_ic_,_ino_)    CYG_EMPTY_STATEMENT
90
 
91
// Tried to make this implementation use tables, but the requirement to
92
// allow for extra space makes this difficult
93
 
94
__externC void
95
cyg_inodecache_destroy( cyg_inodecache *ic )
96
{
97
    cyg_inode *tmp;
98
    for ( tmp=ic->head; tmp != NULL; tmp=tmp->i_cache_next )
99
        free(tmp);
100
#if CYGNUM_IO_FILEIO_MAX_INODE_CACHE_DEAD > 0
101
    for ( tmp=ic->freeable; tmp != NULL; tmp=tmp->i_cache_next )
102
        free(tmp);
103
#endif    
104
} // cyg_inodecache_destroy()
105
 
106
static __inline__ void
107
insert_in_list( cyg_inode **i, cyg_inode *ino )
108
{
109
    cyg_inode *here = *i;
110
    if ( here == NULL ) {
111
        ino->i_cache_prev = ino->i_cache_next = ino;
112
    } else {
113
        ino->i_cache_prev = here->i_cache_prev;
114
        ino->i_cache_next = here;
115
        here->i_cache_prev = ino;
116
        ino->i_cache_prev->i_cache_next = ino;
117
    }
118
    // put at start, as this is more likely to come off sooner than later
119
    *i = ino;
120
}
121
 
122
// Create an inode. Returns a negative error code on error.
123
__externC cyg_inode *
124
cyg_inode_create( cyg_inodecache *ic )
125
{
126
    cyg_inode *ni;
127
 
128
    ni = (cyg_inode *)malloc( sizeof(cyg_inode)+ic->privatespace );
129
    if ( !ni )
130
        return ni;
131
    ni->i_count = 1;
132
 
133
    LOCK_ICACHE(ic);
134
    insert_in_list( &ic->head, ni );
135
    UNLOCK_ICACHE(ic);
136
 
137
    return ni;
138
} // cyg_inode_create()
139
 
140
__externC cyg_inode *
141
cyg_inode_get( cyg_inodecache *ic, cyg_uint32 ino )
142
{
143
    cyg_inode *head = ic->head;
144
    // first try the (live) cache
145
    if (head) {
146
        cyg_inode *tmp=head;
147
        while (1) {
148
            if ( tmp->i_ino == ino ) {
149
                tmp->i_count++;
150
                return tmp;
151
            }
152
            tmp = tmp->i_cache_next;
153
            if ( tmp == head )
154
                break;
155
        }
156
    }
157
#if CYGNUM_IO_FILEIO_MAX_INODE_CACHE_DEAD > 0
158
    // now try the cache of dead inodes
159
    head = ic->freeable;
160
    if (head) {
161
        cyg_inode *tmp=head;
162
        while (1) {
163
            if ( tmp->i_ino == ino ) {
164
                tmp->i_count++;
165
                LOCK_ICACHE(ic);
166
                ic->freeablelistlen--;
167
                if ( ic->freeablelistlen ) {
168
                    tmp->i_cache_prev->i_cache_next = tmp->i_cache_next;
169
                    tmp->i_cache_next->i_cache_prev = tmp->i_cache_prev;
170
                } else
171
                    ic->freeable = NULL;
172
                insert_in_list( &ic->head, tmp );
173
                UNLOCK_ICACHE(ic);
174
                return tmp;
175
            }
176
            tmp = tmp->i_cache_next;
177
            if ( tmp == head )
178
                break;
179
        }
180
    }
181
#endif
182
    // not found so make it
183
    return cyg_inode_create( ic );
184
 
185
} // cyg_inode_get()
186
 
187
__externC void
188
cyg_inode_put( cyg_inodecache *ic, cyg_inode *ino )
189
{
190
    if ( --ino->i_count == 0 )
191
    {
192
        LOCK_ICACHE(ic);
193
        if ( ino->i_cache_next == ino ) {
194
            ic->head = NULL;
195
        } else {
196
            ino->i_cache_prev->i_cache_next = ino->i_cache_next;
197
            ino->i_cache_next->i_cache_prev = ino->i_cache_prev;
198
        }
199
#if CYGNUM_IO_FILEIO_MAX_INODE_CACHE_DEAD > 0
200
        ic->freeablelistlen++;
201
        insert_in_list( &ic->freeable, ino );
202
        if ( ic->freeablelistlen > CYGNUM_IO_FILEIO_MAX_INODE_CACHE_DEAD ) {
203
            cyg_inode *prev = ino->i_cache_prev;
204
            prev->i_cache_prev->i_cache_next = ino;
205
            ino->i_cache_prev = prev->i_cache_prev;
206
            ic->freecallback(prev);
207
            free(prev);
208
        }
209
#else
210
        ic->freecallback(ino);
211
        free(ino);
212
#endif
213
    }
214
} // cyg_inode_put()
215
 
216
// EOF inode.h

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.