Ejemplo n.º 1
0
EAPI Eina_Stringshare *
eina_stringshare_add_length(const char *str, unsigned int slen)
{
   if (!str)
     return NULL;
   else if (slen == 0)
     {
        eina_share_common_population_add(stringshare_share, slen);

        return "";
     }
   else if (slen == 1)
     {
        eina_share_common_population_add(stringshare_share, slen);

        return (Eina_Stringshare *) _eina_stringshare_single + ((*str) << 1);
     }
   else if (slen < 4)
     {
        const char *s;

        eina_share_common_population_add(stringshare_share, slen);
        eina_spinlock_take(&_mutex_small);
        s = _eina_stringshare_small_add(str, slen);
        eina_spinlock_release(&_mutex_small);

        return s;
     }

   return eina_share_common_add_length(stringshare_share, str, slen *
                                       sizeof(char), sizeof(char));
}
Ejemplo n.º 2
0
static void
_eio_pool_free(Eio_Alloc_Pool *pool, void *data)
{
   if (pool->count >= EIO_PROGRESS_LIMIT)
     {
        eina_spinlock_take(&memory_pool_lock);
        memory_pool_usage -= pool->mem_size;
        eina_spinlock_release(&memory_pool_lock);
        free(data);

        if (memory_pool_limit > 0 &&
            memory_pool_usage < memory_pool_limit)
          {
             eina_lock_take(&(memory_pool_mutex));
             if (memory_pool_suspended)
               eina_condition_broadcast(&(memory_pool_cond));
             eina_lock_release(&(memory_pool_mutex));
          }
     }
   else
     {
        eina_lock_take(&(pool->lock));
        eina_trash_push(&pool->trash, data);
        pool->count++;
        eina_lock_release(&(pool->lock));
     }
}
Ejemplo n.º 3
0
EAPI void
eina_evlog(const char *event, void *obj, double srctime, const char *detail)
{
   Eina_Evlog_Item *item;
   int size;
   char *strings;
   double now = get_time();
   unsigned short detail_offset = 0;
   unsigned short event_size;

   eina_spinlock_take(&_evlog_lock);
   if (!_evlog_go)
     {
        eina_spinlock_release(&_evlog_lock);
        return;
     }
   size = sizeof(Eina_Evlog_Item);
   event_size = strlen(event) + 1;
   size += event_size;
   if (detail)
     {
        detail_offset = size;
        size += strlen(detail) + 1;
     }
   size = sizeof(double) * ((size + sizeof(double) - 1) / sizeof(double));

   strings = push_buf(buf, size);
   item = (Eina_Evlog_Item *)strings;
   item->tim = now;
   item->srctim = srctime;
   item->thread = (unsigned long long)pthread_self();
   item->obj = (unsigned long long)obj;
   item->event_offset = sizeof(Eina_Evlog_Item);
   item->detail_offset = detail_offset;
   item->event_next = size;

   strcpy(strings + sizeof(Eina_Evlog_Item), event);
   if (detail_offset > 0) strcpy(strings + detail_offset, detail);

   eina_spinlock_release(&_evlog_lock);
}
Ejemplo n.º 4
0
EAPI void
eina_evlog_stop(void)
{
   eina_spinlock_take(&_evlog_lock);
   _evlog_go--;
   if (_evlog_go == 0)
     {
        free_buf(&(buffers[0]));
        free_buf(&(buffers[1]));
     }
   eina_spinlock_release(&_evlog_lock);
}
Ejemplo n.º 5
0
EAPI void
eina_evlog_start(void)
{
   eina_spinlock_take(&_evlog_lock);
   _evlog_go++;
   if (_evlog_go == 1)
     {
        // alloc 2 buffers for spinning around in
        alloc_buf(&(buffers[0]), EVLOG_BUF_SIZE);
        alloc_buf(&(buffers[1]), EVLOG_BUF_SIZE);
     }
   eina_spinlock_release(&_evlog_lock);
}
Ejemplo n.º 6
0
EAPI Eina_Stringshare *
eina_stringshare_ref(Eina_Stringshare *str)
{
   int slen;

   if (!str)
     return NULL;

   /* special cases */
   if      (str[0] == '\0')
     slen = 0;
   else if (str[1] == '\0')
     slen = 1;
   else if (str[2] == '\0')
     slen = 2;
   else if (str[3] == '\0')
     slen = 3;
   else
     slen = 3 + (int)strlen(str + 3);

   if (slen < 2)
     {
        eina_share_common_population_add(stringshare_share, slen);

        return str;
     }
   else if (slen < 4)
     {
        const char *s;

        eina_share_common_population_add(stringshare_share, slen);
        eina_spinlock_take(&_mutex_small);
        s = _eina_stringshare_small_add(str, slen);
        eina_spinlock_release(&_mutex_small);

        return s;
     }

   return eina_share_common_ref(stringshare_share, str);
}
Ejemplo n.º 7
0
static void *
_eio_pool_malloc(Eio_Alloc_Pool *pool)
{
   void *result = NULL;

   if (pool->count)
     {
        eina_lock_take(&(pool->lock));
        result = eina_trash_pop(&pool->trash);
        if (result) pool->count--;
        eina_lock_release(&(pool->lock));
     }

   if (!result)
     {
        result = malloc(pool->mem_size);
        eina_spinlock_take(&memory_pool_lock);
        if (result) memory_pool_usage += pool->mem_size;
        eina_spinlock_release(&memory_pool_lock);
     }
   return result;
}
Ejemplo n.º 8
0
EAPI void
eina_stringshare_del(Eina_Stringshare *str)
{
   int slen;

   if (!str)
     return;

   /* special cases */
   if (str[0] == '\0')
     slen = 0;
   else if (str[1] == '\0')
     slen = 1;
   else if (str[2] == '\0')
     slen = 2;
   else if (str[3] == '\0')
     slen = 3;
   else
     slen = 4;  /* handled later */

   if (slen < 2)
     {
        eina_share_common_population_del(stringshare_share, slen);

        return;
     }
   else if (slen < 4)
     {
        eina_share_common_population_del(stringshare_share, slen);
        eina_spinlock_take(&_mutex_small);
        _eina_stringshare_small_del(str, slen);
        eina_spinlock_release(&_mutex_small);

        return;
     }

   if (!eina_share_common_del(stringshare_share, str))
     CRI("EEEK trying to del non-shared stringshare \"%s\"", str);
}
Ejemplo n.º 9
0
EAPI Eina_Evlog_Buf *
eina_evlog_steal(void)
{
   Eina_Evlog_Buf *stolen = NULL;

   eina_spinlock_take(&_evlog_lock);
   if (buf == &(buffers[0]))
     {
        buf = &(buffers[1]);
        buf->top = 0;
        buf->overflow = 0;
        stolen = &(buffers[0]);
     }
   else
     {
        buf = &(buffers[0]);
        buf->top = 0;
        buf->overflow = 0;
        stolen = &(buffers[1]);
     }
   eina_spinlock_release(&_evlog_lock);
   return stolen;
}
Ejemplo n.º 10
0
// remove a thread id from our tracking array - simply find and shuffle all
// later elements down. this array should be small almsot all the time and
// shouldn't bew changing THAT often for this to matter
void
_eina_debug_thread_del(void *th)
{
   pthread_t *pth = th;
   int i;
   // take a thread tracking lock
   eina_spinlock_take(&_eina_debug_thread_lock);
   // find the thread id to remove
   for (i = 0; i < _eina_debug_thread_active_num; i++)
     {
        if (_eina_debug_thread_active[i] == *pth)
          {
             // found it - now shuffle down all further thread id's in array
             for (; i < (_eina_debug_thread_active_num - 1); i++)
               _eina_debug_thread_active[i] = _eina_debug_thread_active[i + 1];
             // reduce our counter and get out of loop
             _eina_debug_thread_active_num--;
             break;
          }
     }
   // release lock cleanly
   eina_spinlock_release(&_eina_debug_thread_lock);
}
Ejemplo n.º 11
0
// add a thread id to our tracking array - very simple. add to end, and
// if array to small, reallocate it to be bigger by 16 slots AND double that
// size (so grows should slow down FAST). we will never shrink this array
void
_eina_debug_thread_add(void *th)
{
   pthread_t *pth = th;
   // take thread tracking lock
   eina_spinlock_take(&_eina_debug_thread_lock);
   // if we don't have enough space to store thread id's - make some more
   if (_thread_active_size < (_eina_debug_thread_active_num + 1))
     {
        pthread_t *threads = realloc
          (_eina_debug_thread_active,
           ((_eina_debug_thread_active_num + 16) * 2) * sizeof(pthread_t *));
        if (threads)
          {
             _eina_debug_thread_active = threads;
             _thread_active_size = (_eina_debug_thread_active_num + 16) * 2;
          }
     }
   // add new thread id to the end
   _eina_debug_thread_active[_eina_debug_thread_active_num] = *pth;
   _eina_debug_thread_active_num++;
   // release our lock cleanly
   eina_spinlock_release(&_eina_debug_thread_lock);
}
Ejemplo n.º 12
0
static inline void
_config_unlock(Email_Config *cfg)
{
    eina_spinlock_release(&cfg->lock);
}
Ejemplo n.º 13
0
// do a "fast lookup" of a filename to a file path for debug output. this
// relies on caching to avoid system calls and assumes that once we know
// the full path of a given filename, we can know its full path reliably.
// if we can't we'd be in trouble anyway as the filename and path lookup
// failure is due maybe to a deleted file or renamed file and then we are
// going to have a bad day either way.
const char *
_eina_debug_file_get(const char *fname)
{
   char buf[4096];
   const char *file;
   static const char **path = NULL;
   static char *pathstrs = NULL;

   // no filename provided
   if ((!fname) || (!fname[0])) return NULL;
   // it's a full path so return as-is
   if (fname[0] == '/') return fname;
   // first look in cache for filename -> full path lookup and if
   // there, return that (yes - assuming filesystem paths doesn't change
   // which is unlikely as they were set up at star most likely)
   eina_spinlock_take(&_eina_debug_lock);
   file = _eina_debug_file_lookup(fname);
   eina_spinlock_release(&_eina_debug_lock);
   if (file) return file;

   // store PATH permanently - yes. if it changes runtime it will break.
   // for speed reasons we need to assume it won't change. store path broken
   // down into an array of ptrs to strings with NULL ptr at the end. this
   // will only execute once as an "init" for a breoken up path so it should
   // not matter speed-wise
   eina_spinlock_take(&_eina_debug_lock);
   if (!path)
     {
        unsigned int n;
        char *p1, *p2;
        const char *p;
        const char *pathstr = getenv("PATH");

        if (!pathstr)
          {
             eina_spinlock_release(&_eina_debug_lock);
             return NULL;
          }
        // dup the entire env as we will rpelace : with 0 bytes to break str
        pathstrs = _eina_debug_chunk_strdup(pathstr);
        for (n = 0, p = pathstr; *p;)
          {
             n++;
             p = strchr(p, ':');
             if (!p) break;
             p++;
          }
        path = _eina_debug_chunk_push(sizeof(const char *) * (n + 1));
        for (n = 0, p1 = pathstrs; *p1; n++)
          {
             path[n] = p1;
             p2 = strchr(p1, ':');
             if (!p2) break;
             *p2 = 0;
             p1 = p2 + 1;
          }
        path[n] = NULL;
     }
   eina_spinlock_release(&_eina_debug_lock);

   // a relative path - resolve with realpath. due to the cache store above
   // we shouldn't have to do this very often
   if ((!strncmp(fname, "./", 2)) || (!strncmp(fname, "../", 3)))
     { // relative path
        if (realpath(fname, buf)) file = buf;
        else file = NULL;
     }
   // search in $PATH for the file then - this should also be very rare as
   // we will store and cache results permanently
   else if (path)
     {
        struct stat st;
        unsigned int n;

        for (n = 0; path[n]; n++)
          {
             snprintf(buf, sizeof(buf), "%s/%s", path[n], fname);
             if (stat(buf, &st) == 0)
               {
                  file = buf;
                  break;
               }
          }
     }
   // if it's found - store it in cache for later
   if (file)
     {
        eina_spinlock_take(&_eina_debug_lock);
        file = _eina_debug_file_store(fname, file);
        eina_spinlock_release(&_eina_debug_lock);
     }
   return file;
}