Changeset 9ace2648 in rtems


Ignore:
Timestamp:
Feb 8, 2018, 8:37:25 AM (3 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
5, master
Children:
a49dfb1
Parents:
abc2164
Message:

fdt: Use self-contained mutex

Update #2843.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libmisc/rtems-fdt/rtems-fdt.c

    rabc2164 r9ace2648  
    1818
    1919#include <rtems/rtems-fdt.h>
    20 #include <rtems/libio_.h>
     20#include <rtems/thread.h>
    2121
    2222/**
     
    5858typedef struct
    5959{
    60   rtems_id            lock;     /**< The FDT lock id */
     60  rtems_mutex         lock;     /**< The FDT lock id */
    6161  rtems_chain_control blobs;    /**< List if loaded blobs. */
    6262  const char*         paths;    /**< Search paths for blobs. */
    6363} rtems_fdt_data;
    6464
    65 /**
    66  * Semaphore configuration to create a mutex.
    67  */
    68 #define RTEMS_MUTEX_ATTRIBS                                           \
    69   (RTEMS_PRIORITY | RTEMS_BINARY_SEMAPHORE |                          \
    70    RTEMS_INHERIT_PRIORITY | RTEMS_NO_PRIORITY_CEILING | RTEMS_LOCAL)
    71 
    72 /**
    73  * The FDT data.
    74  */
    75 static rtems_fdt_data* fdt_data;
    76 
    77 static bool
    78 rtems_fdt_unlock (void)
    79 {
    80   /*
    81    * Not sure any error should be returned or an assert.
    82    */
    83   rtems_status_code sc;
    84   sc = rtems_semaphore_release (fdt_data->lock);
    85   if ((sc != RTEMS_SUCCESSFUL) && (errno == 0))
    86   {
    87     errno = EINVAL;
    88     return false;
    89   }
    90   return true;
    91 }
    92 
    93 static bool
    94 rtems_fdt_data_init (void)
    95 {
    96   /*
    97    * Lock the FDT. We only create a lock if a call is made. First we test if a
    98    * lock is present. If one is present we lock it. If not the libio lock is
    99    * locked and we then test the lock again. If not present we create the lock
    100    * then release libio lock.
    101    */
    102   if (!fdt_data)
    103   {
    104     rtems_libio_lock ();
    105 
    106     if (!fdt_data)
    107     {
    108       rtems_status_code sc;
    109       rtems_id          lock;
    110 
    111       /*
    112        * Always in the heap.
    113        */
    114       fdt_data = malloc (sizeof (rtems_fdt_data));
    115       if (!fdt_data)
    116       {
    117         errno = ENOMEM;
    118         return false;
    119       }
    120 
    121       *fdt_data = (rtems_fdt_data) { 0 };
    122 
    123       /*
    124        * Create the FDT lock.
    125        */
    126       sc = rtems_semaphore_create (rtems_build_name ('F', 'D', 'T', ' '),
    127                                    1, RTEMS_MUTEX_ATTRIBS,
    128                                    RTEMS_NO_PRIORITY, &lock);
    129       if (sc != RTEMS_SUCCESSFUL)
    130       {
    131         free (fdt_data);
    132         return false;
    133       }
    134 
    135       sc = rtems_semaphore_obtain (lock, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
    136       if (sc != RTEMS_SUCCESSFUL)
    137       {
    138         rtems_semaphore_delete (lock);
    139         free (fdt_data);
    140         return false;
    141       }
    142 
    143       fdt_data->lock = lock;
    144 
    145       /*
    146        * Initialise the blob list.
    147        */
    148       rtems_chain_initialize_empty (&fdt_data->blobs);
    149     }
    150 
    151     rtems_libio_unlock ();
    152 
    153     rtems_fdt_unlock ();
    154   }
    155 
    156   return true;
     65static void
     66rtems_fdt_unlock (rtems_fdt_data *fdt)
     67{
     68  rtems_mutex_unlock (&fdt->lock);
    15769}
    15870
     
    16072rtems_fdt_lock (void)
    16173{
    162   rtems_status_code sc;
    163 
    164   if (!rtems_fdt_data_init ())
    165     return NULL;
    166 
    167   sc = rtems_semaphore_obtain (fdt_data->lock,
    168                                RTEMS_WAIT, RTEMS_NO_TIMEOUT);
    169   if (sc != RTEMS_SUCCESSFUL)
    170   {
    171     errno = EINVAL;
    172     return NULL;
    173   }
    174 
    175   return fdt_data;
     74  static rtems_fdt_data fdt_instance = {
     75    .lock = RTEMS_MUTEX_INITIALIZER ("FDT"),
     76    .blobs = RTEMS_CHAIN_INITIALIZER_EMPTY (fdt_instance.blobs)
     77  };
     78  rtems_fdt_data *fdt = &fdt_instance;
     79
     80  rtems_mutex_lock (&fdt->lock);
     81  return fdt;
    17682}
    17783
     
    439345  if (from && to)
    440346  {
    441     (void) rtems_fdt_lock ();
     347    rtems_fdt_data* fdt;
     348
     349    fdt = rtems_fdt_lock ();
    442350    to->blob = from->blob;
    443351    ++to->blob->refs;
    444     rtems_fdt_unlock ();
     352    rtems_fdt_unlock (fdt);
    445353  }
    446354}
     
    470378    }
    471379
    472     rtems_fdt_unlock ();
     380    rtems_fdt_unlock (fdt);
    473381
    474382    handle->blob = NULL;
     
    493401      if (handle->blob == blob)
    494402      {
    495         rtems_fdt_unlock ();
     403        rtems_fdt_unlock (fdt);
    496404        return true;
    497405      }
     
    499407    }
    500408
    501     rtems_fdt_unlock ();
     409    rtems_fdt_unlock (fdt);
    502410  }
    503411
     
    530438      ++temp_handle.blob->refs;
    531439      handle->blob = temp_handle.blob;
    532       rtems_fdt_unlock ();
     440      rtems_fdt_unlock (fdt);
    533441      return offset;
    534442    }
     
    537445  }
    538446
    539   rtems_fdt_unlock ();
     447  rtems_fdt_unlock (fdt);
    540448
    541449  return -FDT_ERR_NOTFOUND;
     
    694602  blob->refs = 1;
    695603
    696   rtems_fdt_unlock ();
     604  rtems_fdt_unlock (fdt);
    697605
    698606  handle->blob = blob;
     
    738646  blob->refs = 1;
    739647
    740   rtems_fdt_unlock ();
     648  rtems_fdt_unlock (fdt);
    741649
    742650  handle->blob = blob;
     
    755663rtems_fdt_unload (rtems_fdt_handle* handle)
    756664{
    757   (void) rtems_fdt_lock ();
     665  rtems_fdt_data* fdt;
     666
     667  fdt = rtems_fdt_lock ();
    758668
    759669  if (!rtems_fdt_valid_handle (handle))
    760670  {
    761     rtems_fdt_unlock ();
     671    rtems_fdt_unlock (fdt);
    762672    return -RTEMS_FDT_ERR_INVALID_HANDLE;
    763673  }
     
    765675  if (handle->blob->refs > 1)
    766676  {
    767     rtems_fdt_unlock ();
     677    rtems_fdt_unlock (fdt);
    768678    return -RTEMS_FDT_ERR_REFERENCED;
    769679  }
     
    775685  handle->blob = NULL;
    776686
    777   rtems_fdt_unlock ();
     687  rtems_fdt_unlock (fdt);
    778688
    779689  rtems_fdt_release_index(&handle->blob->index);
Note: See TracChangeset for help on using the changeset viewer.