shm_lut.cpp

00001
00002 /***************************************************************************
00003  *  shm_lut.cpp - shared memory lookup table
00004  *
00005  *  Generated: Thu feb 09 17:32:31 2006
00006  *  Copyright  2005-2007  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023
00024 #include <fvutils/ipc/shm_lut.h>
00025 #include <fvutils/ipc/shm_exceptions.h>
00026 #include <utils/system/console_colors.h>
00027
00028 #include <iostream>
00029 #include <cstring>
00030 #include <cstdlib>
00031 #include <cstdio>
00032
00033 using namespace std;
00034 using namespace fawkes;
00035 
00036 /** @class SharedMemoryLookupTable <fvutils/ipc/shm_lut.h>
00037  * Shared memory lookup table.
00038  */
00039 
00040 /** Write Constructor.
00041  * Create a new shared memory segment. Will open a shared memory segment that
00042  * exactly fits the given information. Will throw an error if image with num
00043  * image_num exists it will throw an exception an exception.
00044  * I will create a new segment if no matching segment was found.
00045  * The segment is accessed in read-write mode.
00046  *
00047  * @param lut_id LUT ID
00048  * @param width LUT width
00049  * @param height LUT height
00050  * @param depth LUT depth
00051  * @param bytes_per_cell LUT bytes per cell
00052  */
00053 SharedMemoryLookupTable::SharedMemoryLookupTable(const char *lut_id,
00054                                                  unsigned int width,
00055                                                  unsigned int height,
00056                                                  unsigned int depth,
00057                                                  unsigned int bytes_per_cell)
00058   : SharedMemory(FIREVISION_SHM_LUT_MAGIC_TOKEN, false, true, true)
00059 {
00060   constructor(lut_id, width, height, depth, bytes_per_cell, false);
00061 }
00062 
00063 /** Read constructor.
00064  * This constructor is used to search for an existing shared memory segment.
00065  * It will throw an error if it cannot find a segment with the specified data.
00066  * The segment is opened read-only by default, but this can be overridden with
00067  * the is_read_only argument if needed.
00068  *
00069  * @param lut_id LUT ID
00070  * @param is_read_only true to open read-only
00071  */
00072 SharedMemoryLookupTable::SharedMemoryLookupTable(const char *lut_id,
00073                                                  bool is_read_only)
00074   : SharedMemory(FIREVISION_SHM_LUT_MAGIC_TOKEN, is_read_only, false, false)
00075 {
00076   constructor(lut_id, 0, 0, 0, 0, is_read_only);
00077 }
00078
00079
00080 void
00081 SharedMemoryLookupTable::constructor(const char *lut_id,
00082                                      unsigned int width, unsigned int height,
00083                                      unsigned int depth,
00084                                      unsigned int bytes_per_cell,
00085                                      bool is_read_only)
00086 {
00087   _is_read_only    = is_read_only;
00088   __lut_id         = strdup(lut_id);
00089   __width          = width;
00090   __height         = height;
00091   __depth          = depth;
00092   __bytes_per_cell = bytes_per_cell;
00093
00094   __priv_header = new SharedMemoryLookupTableHeader(__lut_id, __width, __height, __depth, __bytes_per_cell);
00095   _header = __priv_header;
00096   attach();
00097   __raw_header = __priv_header->raw_header();
00098
00099   if (_memptr == NULL) {
00100     throw Exception("Could not create shared memory segment");
00101   }
00102 }
00103
00104 
00105 /** Destructor. */
00106 SharedMemoryLookupTable::~SharedMemoryLookupTable()
00107 {
00108   delete __priv_header;
00109   ::free(__lut_id);
00110 }
00111
00112 
00113 /** Get LUT ID.
00114  * @return LUT ID
00115  */
00116 const char *
00117 SharedMemoryLookupTable::lut_id() const
00118 {
00119   return __lut_id;
00120 }
00121
00122 
00123 /** Set LUT ID.
00124  * @param lut_id LUT ID
00125  * @return true on success
00126  */
00127 bool
00128 SharedMemoryLookupTable::set_lut_id(const char *lut_id)
00129 {
00130   free();
00131   ::free(__lut_id);
00132   __lut_id = strdup(lut_id);
00133   __priv_header->set_lut_id(__lut_id);
00134   attach();
00135   return (_memptr != NULL);
00136 }
00137
00138 
00139 /** Get LUT buffer.
00140  * @return LUT buffer
00141  */
00142 unsigned char *
00143 SharedMemoryLookupTable::buffer() const
00144 {
00145   return (unsigned char *)_memptr;
00146 }
00147
00148 
00149 /** Get LUT width.
00150  * @return LUT width
00151  */
00152 unsigned int
00153 SharedMemoryLookupTable::width() const
00154 {
00155   return __raw_header->width;
00156 }
00157
00158 
00159 /** Get LUT height.
00160  * @return LUT height
00161  */
00162 unsigned int
00163 SharedMemoryLookupTable::height() const
00164 {
00165   return __raw_header->height;
00166 }
00167
00168 
00169 /** Get LUT depth.
00170  * @return LUT depth
00171  */
00172 unsigned int
00173 SharedMemoryLookupTable::depth() const
00174 {
00175   return __raw_header->depth;
00176 }
00177
00178 
00179 /** Get bytes per cell.
00180  * @return bytes per cell
00181  */
00182 unsigned int
00183 SharedMemoryLookupTable::bytes_per_cell() const
00184 {
00185   return __raw_header->bytes_per_cell;
00186 }
00187
00188 
00189 /** List shared memory LUT segments. */
00190 void
00191 SharedMemoryLookupTable::list()
00192 {
00193   SharedMemoryLookupTableLister *lister = new SharedMemoryLookupTableLister();
00194   SharedMemoryLookupTableHeader *h      = new SharedMemoryLookupTableHeader();
00195
00196   SharedMemory::list(FIREVISION_SHM_LUT_MAGIC_TOKEN, h, lister);
00197
00198   delete lister;
00199   delete h;
00200 }
00201
00202 
00203 /** Erase all shared memory segments that contain FireVision LUTs.
00204  * @param use_lister if true a lister is used to print the shared memory segments
00205  * to stdout while cleaning up.
00206  */
00207 void
00208 SharedMemoryLookupTable::cleanup(bool use_lister)
00209 {
00210   SharedMemoryLookupTableLister *lister = NULL;
00211   SharedMemoryLookupTableHeader *h      = new SharedMemoryLookupTableHeader();
00212
00213   if ( use_lister ) {
00214     lister = new SharedMemoryLookupTableLister();
00215   }
00216
00217   SharedMemory::erase_orphaned(FIREVISION_SHM_LUT_MAGIC_TOKEN, h, lister);
00218
00219   delete lister;
00220   delete h;
00221 }
00222
00223 
00224 /** Check LUT availability.
00225  * @param lut_id image number to check
00226  * @return true if shared memory segment with requested LUT exists
00227  */
00228 bool
00229 SharedMemoryLookupTable::exists(const char *lut_id)
00230 {
00231   SharedMemoryLookupTableHeader *h = new SharedMemoryLookupTableHeader(lut_id, 0, 0, 0, 0);
00232   bool ex = SharedMemory::exists(FIREVISION_SHM_LUT_MAGIC_TOKEN, h);
00233   delete h;
00234   return ex;
00235 }
00236
00237 
00238 /** Erase a specific shared memory segment that contains a LUT.
00239  * @param lut_id LUT ID
00240  */
00241 void
00242 SharedMemoryLookupTable::wipe(const char *lut_id)
00243 {
00244   SharedMemoryLookupTableHeader *h = new SharedMemoryLookupTableHeader(lut_id, 0, 0, 0, 0);
00245   SharedMemory::erase(FIREVISION_SHM_LUT_MAGIC_TOKEN, h, NULL);
00246   delete h;
00247 }
00248
00249
00250 
00251 /** @class SharedMemoryLookupTableHeader <fvutils/ipc/shm_lut.h>
00252  * Shared memory lookup table header.
00253  */
00254 
00255 /** Constructor. */
00256 SharedMemoryLookupTableHeader::SharedMemoryLookupTableHeader()
00257 {
00258   __lut_id = NULL;
00259   __width = 0;
00260   __height = 0;
00261   __depth = 0;
00262   __bytes_per_cell = 0;
00263   __header = NULL;
00264 }
00265
00266 
00267 /** Constructor.
00268  * @param lut_id LUT ID
00269  * @param width LUT width
00270  * @param height LUT height
00271  * @param bytes_per_cell bytes per cell
00272  */
00273 SharedMemoryLookupTableHeader::SharedMemoryLookupTableHeader(const char *lut_id,
00274                                                              unsigned int width,
00275                                                              unsigned int height,
00276                                                              unsigned int bytes_per_cell)
00277 {
00278   __lut_id = strdup(lut_id);
00279   __width  = width;
00280   __height = height;
00281   __bytes_per_cell = bytes_per_cell;
00282
00283   __header = NULL;
00284 }
00285
00286 
00287 /** Constructor.
00288  * @param lut_id LUT ID
00289  * @param width LUT width
00290  * @param height LUT height
00291  * @param depth LUT depth
00292  * @param bytes_per_cell bytes per cell
00293  */
00294 SharedMemoryLookupTableHeader::SharedMemoryLookupTableHeader(const char *lut_id,
00295                                                              unsigned int width,
00296                                                              unsigned int height,
00297                                                              unsigned int depth,
00298                                                              unsigned int bytes_per_cell)
00299 {
00300   __lut_id = strdup(lut_id);
00301   __width  = width;
00302   __height = height;
00303   __depth  = depth;
00304   __bytes_per_cell = bytes_per_cell;
00305
00306   __header = NULL;
00307 }
00308
00309 
00310 /** Copy constructor.
00311  * @param h header to copy data from
00312  */
00313 SharedMemoryLookupTableHeader::SharedMemoryLookupTableHeader(const SharedMemoryLookupTableHeader *h)
00314 {
00315   if( h->__lut_id != NULL ) {
00316     __lut_id = strdup(h->__lut_id);
00317   } else {
00318     __lut_id = NULL;
00319   }
00320   __width  = h->__width;
00321   __height = h->__height;
00322   __depth  = h->__depth;
00323   __bytes_per_cell = h->__bytes_per_cell;
00324
00325   __header = NULL;
00326 }
00327
00328 
00329 /** Destructor. */
00330 SharedMemoryLookupTableHeader::~SharedMemoryLookupTableHeader()
00331 {
00332   __header = NULL;
00333   if ( __lut_id != NULL ) {
00334     free(__lut_id);
00335     __lut_id = NULL;
00336   }
00337 }
00338
00339
00340 SharedMemoryHeader *
00341 SharedMemoryLookupTableHeader::clone() const
00342 {
00343   return new SharedMemoryLookupTableHeader(this);
00344 }
00345
00346
00347 size_t
00348 SharedMemoryLookupTableHeader::size()
00349 {
00350   return sizeof(SharedMemoryLookupTable_header_t);
00351 }
00352
00353
00354 size_t
00355 SharedMemoryLookupTableHeader::data_size()
00356 {
00357   if (__header == NULL) {
00358     return __width * __height * __depth * __bytes_per_cell;
00359   } else {
00360     return __header->width * __header->height * __header->depth * __header->bytes_per_cell;
00361   }
00362 }
00363
00364
00365 bool
00366 SharedMemoryLookupTableHeader::matches(void *memptr)
00367 {
00368   SharedMemoryLookupTable_header_t *h = (SharedMemoryLookupTable_header_t *)memptr;
00369
00370   if (__lut_id == NULL) {
00371     return true;
00372
00373   } else if (strncmp(h->lut_id, __lut_id, LUT_ID_MAX_LENGTH) == 0) {
00374
00375     if ( (__width == 0) ||
00376          (__height == 0) ||
00377          (__depth == 0) ||
00378          (__bytes_per_cell == 0) ||
00379          ( (h->width == __width) &&
00380            (h->height == __height) &&
00381            (h->depth == __depth) &&
00382            (h->bytes_per_cell == __bytes_per_cell) )
00383          ) {
00384       return true;
00385     } else {
00386       throw InconsistentLUTException("Inconsistent lookup table found in memory (meta)");
00387     }
00388   } else {
00389     return false;
00390   }
00391
00392 }
00393
00394 
00395 /** Print Info. */
00396 void
00397 SharedMemoryLookupTableHeader::print_info()
00398 {
00399   if (__header == NULL) {
00400     cout << "No image set" << endl;
00401     return;
00402   }
00403   cout << "SharedMemory Lookup Table Info: " << endl
00404        << "    LUT ID:         " << __header->lut_id << endl
00405        << "    dimensions:     " << __header->width << "x" << __header->height << "x"
00406        << __header->depth << endl
00407        << "    bytes per cell: " << __header->bytes_per_cell << endl;
00408 }
00409
00410 
00411 /** Check if buffer should be created.
00412  * @return true, if width, height and bytes per cell are all greater than
00413  * zero.
00414  */
00415 bool
00416 SharedMemoryLookupTableHeader::create()
00417 {
00418   return ( (__width > 0) &&
00419            (__height > 0) &&
00420            (__depth > 0) &&
00421            (__bytes_per_cell > 0) );
00422 }
00423
00424
00425 void
00426 SharedMemoryLookupTableHeader::initialize(void *memptr)
00427 {
00428   __header = (SharedMemoryLookupTable_header_t *)memptr;
00429   memset(memptr, 0, sizeof(SharedMemoryLookupTable_header_t));
00430
00431   strncpy(__header->lut_id, __lut_id, LUT_ID_MAX_LENGTH);
00432   __header->width          = __width;
00433   __header->height         = __height;
00434   __header->depth          = __depth;
00435   __header->bytes_per_cell = __bytes_per_cell;
00436 }
00437
00438
00439 void
00440 SharedMemoryLookupTableHeader::set(void *memptr)
00441 {
00442   __header = (SharedMemoryLookupTable_header_t *)memptr;
00443 }
00444
00445
00446 void
00447 SharedMemoryLookupTableHeader::reset()
00448 {
00449   __header = NULL;
00450 }
00451
00452
00453 bool
00454 SharedMemoryLookupTableHeader::operator==(const SharedMemoryHeader &s) const
00455 {
00456   const SharedMemoryLookupTableHeader *h = dynamic_cast<const SharedMemoryLookupTableHeader *>(&s);
00457   if ( ! h ) {
00458     return false;
00459   } else {
00460     return ( (strncmp(__lut_id, h->__lut_id, LUT_ID_MAX_LENGTH) == 0) &&
00461              (__width == h->__width) &&
00462              (__height == h->__height) &&
00463              (__depth == h->__depth) &&
00464              (__bytes_per_cell == h->__bytes_per_cell) );
00465   }
00466 }
00467
00468 
00469 /** Get LUT width.
00470  * @return LUT width.
00471  */
00472 unsigned int
00473 SharedMemoryLookupTableHeader::width() const
00474 {
00475   if (__header == NULL) return 0;
00476   return __header->width;
00477 }
00478
00479 
00480 /** Get LUT height.
00481  * @return LUT height.
00482  */
00483 unsigned int
00484 SharedMemoryLookupTableHeader::height() const
00485 {
00486   if (__header == NULL) return 0;
00487   return __header->height;
00488 }
00489
00490 
00491 /** Get LUT depth.
00492  * @return LUT depth.
00493  */
00494 unsigned int
00495 SharedMemoryLookupTableHeader::depth() const
00496 {
00497   if (__header == NULL) return 0;
00498   return __header->depth;
00499 }
00500
00501 
00502 /** Get bytes per cell.
00503  * @return bytes per cell.
00504  */
00505 unsigned int
00506 SharedMemoryLookupTableHeader::bytes_per_cell() const
00507 {
00508   if (__header == NULL) return 0;
00509   return __header->bytes_per_cell;
00510 }
00511
00512 
00513 /** Get LUT ID.
00514  * @return LUT Id
00515  */
00516 const char *
00517 SharedMemoryLookupTableHeader::lut_id() const
00518 {
00519   if (__header == NULL) return NULL;
00520   return __header->lut_id;
00521 }
00522
00523 
00524 /** Set LUT ID.
00525  * @param lut_id LUT ID
00526  */
00527 void
00528 SharedMemoryLookupTableHeader::set_lut_id(const char *lut_id)
00529 {
00530   if ( __lut_id )  free(__lut_id);
00531   __lut_id = strdup(lut_id);
00532 }
00533
00534 
00535 /** Get raw header.
00536  * @return raw header.
00537  */
00538 SharedMemoryLookupTable_header_t *
00539 SharedMemoryLookupTableHeader::raw_header()
00540 {
00541   return __header;
00542 }
00543 
00544 /** @class SharedMemoryLookupTableLister <fvutils/ipc/shm_lut.h>
00545  * Shared memory lookup table lister.
00546  */
00547
00548 
00549 /** Constructor. */
00550 SharedMemoryLookupTableLister::SharedMemoryLookupTableLister()
00551 {
00552 }
00553
00554 
00555 /** Destructor. */
00556 SharedMemoryLookupTableLister::~SharedMemoryLookupTableLister()
00557 {
00558 }
00559
00560
00561 void
00562 SharedMemoryLookupTableLister::print_header()
00563 {
00564   cout << endl << cgreen << "FireVision Shared Memory Segments - Lookup Tables"
00565        << cnormal << endl
00566        << "========================================================================================" << endl
00567        << cdarkgray;
00568   printf ("%-23s %-10s %-10s %-10s %-9s %-9s %-9s\n",
00569           "LUT ID", "ShmID", "Semaphore", "Bytes", "Width", "Height", "State");
00570   cout << cnormal
00571        << "----------------------------------------------------------------------------------------" << endl;
00572 }
00573
00574
00575 void
00576 SharedMemoryLookupTableLister::print_footer()
00577 {
00578 }
00579
00580
00581 void
00582 SharedMemoryLookupTableLister::print_no_segments()
00583 {
00584   cout << "No FireVision shared memory segments containing lookup tables found" << endl;
00585 }
00586
00587
00588
00589
00590 void
00591 SharedMemoryLookupTableLister::print_no_orphaned_segments()
00592 {
00593   cout << "No orphaned FireVision shared memory segments containing lookup tables found" << endl;
00594 }
00595
00596 void
00597 SharedMemoryLookupTableLister::print_info(const SharedMemoryHeader *header,
00598                                           int shm_id, int semaphore,
00599                                           unsigned int mem_size,
00600                                           const void *memptr)
00601 {
00602
00603   SharedMemoryLookupTableHeader *h = (SharedMemoryLookupTableHeader *)header;
00604
00605   printf("%-23s %-10d %-10d %-10u %-9u %-9u %s%s\n",
00606          h->lut_id(), shm_id, semaphore, mem_size,
00607          h->width(), h->height(),
00608          (SharedMemory::is_swapable(shm_id) ? "S" : ""),
00609          (SharedMemory::is_destroyed(shm_id) ? "D" : "")
00610          );
00611 }