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 -+-

Reply via email to