Example #1
0
void GrowBuffer(WriteBuffer* buf, int size)
{
    if (buf->len + size > buf->size)
    {
        int newsize = max(buf->size * 2, buf->len + size);
        if (buf->buffer != buf->prealloc)
            buf->buffer = MEM_REALLOC(buf->buffer, newsize);
        else
        {
            buf->buffer = MEM_ALLOC(newsize);
            memcpy(buf->buffer, buf->prealloc, sizeof(buf->prealloc));
        }
        buf->size = newsize;
    }
}
Example #2
0
Handle *dat1HandleLock( Handle *handle, int oper, int recurs, int rdonly,
                        int *result, int *status ){

/* Local Variables; */
   Handle *child;
   int ichild;
   int top_level;
   pthread_t *locker;
   pthread_t *rlocker;
   int i;
   int j;
   Handle *error_handle = NULL;
   int child_result;

/* initialise */
   *result = 0;

/* Check inherited status. */
   if( *status != SAI__OK ) return error_handle;

/* Validate the supplied Handle */
   if( !dat1ValidateHandle( "dat1HandleLock", handle, status ) ) return error_handle;

/* To avoid deadlocks, we only lock the Handle mutex for top level
   entries to this function. If "oper" is negative, negate it and set a
   flag indicating we do not need to lock the mutex. */
   if( oper < 0 ) {
      oper = -oper;
      top_level = 0;
   } else {
      top_level = 1;
   }

/* For top-level entries to this function, we need to ensure no other thread
   is modifying the details in the handle, so attempt to lock the handle's
   mutex. */
   if( top_level ) pthread_mutex_lock( &(handle->mutex) );

/* Return information about the current lock on the supplied Handle.
   ------------------------------------------------------------------ */
   if( oper == 1 ) {

/* Default: unlocked */

      if( handle->nwrite_lock ) {
         if( pthread_equal( handle->write_locker, pthread_self() )) {

/* Locked for writing by the current thread. */
            *result = 1;
         } else {

/* Locked for writing by another thread. */
            *result = 2;
         }

      } else if( handle->nread_lock ){

/* Locked for reading by one or more other threads (the current thread does
   not have a read lock on the Handle). */
         *result = 4;

/* Now check to see if the current thread has a read lock, changing the
   above result value if it does. */
         locker = handle->read_lockers;
         for( i = 0; i < handle->nread_lock;i++,locker++ ) {
            if( pthread_equal( *locker, pthread_self() )) {

/* Locked for reading by the current thread (other threads may also have
   a read lock on the Handle). */
               *result = 3;
               break;
            }
         }
      }

/* If required, check any child handles. If we already have a status of
   2, (the supplied handle is locked read-write by another thread), we do
   not need to check the children. */
      if( recurs && *result != 2 ){
         for( ichild = 0; ichild < handle->nchild; ichild++ ) {
            child = handle->children[ichild];
            if( child ) {

/* Get the lock status of the child. */
               (void) dat1HandleLock( child, -1, 1, rdonly, &child_result,
                                      status );

/* If it's 2, we can set the final result and exit immediately. */
               if( child_result == 2 ) {
                  *result = 2;
                  break;

/* Otherwise, ensure the child gives the same result as all the others,
   breaking out and returning the catch-all value if not. */
               } else if(  child_result != *result ) {
                  *result = 5;
                  break;
               }
            }
         }
      }





/* Lock the handle for use by the current thread.
   ------------------------------------------------------------------ */
   } else if( oper == 2 ) {

/* A read-only lock requested.... */
      if( rdonly ) {

/* If the current thread has a read-write lock on the Handle, demote it
   to a read-only lock and return 1 (success). In this case, we know
   there will be no other read-locks. Otherwise if any other thread has
   read-write lock, return zero (failure). */
         if( handle->nwrite_lock ) {
            if( pthread_equal( handle->write_locker, pthread_self() )) {

/* If we do not have an array in which to store read lock thread IDs,
   allocate one now with room for NTHREAD locks. It will be extended as
   needed. */
               if( !handle->read_lockers ) {
                  handle->read_lockers = MEM_CALLOC(NTHREAD,sizeof(pthread_t));
                  if( !handle->read_lockers ) {
                     *status = DAT__NOMEM;
                     emsRep( "", "Could not allocate memory for HDS "
                             "Handle read locks list.", status );
                  }
               }

/* If we now have an array, store the current thread in the first element. */
               if( handle->read_lockers ) {
                  handle->read_lockers[ 0 ] = pthread_self();
                  handle->nread_lock = 1;
                  handle->nwrite_lock = 0;
                  *result = 1;
               }
            }

/* If there is no read-write lock on the Handle, add the current thread
   to the list of threads that currently have a read-only lock, but only
   if it is not already there. */
         } else {

/* Set "result" to 1 if the current thread already has a read-only lock. */
            locker = handle->read_lockers;
            for( i = 0; i < handle->nread_lock;i++,locker++ ) {
               if( pthread_equal( *locker, pthread_self() )) {
                  *result = 1;
                  break;
               }
            }

/* If not, extend the read lock thread ID array if necessary, and append
   the current thread ID to the end. */
            if( *result == 0 ) {
               handle->nread_lock++;
               if( handle->maxreaders < handle->nread_lock ) {
                  handle->maxreaders += NTHREAD;
                  handle->read_lockers = MEM_REALLOC( handle->read_lockers,
                                                    handle->maxreaders*sizeof(pthread_t));
                  if( !handle->read_lockers ) {
                     *status = DAT__NOMEM;
                     emsRep( "", "Could not reallocate memory for HDS "
                             "Handle read locks list.", status );
                  }
               }

               if( handle->read_lockers ) {
                  handle->read_lockers[ handle->nread_lock - 1 ] = pthread_self();

/* Indicate the read-only lock was applied successfully. */
                  *result = 1;
               }
            }
         }

/* A read-write lock requested. */
      } else {

/* If there are currently no locks of any kind, apply the lock. */
         if( handle->nread_lock == 0 ) {
            if( handle->nwrite_lock == 0 ) {
               handle->write_locker = pthread_self();
               handle->nwrite_lock = 1;
               *result = 1;

/* If the current thread already has a read-write lock, indicate success. */
            } else if( pthread_equal( handle->write_locker, pthread_self() )) {
               *result = 1;
            }

/* If there is currently only one read-only lock, and it is owned by the
   current thread, then promote it to a read-write lock. */
         } else if( handle->nread_lock == 1 &&
                    pthread_equal( handle->read_lockers[0], pthread_self() )) {
            handle->nread_lock = 0;
            handle->write_locker = pthread_self();
            handle->nwrite_lock = 1;
            *result = 1;
         }
      }

/* If required, and if the above lock operation was successful, lock any
   child handles that can be locked. */
      if( *result ){
         if( recurs ){
            for( ichild = 0; ichild < handle->nchild; ichild++ ) {
               child = handle->children[ichild];
               if( child ) {
                  error_handle = dat1HandleLock( child, -2, 1, rdonly,
                                                 result, status );
                  if( error_handle ) break;
               }
            }
         }

/* If the lock operation failed, return a pointer to the Handle. */
      } else {
         error_handle = handle;
      }




/* Unlock the handle.
   ----------------- */
   } else if( oper == 3 ) {

/* Assume failure. */
      *result = 0;

/* If the current thread has a read-write lock, remove it. */
      if( handle->nwrite_lock ) {
         if( pthread_equal( handle->write_locker, pthread_self() )) {
            handle->nwrite_lock = 0;
            *result = 1;
         } else {
            *result = -1;
         }

/* Otherwise, if the current thread has a read-only lock, remove it. */
      } else {

/* Loop through all the threads that have read-only locks. */
         locker = handle->read_lockers;
         for( i = 0; i < handle->nread_lock; i++,locker++ ) {

/* If the current thread is found, shuffle any remaining threads down one
   slot to fill the gap left by removing the current thread from the list. */
            if( pthread_equal( *locker, pthread_self() )) {
               rlocker = locker + 1;
               for( j = i + 1; j < handle->nread_lock; j++,locker++ ) {
                  *locker = *(rlocker++);
               }

/* Reduce the number of read-only locks. */
               handle->nread_lock--;
               *result = 1;
               break;
            }
         }
      }

/* If required, and if the above unlock operation was successful, unlock any
   child handles that can be unlocked. */
      if( *result == 1 ){
         if( recurs ){
            for( ichild = 0; ichild < handle->nchild; ichild++ ) {
               child = handle->children[ichild];
               if( child ) {
                  error_handle = dat1HandleLock( child, -3, 1, 0,
                                                 result, status );
                  if( error_handle ) break;
               }
            }
         }

/* If the unlock operation failed, return a pointer to the Handle. */
      } else {
         error_handle = handle;
      }




/* Report an error for any other "oper" value. */
   } else if( *status == SAI__OK ) {
      *status = DAT__FATAL;
      emsRepf( " ", "dat1HandleLock: Unknown 'oper' value (%d) supplied - "
               "(internal HDS programming error).", status, oper );
   }

/* If this is a top-level entry, unlock the Handle's mutex so that other
   threads can access the values in the Handle. */
   if( top_level ) pthread_mutex_unlock( &(handle->mutex) );

/* Return the error handle. */
   return error_handle;
}
Example #3
0
static void
regular_test(struct mem_allocator* allocator)
{
    char dump[BUFSIZ];
    void* p = NULL;
    void* q[3] = {NULL, NULL, NULL};
    size_t i = 0;

    p = MEM_ALIGNED_ALLOC(allocator, 1024, ALIGNOF(char));
    NCHECK(p, NULL);
    CHECK(IS_ALIGNED((uintptr_t)p, ALIGNOF(char)), 1);
    MEM_FREE(allocator, p);

    q[0] = MEM_ALIGNED_ALLOC(allocator, 10, 8);
    q[1] = MEM_CALLOC(allocator, 1, 58);
    q[2] = MEM_ALLOC(allocator, 78);
    NCHECK(q[0], NULL);
    NCHECK(q[1], NULL);
    NCHECK(q[2], NULL);
    CHECK(IS_ALIGNED((uintptr_t)q[0], 8), 1);

    p = MEM_CALLOC(allocator, 2, 2);
    NCHECK(p, NULL);
    for(i = 0; i < 4; ++i)
        CHECK(((char*)p)[i], 0);
    for(i = 0; i < 4; ++i)
        ((char*)p)[i] = (char)i;

    MEM_DUMP(allocator, dump, BUFSIZ);
    printf("dump:\n%s\n", dump);
    MEM_DUMP(allocator, dump, 16);
    printf("truncated dump:\n%s\n", dump);
    MEM_DUMP(allocator, NULL, 0); /* may not crashed. */

    MEM_FREE(allocator, q[1]);

    p = MEM_REALLOC(allocator, p, 8);
    for(i = 0; i < 4; ++i)
        CHECK(((char*)p)[i], (char)i);
    for(i = 4; i < 8; ++i)
        ((char*)p)[i] = (char)i;

    MEM_FREE(allocator, q[2]);

    p = MEM_REALLOC(allocator, p, 5);
    for(i = 0; i < 5; ++i)
        CHECK(((char*)p)[i], (char)i);

    MEM_FREE(allocator, p);

    p = NULL;
    p = MEM_REALLOC(allocator, NULL, 16);
    NCHECK(p, NULL);
    p = MEM_REALLOC(allocator, p, 0);

    MEM_FREE(allocator, q[0]);

    CHECK(MEM_ALIGNED_ALLOC(allocator, 1024, 0), NULL);
    CHECK(MEM_ALIGNED_ALLOC(allocator, 1024, 3), NULL);
    CHECK(MEM_ALLOCATED_SIZE(allocator), 0);
}
Example #4
0
void video_draw_rect_rotated(TexHandle tex, uint layer,
							 const RectF* source, const RectF* dest, float rotation, Color tint) {
	assert(layer < bucket_count);
	assert(dest);

	assert(tex < textures.size);
	Texture* t = DARRAY_DATA_PTR(textures, Texture);
	assert(t[tex].active);
	uint fixed_scale = (uint)(t[tex].scale * (tex_mul+1.0f));
	uint texture_width = t[tex].width;
	uint texture_height = t[tex].height;

	int16 real_src_l = 0;
	int16 real_src_t = 0;
	int16 real_src_r = texture_width;
	int16 real_src_b = texture_height;

	if(source != NULL) {
		real_src_l = (int16)(source->left);
		real_src_t = (int16)(source->top);
		real_src_r = (int16)(source->right);
		real_src_b = (int16)(source->bottom);
	}

	// This is faster than comparing floats
	bool full_dest = (*((uint*)&dest->right) | *((uint*)&dest->bottom)) == 0U;
	RectF real_dest = *dest;

    int w = real_src_r - real_src_l;
    int h = real_src_b - real_src_t;

    if(full_dest) {
		float width = (float)w;
		float height = (float)h;
		real_dest.right = real_dest.left + width;
		real_dest.bottom = real_dest.top + height;
	}

    // Don't draw rect if it's not inside screen rect
    if(transform[layer] == NULL) {
        RectF screen = {0.0f, 0.0f, screen_widthf, screen_heightf};
        if(!rectf_rectf_collision(&screen, &real_dest))
            return;
    }

	assert(is_pow2((texture_width * fixed_scale) >> 15));
	assert(is_pow2((texture_height * fixed_scale) >> 15));

	uint wlog2 = _ilog2((texture_width * fixed_scale) >> 15);
	uint hlog2 = _ilog2((texture_height * fixed_scale) >> 15);

	real_src_l = ((real_src_l << 15) - 1) >> wlog2;
	real_src_t = ((real_src_t << 15) - 1) >> hlog2;
	real_src_r = ((real_src_r << 15) - 1) >> wlog2;
	real_src_b = ((real_src_b << 15) - 1) >> hlog2;

	TexturedRectDesc new_rect = {
		.tex = tex,
		.src_l = real_src_l,
		.src_t = real_src_t,
		.src_r = real_src_r,
		.src_b = real_src_b,
		.dest = real_dest,
		.tint = tint,
		.rotation = rotation
	};

    // Do something uglier instead of darray_append, saving a memcpy here is worth it
	//darray_append(&rect_buckets[layer], &new_rect);

    DArray* bucket = &rect_buckets[layer];
	if(!bucket->reserved)
		rect_buckets[layer] = darray_create(sizeof(TexturedRectDesc), 32);
	else if(bucket->reserved - bucket->size < 1) {
        bucket->reserved *= 2;
        bucket->data = MEM_REALLOC(bucket->data, bucket->item_size * bucket->reserved);
    }

    TexturedRectDesc* rects = DARRAY_DATA_PTR(*bucket, TexturedRectDesc);
    rects[bucket->size] = new_rect;
    bucket->size++;
}
Example #5
0
int
main(int argc, char** argv)
{
  char buf[BUFSIZ];
  struct font_glyph_desc desc;
  struct font_system* sys = NULL;
  struct font_rsrc* font = NULL;
  struct font_glyph* glyph = NULL;
  const char* path = NULL;
  unsigned char* buffer = NULL;
  size_t buffer_size = 0;
  int h = 0;
  int w = 0;
  int Bpp = 0;
  int i = 0;
  bool b = false;

  if(argc != 2) {
    printf("usage: %s FONT\n", argv[0]);
    goto error;
  }
  path = argv[1];

  CHECK(font_system_create( NULL, NULL ), BAD_ARG);
  CHECK(font_system_create(NULL, &sys), OK);

  CHECK(font_rsrc_create(NULL, NULL, NULL), BAD_ARG);
  CHECK(font_rsrc_create(sys, NULL, NULL), BAD_ARG);
  CHECK(font_rsrc_create(NULL, NULL, &font), BAD_ARG);
  CHECK(font_rsrc_create(sys, NULL, &font), OK);

  CHECK(font_rsrc_load(NULL, NULL), BAD_ARG);
  CHECK(font_rsrc_load(font, NULL), BAD_ARG);
  CHECK(font_rsrc_load(NULL, path), BAD_ARG);
  CHECK(font_rsrc_load(font, path), OK);

  CHECK(font_rsrc_is_scalable(NULL, NULL), BAD_ARG);
  CHECK(font_rsrc_is_scalable(font, NULL), BAD_ARG);
  CHECK(font_rsrc_is_scalable(NULL, &b), BAD_ARG);
  CHECK(font_rsrc_is_scalable(font, &b), OK);

  if(b) {
    CHECK(font_rsrc_set_size(NULL, 0, 0), BAD_ARG);
    CHECK(font_rsrc_set_size(font, 0, 0), BAD_ARG);
    CHECK(font_rsrc_set_size(NULL, 32, 0), BAD_ARG);
    CHECK(font_rsrc_set_size(font, 32, 0), BAD_ARG);
    CHECK(font_rsrc_set_size(NULL, 0, 64), BAD_ARG);
    CHECK(font_rsrc_set_size(font, 0, 64), BAD_ARG);
    CHECK(font_rsrc_set_size(NULL, 32, 64), BAD_ARG);
    CHECK(font_rsrc_set_size(font, 32, 64), OK);
    CHECK(font_rsrc_set_size(font, 16, 16), OK);
  }

  CHECK(font_rsrc_get_line_space(NULL, NULL), BAD_ARG);
  CHECK(font_rsrc_get_line_space(font, NULL), BAD_ARG);
  CHECK(font_rsrc_get_line_space(NULL, &i), BAD_ARG);
  CHECK(font_rsrc_get_line_space(font, &i), OK);

  CHECK(font_rsrc_get_glyph(NULL, L'a', NULL), BAD_ARG);
  CHECK(font_rsrc_get_glyph(font, L'a', NULL), BAD_ARG);
  CHECK(font_rsrc_get_glyph(NULL, L'a', &glyph), BAD_ARG);
  CHECK(font_rsrc_get_glyph(font, L'a', &glyph), OK);

  CHECK(font_glyph_get_desc(NULL, NULL), BAD_ARG);
  CHECK(font_glyph_get_desc(glyph, NULL), BAD_ARG);
  CHECK(font_glyph_get_desc(NULL, &desc), BAD_ARG);
  CHECK(font_glyph_get_desc(glyph, &desc), OK);
  CHECK(desc.character, L'a');

  CHECK(font_glyph_get_bitmap(NULL, true, NULL, NULL, NULL, NULL), BAD_ARG);
  CHECK(font_glyph_get_bitmap(glyph, true, NULL, NULL, NULL, NULL), OK);
  CHECK(font_glyph_get_bitmap(glyph, true, &w, NULL, NULL, NULL), OK);
  CHECK(font_glyph_get_bitmap(glyph, true, NULL, &h, NULL, NULL), OK);
  CHECK(font_glyph_get_bitmap(glyph, true, &w, &h, NULL, NULL), OK);
  CHECK(font_glyph_get_bitmap(glyph, true, NULL, NULL, &Bpp, NULL), OK);
  CHECK(font_glyph_get_bitmap(glyph, true, &w, NULL, &Bpp, NULL), OK);
  CHECK(font_glyph_get_bitmap(glyph, true, NULL, &h, &Bpp, NULL), OK);
  CHECK(font_glyph_get_bitmap(glyph, true, &w, &h, &Bpp, NULL), OK);
  NCHECK(w, 0);
  NCHECK(h, 0);
  NCHECK(Bpp, 0);

  buffer = MEM_CALLOC
    (&mem_default_allocator, (size_t)(w*h*Bpp), sizeof(unsigned char));
  NCHECK(buffer, NULL);
  buffer_size = (size_t)(w*h*Bpp) * sizeof(unsigned char);

  CHECK(font_glyph_get_bitmap(glyph, false, NULL, NULL, NULL, buffer), OK);
  CHECK(font_glyph_get_bitmap(glyph, false, &w, NULL, NULL, buffer), OK);
  CHECK(font_glyph_get_bitmap(glyph, false, NULL, &h, NULL, buffer), OK);
  CHECK(font_glyph_get_bitmap(glyph, false, &w, &h, NULL, buffer), OK);
  CHECK(font_glyph_get_bitmap(glyph, false, NULL, NULL, &Bpp, buffer), OK);
  CHECK(font_glyph_get_bitmap(glyph, false, &w, NULL, &Bpp, buffer), OK);
  CHECK(font_glyph_get_bitmap(glyph, false, NULL, &h, &Bpp, buffer), OK);
  CHECK(font_glyph_get_bitmap(glyph, false, &w, &h, &Bpp, buffer), OK);

  CHECK(font_glyph_ref_get(NULL), BAD_ARG);
  CHECK(font_glyph_ref_get(glyph), OK);
  CHECK(font_glyph_ref_put(NULL), BAD_ARG);
  CHECK(font_glyph_ref_put(glyph), OK);
  CHECK(font_glyph_ref_put(glyph), OK);

  b = true;
  for(i = 0; b && i < w*h*Bpp; ++i)
    b = ((int)buffer[i] == 0);
  CHECK(b, false);

  for(i = 32; i < 127; ++i) {
    size_t required_buffer_size = 0;
    CHECK(font_rsrc_get_glyph(font, (wchar_t)i, &glyph), OK);

    CHECK(font_glyph_get_bitmap(glyph, true, &w, &h, &Bpp, NULL), OK);
    required_buffer_size = (size_t)(w * h * Bpp) * sizeof(unsigned char);
    if(required_buffer_size > buffer_size) {
      buffer = MEM_REALLOC(&mem_default_allocator,buffer, required_buffer_size);
      NCHECK(buffer, NULL);
      buffer_size = required_buffer_size;
    }
    CHECK(font_glyph_get_bitmap(glyph, true, &w, &h, &Bpp, buffer), OK);
    NCHECK(snprintf(buf, BUFSIZ, "/tmp/%.3d.ppm", i - 32), BUFSIZ);
    CHECK(image_ppm_write(buf, w, h, Bpp, buffer), 0);
    CHECK(font_glyph_ref_put(glyph), OK);
  }
  MEM_FREE(&mem_default_allocator, buffer);

  CHECK(font_rsrc_ref_get(NULL), BAD_ARG);
  CHECK(font_rsrc_ref_get(font), OK);
  CHECK(font_rsrc_ref_put(NULL), BAD_ARG);
  CHECK(font_rsrc_ref_put(font), OK);
  CHECK(font_rsrc_ref_put(font), OK);

  CHECK(font_system_ref_get(NULL), BAD_ARG);
  CHECK(font_system_ref_get(sys), OK);
  CHECK(font_system_ref_put(NULL), BAD_ARG);
  CHECK(font_system_ref_put(sys), OK);
  CHECK(font_system_ref_put(sys), OK);

  CHECK(MEM_ALLOCATED_SIZE(&mem_default_allocator), 0);

  return 0;

error:
  return -1;
}