yaffsfs.c: Fix NULL dereference in yaffs_unmount2_reldev()
[yaffs2.git] / direct / test-framework / yaffs_osglue.c
index 9d8327496f374d5dce3c47a68a1afb7926aeeb1c..94ca24dfd225a73bde9924f6c51a73672ed1c89b 100644 (file)
@@ -1,8 +1,7 @@
 /*
  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
  *
- * Copyright (C) 2002-2011 Aleph One Ltd.
- *   for Toby Churchill Ltd and Brightstar Engineering
+ * Copyright (C) 2002-2018 Aleph One Ltd.
  *
  * Created by Charles Manning <charles@aleph1.co.uk>
  *
@@ -11,7 +10,7 @@
  * published by the Free Software Foundation.
  */
 
-/* 
+/*
  * Example OS glue functions for running on a Linux/POSIX system.
  */
 
@@ -22,6 +21,7 @@
 #include <assert.h>
 
 #include <errno.h>
+#include <unistd.h>
 
 /*
  * yaffsfs_SetError() and yaffsfs_GetError()
@@ -52,6 +52,9 @@ int yaffsfs_GetLastError(void)
  */
 int yaffsfs_CheckMemRegion(const void *addr, size_t size, int write_request)
 {
+       (void) size;
+       (void) write_request;
+
        if(!addr)
                return -1;
        return 0;
@@ -62,12 +65,16 @@ int yaffsfs_CheckMemRegion(const void *addr, size_t size, int write_request)
  * yaffsfs_Unlock()
  * A single mechanism to lock and unlock yaffs. Hook up to a mutex or whatever.
  * Here are two examples, one using POSIX pthreads, the other doing nothing.
+ *
+ * If we use pthreads then we also start a background gc thread.
  */
 
-#ifdef CONFIG_YAFFS_USE_PTHREADS
+#if 1
+
 #include <pthread.h>
-static pthread_mutex_t mutex1;
 
+static pthread_mutex_t mutex1;
+static pthread_t bc_gc_thread;
 
 void yaffsfs_Lock(void)
 {
@@ -79,9 +86,55 @@ void yaffsfs_Unlock(void)
        pthread_mutex_unlock( &mutex1 );
 }
 
+static void *bg_gc_func(void *dummy)
+{
+       struct yaffs_dev *dev;
+       int urgent = 0;
+       int result;
+       int next_urgent;
+
+       (void)dummy;
+
+       /* Sleep for a bit to allow start up */
+       sleep(2);
+
+
+       while (1) {
+               /* Iterate through devices, do bg gc updating ungency */
+               yaffs_dev_rewind();
+               next_urgent = 0;
+
+               while ((dev = yaffs_next_dev()) != NULL) {
+                       result = yaffs_do_background_gc_reldev(dev, urgent);
+
+                       /* result is 1 if more than half the free space is
+                        * erased.
+                        * If less than half the free space is erased then it is
+                        * worth doing another background_gc operation sooner.
+                        */
+                       if (result == 0)
+                               next_urgent = 1;
+               }
+
+               urgent = next_urgent;
+
+               if (next_urgent)
+                       sleep(1);
+               else
+                       sleep(5);
+       }
+
+       /* Don't ever return. */
+       return NULL;
+}
+
 void yaffsfs_LockInit(void)
 {
-       pthread_mutex_init( &mutex1, NULL);
+       /* Initialise lock */
+       pthread_mutex_init(&mutex1, NULL);
+
+       /* Sneak in starting a background gc thread too */
+       pthread_create(&bc_gc_thread, NULL, bg_gc_func, NULL);
 }
 
 #else
@@ -101,10 +154,10 @@ void yaffsfs_LockInit(void)
 
 /*
  * yaffsfs_CurrentTime() retrns a 32-bit timestamp.
- * 
+ *
  * Can return 0 if your system does not care about time.
  */
+
 u32 yaffsfs_CurrentTime(void)
 {
        return time(NULL);
@@ -117,7 +170,49 @@ u32 yaffsfs_CurrentTime(void)
  *
  * Functions to allocate and free memory.
  */
+
+
+static unsigned malloc_high_water;
+static unsigned malloc_currently_allocated;
+
+#ifdef CONFIG_YAFFS_MONITOR_MALLOC
+
+#include <malloc.h>
+static void yaffsfs_malloc_add(void *ptr)
+{
+       unsigned this_size = malloc_usable_size(ptr);
+       malloc_currently_allocated += this_size;
+
+       if (malloc_currently_allocated > malloc_high_water)
+               malloc_high_water = malloc_currently_allocated;
+}
+
+static void yaffsfs_malloc_remove(void *ptr)
+{
+       unsigned this_size = malloc_usable_size(ptr);
+       malloc_currently_allocated -= this_size;
+}
+#else
+static void yaffsfs_malloc_add(void *ptr)
+{
+       (void)ptr;
+}
+
+static void yaffsfs_malloc_remove(void *ptr)
+{
+       (void)ptr;
+}
+#endif
+
+void yaffsfs_get_malloc_values(unsigned *current, unsigned *high_water)
+{
+       if (current)
+               *current = malloc_currently_allocated;
+       if(high_water)
+               *high_water = malloc_high_water;
+}
+
+
 #ifdef CONFIG_YAFFS_TEST_MALLOC
 
 static int yaffs_kill_alloc = 0;
@@ -135,6 +230,7 @@ void *yaffsfs_malloc(size_t size)
        this = malloc(size);
        if(this)
                total_malloced += size;
+       yaffsfs_malloc_add(this);
        return this;
 }
 
@@ -142,13 +238,19 @@ void *yaffsfs_malloc(size_t size)
 
 void *yaffsfs_malloc(size_t size)
 {
-       return malloc(size);
+       void *this = malloc(size);
+       yaffsfs_malloc_add(this);
+       return this;
 }
 
 #endif
 
+
+
+
 void yaffsfs_free(void *ptr)
 {
+       yaffsfs_malloc_remove(ptr);
        free(ptr);
 }
 
@@ -161,7 +263,7 @@ void yaffsfs_OSInitialisation(void)
  * yaffs_bug_fn()
  * Function to report a bug.
  */
+
 void yaffs_bug_fn(const char *file_name, int line_no)
 {
        printf("yaffs bug detected %s:%d\n",