Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / libcfs / libcfs / winnt / winnt-mem.c
diff --git a/libcfs/libcfs/winnt/winnt-mem.c b/libcfs/libcfs/winnt/winnt-mem.c
new file mode 100644 (file)
index 0000000..6b66a95
--- /dev/null
@@ -0,0 +1,332 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=4:tabstop=4:
+ *
+ * Copyright (C) 2001, 2002 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+
+#include <libcfs/libcfs.h>
+
+
+cfs_mem_cache_t *cfs_page_t_slab = NULL;
+cfs_mem_cache_t *cfs_page_p_slab = NULL;
+
+/*
+ * cfs_alloc_page
+ *   To allocate the cfs_page_t and also 1 page of memory
+ *
+ * Arguments:
+ *   flags:  the allocation options
+ *
+ * Return Value:
+ *   pointer to the cfs_page_t strcture in success or
+ *   NULL in failure case
+ *
+ * Notes: 
+ *   N/A
+ */
+
+cfs_page_t * cfs_alloc_page(int flags)
+{
+    cfs_page_t *pg;
+    pg = cfs_mem_cache_alloc(cfs_page_t_slab, 0);
+    
+    if (NULL == pg) {
+        cfs_enter_debugger();
+        return NULL;
+    }
+
+    memset(pg, 0, sizeof(cfs_page_t));
+    pg->addr = cfs_mem_cache_alloc(cfs_page_p_slab, 0);
+    atomic_set(&pg->count, 1);
+
+    if (pg->addr) {
+        if (cfs_is_flag_set(flags, CFS_ALLOC_ZERO)) {
+            memset(pg->addr, 0, CFS_PAGE_SIZE);
+        }
+    } else {
+        cfs_enter_debugger();
+        cfs_mem_cache_free(cfs_page_t_slab, pg);
+        pg = NULL;
+    }
+
+    return pg;
+}
+
+/*
+ * cfs_free_page
+ *   To free the cfs_page_t including the page
+ *
+ * Arguments:
+ *   pg:  pointer to the cfs_page_t strcture
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *   N/A
+ */
+void cfs_free_page(cfs_page_t *pg)
+{
+    ASSERT(pg != NULL);
+    ASSERT(pg->addr  != NULL);
+    ASSERT(atomic_read(&pg->count) <= 1);
+
+    cfs_mem_cache_free(cfs_page_p_slab, pg->addr);
+    cfs_mem_cache_free(cfs_page_t_slab, pg);
+}
+
+
+/*
+ * cfs_alloc
+ *   To allocate memory from system pool
+ *
+ * Arguments:
+ *   nr_bytes:  length in bytes of the requested buffer
+ *   flags:     flags indiction
+ *
+ * Return Value:
+ *   NULL: if there's no enough memory space in system
+ *   the address of the allocated memory in success.
+ *
+ * Notes: 
+ *   This operation can be treated as atomic.
+ */
+
+void *
+cfs_alloc(size_t nr_bytes, u_int32_t flags)
+{
+       void *ptr;
+
+    /* Ignore the flags: always allcoate from NonPagedPool */
+
+       ptr = ExAllocatePoolWithTag(NonPagedPool, nr_bytes, 'Lufs');
+
+       if (ptr != NULL && (flags & CFS_ALLOC_ZERO)) {
+               memset(ptr, 0, nr_bytes);
+    }
+
+    if (!ptr) {
+        cfs_enter_debugger();
+    }
+
+       return ptr;
+}
+
+/*
+ * cfs_free
+ *   To free the sepcified memory to system pool
+ *
+ * Arguments:
+ *   addr:   pointer to the buffer to be freed
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *    This operation can be treated as atomic.
+ */
+
+void
+cfs_free(void *addr)
+{
+       ExFreePool(addr);
+}
+
+/*
+ * cfs_alloc_large
+ *   To allocate large block of memory from system pool
+ *
+ * Arguments:
+ *   nr_bytes:  length in bytes of the requested buffer
+ *
+ * Return Value:
+ *   NULL: if there's no enough memory space in system
+ *   the address of the allocated memory in success.
+ *
+ * Notes: 
+ *   N/A
+ */
+
+void *
+cfs_alloc_large(size_t nr_bytes)
+{
+       return cfs_alloc(nr_bytes, 0);
+}
+
+/*
+ * cfs_free_large
+ *   To free the sepcified memory to system pool
+ *
+ * Arguments:
+ *   addr:   pointer to the buffer to be freed
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *   N/A
+ */
+
+void
+cfs_free_large(void *addr)
+{
+       cfs_free(addr);
+}
+
+
+/*
+ * cfs_mem_cache_create
+ *   To create a SLAB cache
+ *
+ * Arguments:
+ *   name:   name string of the SLAB cache to be created
+ *   size:   size in bytes of SLAB entry buffer
+ *   offset: offset in the page
+ *   flags:  SLAB creation flags
+*
+ * Return Value:
+ *   The poitner of cfs_memory_cache structure in success.
+ *   NULL pointer in failure case.
+ *
+ * Notes: 
+ *   1, offset won't be used here.
+ *   2, it could be better to induce a lock to protect the access of the
+ *       SLAB structure on SMP if there's not outside lock protection.
+ *   3, parameters C/D are removed.
+ */
+
+cfs_mem_cache_t *
+cfs_mem_cache_create(
+    const char * name,
+    size_t size,
+    size_t offset,
+    unsigned long flags
+    )
+{
+    cfs_mem_cache_t * kmc = NULL;
+
+    /*  The name of the SLAB could not exceed 20 chars */
+
+    if (name && strlen(name) >= 20) {
+        goto errorout;
+    }
+
+    /* Allocate and initialize the SLAB strcture */
+
+    kmc = cfs_alloc (sizeof(cfs_mem_cache_t), 0);
+
+    if (NULL == kmc) {
+        goto errorout;
+    }
+
+    memset(kmc, 0, sizeof(cfs_mem_cache_t));
+
+    kmc->flags = flags;
+
+    if (name) {
+        strcpy(&kmc->name[0], name);
+    }
+
+    /* Initialize the corresponding LookAside list */
+
+    ExInitializeNPagedLookasideList(
+            &(kmc->npll),
+            NULL,
+            NULL,
+            0,
+            size,
+            'pnmk',
+            0);
+errorout:
+
+    return kmc;
+}
+
+/*
+ * cfs_mem_cache_destroy
+ *   To destroy the unused SLAB cache
+ *
+ * Arguments:
+ *   kmc: the SLAB cache to be destroied.
+ *
+ * Return Value:
+ *   0: in success case.
+ *   1: in failure case.
+ *
+ * Notes: 
+ *   N/A
+ */
+
+int cfs_mem_cache_destroy (cfs_mem_cache_t * kmc)
+{
+    ASSERT(kmc != NULL);
+
+    ExDeleteNPagedLookasideList(&(kmc->npll));
+
+    cfs_free(kmc);
+
+    return 0;
+}
+
+/*
+ * cfs_mem_cache_alloc
+ *   To allocate an object (LookAside entry) from the SLAB
+ *
+ * Arguments:
+ *   kmc:   the SLAB cache to be allocated from.
+ *   flags: flags for allocation options
+ *
+ * Return Value:
+ *   object buffer address: in success case.
+ *   NULL: in failure case.
+ *
+ * Notes: 
+ *   N/A
+ */
+
+void *cfs_mem_cache_alloc(cfs_mem_cache_t * kmc, int flags)
+{
+    void *buf = NULL;
+
+    buf = ExAllocateFromNPagedLookasideList(&(kmc->npll));
+
+    return buf;
+}
+
+/*
+ * cfs_mem_cache_free
+ *   To free an object (LookAside entry) to the SLAB cache
+ *
+ * Arguments:
+ *   kmc: the SLAB cache to be freed to.
+ *   buf: the pointer to the object to be freed.
+ *
+ * Return Value:
+ *   N/A
+ *
+ * Notes: 
+ *   N/A
+ */
+
+void cfs_mem_cache_free(cfs_mem_cache_t * kmc, void * buf)
+{
+    ExFreeToNPagedLookasideList(&(kmc->npll), buf);
+}