Justus Winter, le Thu 29 May 2014 18:41:00 +0200, a écrit : > libnetfs has two kind of nodes, struct node and struct netnode. > struct node is used to store libnetfs specific data, while struct > netnode contains user supplied data. Previously, both objects were > allocated separatly, and a pointer from the node to the netnode > provided a mapping from the former to the latter. > > Provide a function netfs_make_node_alloc that allocates both nodes in > a contiguous region. > > This reduces the memory allocation overhead when creating nodes. It > also makes the relation between node and netnode a simple offset > calculation. Provide two functions to compute the netnode address > from the node address and vice-versa. > > Most notably, this makes implementing a cache on top of libnetfs > easier. Auxiliary data for the cache can be stored in the > user-defined netnode, and the fat node can be used as the value.
Ack. > * libnetfs/make-node.c (init_node): Move initialization here. > (netfs_make_node): Use init_node. > (netfs_make_node_alloc): New function to allocate fat nodes. > * libnetfs/netfs.h (netfs_make_node_alloc): New declaration. > (_netfs_sizeof_struct_node): Likewise. > (netfs_node_netnode): Compute netnode address from node address. > (netfs_netnode_node): And vice-versa. > * libnetfs/init-init.c (_netfs_sizeof_struct_node): New variable. > --- > libnetfs/init-init.c | 3 +++ > libnetfs/make-node.c | 29 +++++++++++++++++++++++------ > libnetfs/netfs.h | 27 +++++++++++++++++++++++++++ > 3 files changed, 53 insertions(+), 6 deletions(-) > > diff --git a/libnetfs/init-init.c b/libnetfs/init-init.c > index e98b656..a088ad5 100644 > --- a/libnetfs/init-init.c > +++ b/libnetfs/init-init.c > @@ -21,6 +21,9 @@ > > #include "netfs.h" > > +/* For safe inlining of netfs_node_netnode and netfs_netnode_node. */ > +size_t const _netfs_sizeof_struct_node = sizeof (struct node); > + > pthread_spinlock_t netfs_node_refcnt_lock = PTHREAD_SPINLOCK_INITIALIZER; > > struct node *netfs_root_node = 0; > diff --git a/libnetfs/make-node.c b/libnetfs/make-node.c > index f20ada1..6bd8109 100644 > --- a/libnetfs/make-node.c > +++ b/libnetfs/make-node.c > @@ -21,13 +21,9 @@ > #include "netfs.h" > #include <hurd/fshelp.h> > > -struct node * > -netfs_make_node (struct netnode *nn) > +static struct node * > +init_node (struct node *np, struct netnode *nn) > { > - struct node *np = malloc (sizeof (struct node)); > - if (! np) > - return NULL; > - > np->nn = nn; > > pthread_mutex_init (&np->lock, NULL); > @@ -40,3 +36,24 @@ netfs_make_node (struct netnode *nn) > > return np; > } > + > +struct node * > +netfs_make_node (struct netnode *nn) > +{ > + struct node *np = malloc (sizeof (struct node)); > + if (! np) > + return NULL; > + > + return init_node (np, nn); > +} > + > +struct node * > +netfs_make_node_alloc (size_t size) > +{ > + struct node *np = malloc (sizeof (struct node) + size); > + > + if (np == NULL) > + return NULL; > + > + return init_node (np, netfs_node_netnode (np)); > +} > diff --git a/libnetfs/netfs.h b/libnetfs/netfs.h > index aef4a3d..fbe2c60 100644 > --- a/libnetfs/netfs.h > +++ b/libnetfs/netfs.h > @@ -372,6 +372,33 @@ extern int netfs_maxsymlinks; > If an error occurs, NULL is returned. */ > struct node *netfs_make_node (struct netnode *); > > +/* Create a new node structure. Also allocate SIZE bytes for the > + netnode. The address of the netnode can be obtained using > + netfs_node_netnode. The new node will have one hard reference and > + no light references. If an error occurs, NULL is returned. */ > +struct node *netfs_make_node_alloc (size_t size); > + > +/* To avoid breaking the ABI whenever sizeof (struct node) changes, we > + explicitly provide the size. The following two functions will use > + this value for offset calculations. */ > +extern const size_t _netfs_sizeof_struct_node; > + > +/* Return the address of the netnode for NODE. NODE must have been > + allocated using netfs_make_node_alloc. */ > +static inline struct netnode * > +netfs_node_netnode (struct node *node) > +{ > + return (struct netnode *) ((char *) node + _netfs_sizeof_struct_node); > +} > + > +/* Return the address of the node for NETNODE. NETNODE must have been > + allocated using netfs_make_node_alloc. */ > +static inline struct node * > +netfs_netnode_node (struct netnode *netnode) > +{ > + return (struct node *) ((char *) netnode - _netfs_sizeof_struct_node); > +} > + > /* Whenever node->references is to be touched, this lock must be > held. Cf. netfs_nrele, netfs_nput, netfs_nref and netfs_drop_node. */ > extern pthread_spinlock_t netfs_node_refcnt_lock; > -- > 2.0.0.rc2 > -- Samuel Yep. Moi j'ai un clavier à une touche. Par contre, ma souris a 102 boutons, c'est pas toujours pratique. -+- OG in: Guide du Cabaliste Usenet - Le mulot contre attaque -+-