Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
G

Gerardo Orozco

@Gerardo Orozco
About
Posts
10
Topics
0
Shares
0
Groups
0
Followers
0
Following
0

Posts

Recent Best Controversial

  • I thought .NET was supposed to make things easier, if anything, than unmanaged code.
    G Gerardo Orozco

    +1 for this suggestion. Performance is much, much better than using the managed classes for memory mapped files. (I remember we clocked this being around 5x faster). We used this approach to store multimedia fingerprint data. Here is a small snippet of code showing how we initialized the memory mapped file using C++/CLI - The data is accessible through the _pData (UInt32*) member.

    Int32 StationHashStorage::Open() {
    msclr::lock lock(_syncRoot);
    if( _isOpen )
    return 0;
    String^ fileName = GetFullFileName();

    _szInBytes = ComputeFileSizeInBytes(fileName);
    String^ mapExtension = GetFileExtension();
    String^ mapName = String::Format("{0}{1}_{2}", _stationId, _date.ToString("yyyyMMdd"), mapExtension);

    marshal_context context;
    LPCTSTR pMapName = context.marshal_as(mapName);

    {
    msclr::lock lock( _openLock );
    // Try to see if another storage instance has requested the same memory-mapped file and share it
    _hMapping = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, pMapName);
    if( !_hMapping ) {
    // This is the first instance acquiring the file
    LPCTSTR pFileName = context.marshal_as(fileName);
    // Try to open the existing file, or create new one if not exists
    _hFile = CreateFile(pFileName,
    GENERIC_READ | GENERIC_WRITE,
    FILE_SHARE_READ,
    NULL,
    OPEN_ALWAYS,
    FILE_ATTRIBUTE_NORMAL,
    NULL);
    if( !_hFile )
    throw gcnew IOException(String::Format(Strings::CreateFileFailed, GetLastError(), _stationId));
    _hMapping = CreateFileMapping(_hFile,
    NULL,
    PAGE_READWRITE | SEC_COMMIT,
    0,
    _szInBytes,
    pMapName);
    if( !_hMapping )
    throw gcnew IOException(String::Format(Strings::CreateMappingFailed, GetLastError(), _stationId));
    _usingSharedFile = false;
    } else {
    _usingSharedFile = true;
    }
    }

    _pData = (UInt32*)::MapViewOfFile(_hMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);

    if( !_pData )
    throw gcnew IOE

    The Lounge csharp database sql-server com sysadmin

  • I just used a goto!
    G Gerardo Orozco

    IMHO goto's can really offer a very clean solution when coding in C and you want to implement a sort of manual "finally" or "rollback" logic. Here is an example of code that is rolling back some state if something goes wrong. I like it because the intent is clear (there is a single label we are jumping to), I'm avoiding repeating cleanup code and I'm not introducing additional indentation levels that would be necessary with a structured approach - if we want to avoid multiple exit points.

    static STATUS Android_PrepareAudioBuffers(void) {
    STATUS errCode;
    SLresult result;
    _slBufferQueueItf = NULL;
    /* Obtain interface to the AudioBufferQueue object */
    result = (*_slRecorderInstance)->GetInterface(_slRecorderInstance, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
    &_slBufferQueueItf);

    if( result != SL_RESULT_SUCCESS ) {
    LOGE("%s - Error calling _slRecorderInstance->GetInterface(SL_IID_ANDROIDSIMPLEBUFFERQUEUE)", __func__);
    errCode = S_ERR_OPENSLES_GET_INTERFACE;
    goto fail_point;
    }

    /* Register buffer-ready call-back */
    result = (*_slBufferQueueItf)->RegisterCallback(_slBufferQueueItf, Android_RecordCallback, NULL);
    if( result != SL_RESULT_SUCCESS ) {
    LOGE("%s - Error calling _slBufferQueueItf->RegisterCallback()", __func__);
    errCode = S_ERR_OPENSLES_REGISTER_CALLBACK;
    goto fail_point;
    }

    /* Specify an event mask to ensure the callback fires only when an audio buffer is full */
    (*_slRecorderItf)->SetCallbackEventsMask(_slRecorderItf, SL_RECORDEVENT_BUFFER_FULL);

    _activeBuffIdx = 0;
    /* Initialize buffer queue by enqueing all buffers at once.
    When a buffer is filled, it is dequeued and the registered call-back is called
    The buffer should be re-enqueued when processed to implement circular-buffer-list
    functionality */

    int i;
    for( i = 0; i < RECORD_BUFFER_COUNT; i++ ) {
    result = (*_slBufferQueueItf)->Enqueue(_slBufferQueueItf, _buffers[i], _buffSz);
    if( result != SL_RESULT_SUCCESS ) {
    LOGE("%s - Error calling_slBufferQueueItf->Enqueue()", __func__);
    errCode = S_ERR_OPENSLES_ENQUEUE_BUFF;
    goto fail_point;
    }
    }
    return S_OK;
    fail_point:
    // rollback state
    if( _slBufferQueueItf ) {
    (*_slBufferQueueItf)->RegisterCallback(_slBufferQueueItf, NULL, NULL);
    (*_slBufferQueueItf)->Clear(_slBufferQueueItf);
    _slBufferQueueItf = NULL;
    }
    return errCode;
    }

    The Lounge csharp com

  • Yet another rant / pet peeve / frustration
    G Gerardo Orozco

    Don't take it personal, they have "short-circuit evaluation" turned-on by default ;)

    The Lounge question docker performance

  • High performance c#
    G Gerardo Orozco

    Indeed, many of today's optimization techniques revolve around hitting the caches as much as possible. The amount of cycles lost when performing a main memory read are mind boggling. :omg:

    The Lounge csharp c++ performance visual-studio linq

  • Some thoughts on the .net CLR/CLI
    G Gerardo Orozco

    LOL! I couldn't agree more. In my mind I think they should have gone all the way with 100% automated reference counting during reference assignment (a-la Visual Basic), with a lightweight garbage collector relegated to detecting and breaking circular-references (something Visual Basic couldn't do) and of course, compacting memory. This would have offered automatic, true deterministic destruction, while preventing fragmentation. But most importantly, it would have avoided the dreaded Dispose pattern (alongside with the related Finalizer travesty) entirely. Somewhere I remember reading they avoided this route mainly for performance reasons, what a costly decision in retrospective.

    The Lounge csharp c++ delphi dotnet sysadmin

  • Some thoughts on the .net CLR/CLI
    G Gerardo Orozco

    Hi! Let me share with you the techniques we have used to go around some of the drawbacks you describe. Our solution is consuming a LARGE amount of UDP traffic (MPEG2 streams) - over 200Mbps of data. It is also performing some heavy DSP processing and it taxes the garbage collector heavily. Being UDP and with no retransmission protocol available - we are very sensitive to reading the data on time if we want to keep the quality of the video streams high. Reading the UDP traffic with managed code was a disaster. Basically, we are taking advantage of the fact that an unmanaged thread is NOT suspended during garbage collection. 1. We used C++/CLI to write the multicast UDP reader code inside a non-managed class. We ensure that the CLR support is disabled for the .cpp file implementing the code that we don't want to be interrupted during garbage collection. This makes sure that the code is compiled to native code, otherwise it may get compiled to IL code and the unmanaged thread may be blocked once it transitions to IL space. Even if using the unmanaged pragma, the compiler creates managed thunks around the unmanaged code and we want to avoid IL completely for this generated code. The unmanaged thread that is reading the UDP traffic (using RIO for higher performance) runs inside this class. Note that unfortunately we can't take advantage of the .Net framework in this class, so we rely on Boost. 2. We keep the unmanaged code as simple as possible, basically we loop reading UDP packets and enqueue them. However, we make sure that we use a lockless queue for this purpose (we use a Boost lockless queue). This is vital because there will be a managed thread consuming the queue, bridging the data onto the managed world. This consumer thread will be suspendend during GC activity and we don't want the thread to be suspended while holding a lock for the queue (otherwise the unmanaged thread may block contending for the lock). Another plus is that using a lockless queue, we become immune to thread priority inversion, so we can boost the producer thread priority to the highest level possible. 3. Using C++/CLI we produce a .net friendly class. This class owns and instantiates the unmanaged class, and also implements the managed queue consumer thread. (It can seamlessly consume the Boost lockless queue and expose the unmanaged memory (the udp packets) in a managed friendly way. Now, no matter if the managed world is suspended, the unmanaged thread will keep filling the lockless que

    The Lounge csharp c++ delphi dotnet sysadmin

  • Why compilers aren't magic
    G Gerardo Orozco

    LOL :laugh: Joking aside, it is reported that Dr. John von Neumann actually frowned upon at the idea of an assembler!

    Quote:

    John von Neumann, when he first heard about FORTRAN in 1954, was unimpressed and asked "why would you want more than machine language?" One of von Neumann's students at Princeton recalled that graduate students were being used to hand assemble programs into binary for their early machine. This student took time out to build an assembler, but when von Neumann found out about it he was very angry, saying that it was a waste of a valuable scientific computing instrument to use it to do clerical work.

    Source: Computing at Columbia Timeline[^] Gerardo

    The Lounge com ai-coding help question announcement

  • Some advice needed...
    G Gerardo Orozco

    I understand your feelings. I have a developer friend who felt more or less the same as you describe - he was IMHO the smartest person around his work circle (a government financial institution), and was actually treated like a rock star by his peers. He really SHINED, but felt unsatisfied and was looking for a much bigger intellectual challenge. He actually managed to enter a top-tier software company, and the frustration went the other way; now he was surrounded by extremely smart people that often offered better solutions, or could program much faster than he could; the bar got so high that suddenly he had become just an average developer. He tries to stay positive and humble, as he is now in a position where he is learning and pushing himself more; he also misses - A LOT - his old job ;) I guess that what I'm somehow trying to express is that frustration can go both ways and as much as everything in life, job satisfaction is a delicate act of balance. I know - easier said than done. I sincerely hope brighter days lay ahead for you! =)

    The Lounge learning css question workspace

  • Nostalgia in Programming
    G Gerardo Orozco

    Also related to very early days in Web programming. I remember we had a Sun Web Server that had to interact with some legacy system and we lacked connectivity libraries to it; however there was a command line tool that could process simple queries and dump them to the screen. We used a CGI C executable that piped and redirected the screen output of the command line tool. We had to parse the screen-based report to extract the data fields, but eventually managed to provide exactly what the customer was asking for. :cool:

    The Lounge sysadmin question

  • Why Android development sucks today
    G Gerardo Orozco

    We have been using Xamarin for about 7 months now. For me it puts Android development on a different perspective. There's a Starter (free) version to try, it might change your opinion! :-D

    The Lounge html android com hardware testing
  • Login

  • Don't have an account? Register

  • Login or register to search.
  • First post
    Last post
0
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups