예제 #1
0
/*
 * heap_ptr_t paralloc(size_t amt)
 *    @param amt : the amount of memory to allocate
 *    @returns on success : an offset (relative to the global `heaploc` defined
 *                          in `paralloc.h`)
 *    @return on error : -1 (and set errno to the appropriate value).
 *
 *    Allocates the requested amount of memory from the shared memory segment.
 */
heap_ptr_t paralloc(size_t amt) {
    if( amt <= 0) {
        //bad argument
        errno = EINVAL;
        return -1;
    }
    pid_t pid = getpid();
    int arena = pid % NUM_ARENAS;

    //BEGIN CRITICAL SECTION
    semaphore(wait_mutex[arena]);

    int offset = 0;
    linked_list* list = arenas[arena];
    list_node* current = list->head;
    list_node* prev = 0;

    //first-fit algorithm
    while( current) {
        int freesize = current->start - offset;
        if( freesize >= amt) {
            //we found a fit, need to make a node
            list_node* add = malloc( sizeof( list_node));
            add->start = offset;
            add->end = offset + amt;
            add->next = 0;

            //add node to list
            listAdd( list, add, prev);

            semaphore( signal_mutex[arena]);
            return offset;
        }
        offset = current->end;
        prev = current;
        current = current->next;
    }

    if( list->end - offset >= amt) {
        list_node* add = malloc( sizeof( list_node));
        add->start = offset;
        add->end = offset + amt;
        add->next = 0;
        listAdd( list, add, prev);

        semaphore( signal_mutex[arena]);
        return offset;
    }

    semaphore(signal_mutex[arena]);
    //END CRITICAL SECTION

    //out of memory error
    errno = ENOMEM;
    return -1;
}
예제 #2
0
파일: switchpp.cpp 프로젝트: r2labs/uncleos
lswitch::lswitch(memory_address_t lswitch_base, memory_address_t lswitch_pin,
                 semaphore *sem, utimer_t timer_id, subtimer_t timer_subtimer,
                 uint32_t switch_interrupt, uint32_t interrupt_mask, bool start) {

    base = lswitch_base;
    pin = lswitch_pin;

    ctlsys::enable_periph(base);
    GPIOPinTypeGPIOInput(base, pin);
    GPIODirModeSet(base, pin, GPIO_DIR_MODE_IN);

    if ((base == GPIO_PORTF_BASE) && (pin & GPIO_PIN_0)) {
        HWREG(base + GPIO_O_LOCK) = GPIO_LOCK_KEY;
        HWREG(base + GPIO_O_CR) = 0x01;
        HWREG(base + GPIO_O_LOCK) = 0;

        GPIOPadConfigSet(base, pin, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
    }

    /* other solution: timer scoreboard */
    this->tim = timer(timer_id, timer_subtimer, TIMER_CFG_ONE_SHOT, SysCtlClockGet() / 50,
                      ctlsys::timer_timeout_from_subtimer(timer_subtimer));

    GPIOIntTypeSet(base, pin, switch_interrupt);
    IntEnable(interrupt_mask);

    this->sem = sem;
    *(this->sem) = semaphore();

    if (start) {
        this->start();
    }
}
예제 #3
0
inline bool shm_named_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
{
   if(abs_time == boost::posix_time::pos_infin){
      this->wait();
      return true;
   }
   return semaphore()->timed_wait(abs_time);
}
예제 #4
0
/*
 * 	execute Sys Calls
 */
bool SystemCallExec::execute(int swiNumber, int params[])  {
    bool switchTask = false;

	switch (swiNumber) {

    	case WRITE:
    		_kernel->write(params);
    		break;
    	case WRITE_RESPONSE:
    		_kernel->writeResponse(params);
    		break;
    	case SUSPEND:

    		_taskmanager->getActiveTask()->status = Blocked;
            switchTask = true;
    		break;
        case NOTIFY:
            notify(params[2], params[3]);
            break;
        case WAIT:
            wait(_taskmanager->getActiveTask()->id, params[2], params[3]);
            switchTask = true;
            break;
        case SEMAPHORE:
            switchTask = semaphore(params[2], params[3], params[4]);
            
            break;
        case EXIT:
         	_taskmanager->kill(params[1]);
         	// context switch
         	switchTask = true;
         	break;
        	
        case KILL:
            break;
        case EXEC:
            if (params[2] == 0) {
                // Start Test-Task to toggle LED's
                Task* task = _taskmanager->create("test", false);
                TestBytes tb;
                _kernel->getLoader()->loadTaskCode(task, tb.getCodeBytes());
            } else if (params[2] == 1) {
                // Start Test-Task to toggle LED1
                Task* taskLed1 = _taskmanager->create("testLed1", false);
                TestLed1Bytes tbLed1;
                _kernel->getLoader()->loadTaskCode(taskLed1, tbLed1.getCodeBytes());
            }
            break;
        case FORK:
            break;
        case YIELD:
        	// just context switch
        	switchTask = true;
        	break;
    }
    return switchTask;
}
예제 #5
0
TEST(BasicThreadPoolTest, StopThreadPoolTest) {
  YPlatform::Semaphore semaphore(0, 1);
  ContainedThreadPool<2, 10> thread_pool;

  ASSERT_TRUE(thread_pool.Start());
  ASSERT_TRUE(thread_pool.EnqueueRun(ReleaseSemaphoreRoutine, &semaphore));
  ASSERT_TRUE(semaphore.Wait(50));
  ASSERT_TRUE(thread_pool.Stop(50));
}
예제 #6
0
/*
 * int parfree(heap_ptr_t offset)
 *
 *    @param offset : the offset pointing to the memory you want to free (as
 *                    returned by paralloc)
 *    @returns on success : 0
 *    @returns on error : -1
 *
 *    Frees the memory.
 */
int parfree(heap_ptr_t offset) {
    if( offset < 0 || offset >= HEAPSIZE) {
        //bad argument
        errno = EINVAL;
        return -1;
    }
    pid_t pid = getpid();
    int arena = pid % NUM_ARENAS;

    //BEGIN CRITICAL SECTION
    semaphore(wait_mutex[arena]);

    linked_list* list = arenas[arena];
    list_node* current = list->head;
    list_node* prev = 0;
    //first-fit algorithm
    while( current) {
        if( current->start == offset) {
            //this is the block to be freed, remove from linked list
            listRemove( list, current, prev);
            free(current);

            //because the list only keeps track of allocated blocks,
            //this algorithm automatically coalesces.

            semaphore( signal_mutex[arena]);
            return 0;
        }
        if( current->start > offset) {
            //this offset has not been allocated, this is bad!
            break;
        }
        prev = current;
        current = current->next;
    }

    semaphore(signal_mutex[arena]);
    //END CRITICAL SECTION

    errno = EINVAL;
    return -1;
}
예제 #7
0
TEST(BasicThreadPoolTest, StartThreadPoolTest) {
  volatile uint32_t num = 0;
  YPlatform::Semaphore semaphore(0, 1);
  IncrementArg arg_data = { &num };
  ContainedThreadPool<2, 10> thread_pool;

  ASSERT_TRUE(thread_pool.Start());
  ASSERT_TRUE(thread_pool.EnqueueRun(IncrementRoutine, &arg_data));
  ASSERT_TRUE(thread_pool.EnqueueRun(ReleaseSemaphoreRoutine, &semaphore));
  ASSERT_TRUE(semaphore.Wait(50));
  EXPECT_EQ(1, num);
}
예제 #8
0
void SemaphoreTest::testSemaphore()
{
	// Create a semaphore with 2 permits
	syscommon::Semaphore semaphore( 2 );

	// Create 3 runnables/threads to ask for permits
	SemaphoreRunnable runnableOne( &semaphore );
	SemaphoreRunnable runnableTwo( &semaphore );
	SemaphoreRunnable runnableThree( &semaphore );

	syscommon::Thread threadOne( &runnableOne );
	syscommon::Thread threadTwo( &runnableTwo );
	syscommon::Thread threadThree( &runnableThree );

	// Start the threads, they will block until we signal the acquire event on them
	threadOne.start();
	threadTwo.start();
	threadThree.start();

	// Have two runnables acquire the two available permits
	runnableOne.signalAcquire();
	runnableOne.waitForAcquired( NATIVE_INFINITE_WAIT );
	runnableTwo.signalAcquire();
	runnableTwo.waitForAcquired( NATIVE_INFINITE_WAIT );

	// Both runnables should have the permits
	CPPUNIT_ASSERT( runnableOne.isHoldingPermit() );
	CPPUNIT_ASSERT( runnableTwo.isHoldingPermit() );

#ifdef _WIN32
	// Have another runnable attempt to acquire the permit, it should timeout as both permits are
	// taken
	runnableThree.signalAcquire();
	syscommon::WaitResult blockedAcquire = runnableThree.waitForAcquired( 100L );
	CPPUNIT_ASSERT( blockedAcquire == syscommon::WR_TIMEOUT );
	CPPUNIT_ASSERT( !runnableThree.isHoldingPermit() );
#else
	runnableThree.signalAcquire();
#endif

	// Have one of the original runnables release its permit, the waiting runnable should wake up
	// and acquire the released permit
	runnableOne.signalRelease();
	runnableThree.waitForAcquired( NATIVE_INFINITE_WAIT );
	CPPUNIT_ASSERT( runnableThree.isHoldingPermit() );

	runnableTwo.signalRelease();
	runnableThree.signalRelease();

	threadOne.join();
	threadTwo.join();
	threadThree.join();
}
vk::Move<vk::VkSemaphore> createAndImportSemaphore (const vk::DeviceInterface&						vkd,
													const vk::VkDevice								device,
													vk::VkExternalSemaphoreHandleTypeFlagBitsKHR	externalType,
													NativeHandle&									handle,
													vk::VkSemaphoreImportFlagsKHR					flags)
{
	vk::Move<vk::VkSemaphore>	semaphore	(createSemaphore(vkd, device));

	importSemaphore(vkd, device, *semaphore, externalType, handle, flags);

	return semaphore;
}
예제 #10
0
int
sc_main( int, char*[] )
{
    mod_a a( "a" );
    mod_b b( "b" );
    sc_semaphore semaphore( "semaphore", 1 );

    a.semaphore( semaphore );
    b.semaphore( semaphore );

    sc_start( 40, SC_NS );

    return 0;
}
void ray_tracing::Continuous_performer::continuous_perform(std::vector<std::future<void>>& tasks)
{
    Semaphore semaphore(WORKERS_NUM);

    std::vector<std::thread> threads;

    for(std::future<void>& future : tasks)
    {
        semaphore.decrease();
        threads.emplace_back(helper, std::ref(future), std::ref(semaphore));
    }

    std::for_each(threads.begin(), threads.end(), [](std::thread& thread) {thread.join();});
}
예제 #12
0
	VulkanResult<VkSemaphore> Device::CreateSemaphore( VkSemaphoreCreateFlags flags ) {
		VkSemaphoreCreateInfo	createInfo;
		VkSemaphore				semaphore( VK_NULL_HANDLE );

		createInfo.sType	= VkStructureType::VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
		createInfo.pNext	= nullptr;
		createInfo.flags	= flags;

		const auto result( vkCreateSemaphore( _device.Get(), &createInfo, _allocator, &semaphore ) );
		if( result < VkResult::VK_SUCCESS ) {
			return { result };
		}

		return Vulkan::UniquePointer<VkSemaphore>( semaphore, { _device.Get(), _allocator } );
	}
예제 #13
0
TEST(BasicThreadPoolTest, EnqueueMultiple) {
  volatile uint32_t num = 0;
  YPlatform::Semaphore semaphore(0, 1);
  IncrementArg arg_data = { &num };
  ContainedThreadPool<2, 20> thread_pool;

  thread_pool.Start();
  for (int i = 0; i < 10; ++i) {
    thread_pool.EnqueueRun(IncrementRoutine, &arg_data);
  }
  ASSERT_TRUE(thread_pool.EnqueueRun(ReleaseSemaphoreRoutine, &semaphore));
  ASSERT_TRUE(semaphore.Wait(50));
  ASSERT_TRUE(thread_pool.Stop(50));
  EXPECT_EQ(10, num);
}
예제 #14
0
ResultVal<SharedPtr<Semaphore>> Semaphore::Create(s32 initial_count, s32 max_count,
                                                  std::string name) {

    if (initial_count > max_count)
        return ERR_INVALID_COMBINATION_KERNEL;

    SharedPtr<Semaphore> semaphore(new Semaphore);

    // When the semaphore is created, some slots are reserved for other threads,
    // and the rest is reserved for the caller thread
    semaphore->max_count = max_count;
    semaphore->available_count = initial_count;
    semaphore->name = std::move(name);

    return MakeResult<SharedPtr<Semaphore>>(std::move(semaphore));
}
예제 #15
0
ResultVal<SharedPtr<Semaphore>> Semaphore::Create(s32 initial_count, s32 max_count,
        std::string name) {

    if (initial_count > max_count)
        return ResultCode(ErrorDescription::InvalidCombination, ErrorModule::Kernel,
                          ErrorSummary::WrongArgument, ErrorLevel::Permanent);

    SharedPtr<Semaphore> semaphore(new Semaphore);

    // When the semaphore is created, some slots are reserved for other threads,
    // and the rest is reserved for the caller thread
    semaphore->max_count = max_count;
    semaphore->available_count = initial_count;
    semaphore->name = std::move(name);

    return MakeResult<SharedPtr<Semaphore>>(std::move(semaphore));
}
예제 #16
0
  void testWithTwoThreads( void )
  {
    TEST_HEADER;

    Semaphore semaphore(2);
    TS_ASSERT_EQUALS( semaphore.getCount(), 2 );

    ThreadClassWithSemaphore *t1 = new ThreadClassWithSemaphore(semaphore);
    ThreadClassWithSemaphore *t2 = new ThreadClassWithSemaphore(semaphore);
    t1->start();
    t2->start();

    sleep(1);

    TS_ASSERT_EQUALS( t1->use(), true );
    TS_ASSERT_EQUALS( semaphore.getCount(), 1 );
    TS_ASSERT_EQUALS( t1->use(), true );
    TS_ASSERT_EQUALS( semaphore.getCount(), 0 );
    TS_ASSERT_EQUALS( t1->use(1), false );

    TS_ASSERT_EQUALS( t2->use(1), false );
    TS_ASSERT_EQUALS( semaphore.getCount(), 0 );
    TS_ASSERT_EQUALS( t1->release(), true );
    TS_ASSERT_EQUALS( semaphore.getCount(), 1 );
    TS_ASSERT_EQUALS( t2->use(1), true );
    TS_ASSERT_EQUALS( semaphore.getCount(), 0 );

    TS_ASSERT_EQUALS( t2->release(), true );
    TS_ASSERT_EQUALS( semaphore.getCount(), 1 );

    // t2 releases instead of the using t1
    TS_ASSERT_EQUALS( t2->release(), true );
    TS_ASSERT_EQUALS( semaphore.getCount(), 2 );
    TS_ASSERT_EQUALS( t2->release(), false );

    t1->stop();
    t2->stop();
    t1->join();
    t2->join();

    delete t1;
    delete t2;
  }
예제 #17
0
void SkBaseSemaphore::osSignal(int n) { semaphore(this)->signal(n); }
예제 #18
0
void SkBaseSemaphore::osWait() { semaphore(this)->wait(); }
예제 #19
0
inline bool shm_named_semaphore::timed_wait(const boost::posix_time::ptime &abs_time)
{  return semaphore()->timed_wait(abs_time); }
예제 #20
0
inline bool shm_named_semaphore::try_wait()
{  return semaphore()->try_wait();   }
예제 #21
0
inline void shm_named_semaphore::wait()
{  semaphore()->wait();   }
예제 #22
0
inline void shm_named_semaphore::post()
{  semaphore()->post();   }
예제 #23
0
void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
{
    int        id = event.GetId();
    wxPoint    pos;
    bool       redraw = false;

    INSTALL_UNBUFFERED_DC( dc, m_canvas );

    wxGetMousePosition( &pos.x, &pos.y );

    pos.y += 20;

    switch( id )
    {
    case wxID_CUT:
    case wxID_COPY:
    case ID_TOOLBARH_PCB_SELECT_LAYER:
    case ID_MODEDIT_PAD_SETTINGS:
    case ID_PCB_USER_GRID_SETUP:
    case ID_POPUP_PCB_ROTATE_TEXTEPCB:
    case ID_POPUP_PCB_EDIT_TEXTEPCB:
    case ID_POPUP_PCB_ROTATE_TEXTMODULE:
    case ID_POPUP_PCB_ROTATE_MODULE_CLOCKWISE:
    case ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE:
    case ID_POPUP_PCB_EDIT_TEXTMODULE:
    case ID_POPUP_PCB_IMPORT_PAD_SETTINGS:
    case ID_POPUP_PCB_EXPORT_PAD_SETTINGS:
    case ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS:
    case ID_POPUP_PCB_STOP_CURRENT_DRAWING:
    case ID_POPUP_MODEDIT_EDIT_BODY_ITEM:
    case ID_POPUP_MODEDIT_EDIT_WIDTH_CURRENT_EDGE:
    case ID_POPUP_MODEDIT_EDIT_WIDTH_ALL_EDGE:
    case ID_POPUP_MODEDIT_EDIT_LAYER_CURRENT_EDGE:
    case ID_POPUP_MODEDIT_EDIT_LAYER_ALL_EDGE:
    case ID_POPUP_MODEDIT_ENTER_EDGE_WIDTH:
    case ID_POPUP_PCB_DELETE_EDGE:
    case ID_POPUP_PCB_DELETE_TEXTMODULE:
    case ID_POPUP_PCB_DELETE_PAD:
    case ID_POPUP_DELETE_BLOCK:
    case ID_POPUP_PLACE_BLOCK:
    case ID_POPUP_ZOOM_BLOCK:
    case ID_POPUP_MIRROR_X_BLOCK:
    case ID_POPUP_ROTATE_BLOCK:
    case ID_POPUP_COPY_BLOCK:
        break;

    case ID_POPUP_CANCEL_CURRENT_COMMAND:
    default:
        if( m_canvas->IsMouseCaptured() )
        {
            //  for all other commands: stop the move in progress
            m_canvas->CallEndMouseCapture( &dc );
        }

        if( id != ID_POPUP_CANCEL_CURRENT_COMMAND )
            SetToolID( ID_NO_TOOL_SELECTED, m_canvas->GetDefaultCursor(), wxEmptyString );

        break;
    }

    switch( id )
    {
    case ID_EXIT:
        Close( true );
        break;

    case ID_MODEDIT_SELECT_CURRENT_LIB:
        Select_Active_Library();
        break;

    case ID_OPEN_MODULE_VIEWER:
        {
            FOOTPRINT_VIEWER_FRAME * viewer = FOOTPRINT_VIEWER_FRAME::GetActiveFootprintViewer();
            if( viewer == NULL )
            {
                viewer = new FOOTPRINT_VIEWER_FRAME( this, NULL );
                viewer->Show( true );
                viewer->Zoom_Automatique( false );
            }
            else
            {
                if( viewer->IsIconized() )
                     viewer->Iconize( false );

                viewer->Raise();

                // Raising the window does not set the focus on Linux.  This should work on
                // any platform.
                if( wxWindow::FindFocus() != viewer )
                    viewer->SetFocus();
            }
        }
        break;

    case ID_MODEDIT_DELETE_PART:
        DeleteModuleFromCurrentLibrary();
        break;

    case ID_MODEDIT_NEW_MODULE:
        {
            Clear_Pcb( true );
            GetScreen()->ClearUndoRedoList();
            SetCurItem( NULL );
            GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) );

            MODULE* module = Create_1_Module( wxEmptyString );

            if( module )        // i.e. if create module command not aborted
            {
                // Initialize data relative to nets and netclasses (for a new
                // module the defaults are used)
                // This is mandatory to handle and draw pads
                GetBoard()->BuildListOfNets();
                redraw = true;
                module->SetPosition( wxPoint( 0, 0 ) );

                if( GetBoard()->m_Modules )
                    GetBoard()->m_Modules->ClearFlags();

                Zoom_Automatique( false );
            }
        }
        break;

    case ID_MODEDIT_NEW_MODULE_FROM_WIZARD:
        {
            Clear_Pcb( true );
            GetScreen()->ClearUndoRedoList();
            SetCurItem( NULL );
            GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) );

            wxSemaphore semaphore( 0, 1 );
            FOOTPRINT_WIZARD_FRAME *wizard = new FOOTPRINT_WIZARD_FRAME( this, &semaphore,
                                KICAD_DEFAULT_DRAWFRAME_STYLE | wxFRAME_FLOAT_ON_PARENT );
            wizard->Show( true );
            wizard->Zoom_Automatique( false );

            while( semaphore.TryWait() == wxSEMA_BUSY ) // Wait for viewer closing event
            {
                wxYield();
                wxMilliSleep( 50 );
            }

            MODULE* module = wizard->GetBuiltFootprint();

            if( module )        // i.e. if create module command not aborted
            {
                /* Here we should make a copy of the object before adding to board*/
                module->SetParent( (EDA_ITEM*)GetBoard() );
                GetBoard()->m_Modules.Append( module );

                // Initialize data relative to nets and netclasses (for a new
                // module the defaults are used)
                // This is mandatory to handle and draw pads
                GetBoard()->BuildListOfNets();
                redraw = true;
                module->SetPosition( wxPoint( 0, 0 ) );

                if( GetBoard()->m_Modules )
                    GetBoard()->m_Modules->ClearFlags();


            }

            wizard->Destroy();
        }
        break;

    case ID_MODEDIT_SAVE_LIBMODULE:
        if( GetBoard()->m_Modules && getLibPath() != wxEmptyString )
        {
            Save_Module_In_Library( getLibPath(), GetBoard()->m_Modules, true, true );
            GetScreen()->ClrModify();
        }
        break;

    case ID_MODEDIT_INSERT_MODULE_IN_BOARD:
    case ID_MODEDIT_UPDATE_MODULE_IN_BOARD:
        {
            // update module in the current board,
            // not just add it to the board with total disregard for the netlist...
            PCB_EDIT_FRAME* pcbframe = (PCB_EDIT_FRAME*) GetParent();
            BOARD*          mainpcb  = pcbframe->GetBoard();
            MODULE*         source_module  = NULL;
            MODULE*         module_in_edit = GetBoard()->m_Modules;

            // Search the old module (source) if exists
            // Because this source could be deleted when editing the main board...
            if( module_in_edit->m_Link )        // this is not a new module ...
            {
                source_module = mainpcb->m_Modules;

                for( ; source_module != NULL; source_module = (MODULE*) source_module->Next() )
                {
                    if( module_in_edit->m_Link == source_module->GetTimeStamp() )
                        break;
                }
            }

            if( ( source_module == NULL )
                && ( id == ID_MODEDIT_UPDATE_MODULE_IN_BOARD ) ) // source not found
            {
                wxString msg;
                msg.Printf( _( "Unable to find the footprint source on the main board" ) );
                msg << _( "\nCannot update the footprint" );
                DisplayError( this, msg );
                break;
            }

            if( ( source_module != NULL )
                && ( id == ID_MODEDIT_INSERT_MODULE_IN_BOARD ) ) // source not found
            {
                wxString msg;
                msg.Printf( _( "A footprint source was found on the main board" ) );
                msg << _( "\nCannot insert this footprint" );
                DisplayError( this, msg );
                break;
            }

            // Create the "new" module
            MODULE* newmodule = new MODULE( *module_in_edit );
            newmodule->SetParent( mainpcb );
            newmodule->m_Link = 0;

            // Put the footprint in the main pcb linked list.
            mainpcb->Add( newmodule );

            if( source_module )         // this is an update command
            {
                // In the main board,
                // the new module replace the old module (pos, orient, ref, value
                // and connexions are kept)
                // and the source_module (old module) is deleted
                PICKED_ITEMS_LIST pickList;
                pcbframe->Exchange_Module( source_module, newmodule, &pickList );
                newmodule->SetTimeStamp( module_in_edit->m_Link );

                if( pickList.GetCount() )
                    pcbframe->SaveCopyInUndoList( pickList, UR_UNSPECIFIED );
            }
            else        // This is an insert command
            {
                wxPoint cursor_pos = pcbframe->GetScreen()->GetCrossHairPosition();
                pcbframe->GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) );
                pcbframe->PlaceModule( newmodule, NULL );
                pcbframe->GetScreen()->SetCrossHairPosition( cursor_pos );
                newmodule->SetTimeStamp( GetNewTimeStamp() );
                pcbframe->SaveCopyInUndoList( newmodule, UR_NEW );
            }

            newmodule->ClearFlags();
            GetScreen()->ClrModify();
            pcbframe->SetCurItem( NULL );
            mainpcb->m_Status_Pcb = 0;
        }
        break;

    case ID_MODEDIT_IMPORT_PART:
        if( ! Clear_Pcb( true ) )
            break;                  // //this command is aborted

        GetScreen()->ClearUndoRedoList();
        SetCurItem( NULL );
        GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) );
        Import_Module();
        redraw = true;

        if( GetBoard()->m_Modules )
            GetBoard()->m_Modules->ClearFlags();

        GetScreen()->ClrModify();
        Zoom_Automatique( false );

        if( m_Draw3DFrame )
            m_Draw3DFrame->NewDisplay();

        break;

    case ID_MODEDIT_EXPORT_PART:
        if( GetBoard()->m_Modules )
            Export_Module( GetBoard()->m_Modules );
        break;

    case ID_MODEDIT_CREATE_NEW_LIB_AND_SAVE_CURRENT_PART:
        if( GetBoard()->m_Modules )
        {
            // CreateModuleLibrary() only creates a new library, does not save footprint
            wxString libPath = CreateNewLibrary();
            if( libPath.size() )
                SaveCurrentModule( &libPath );
        }
        break;

    case ID_MODEDIT_SHEET_SET:
        break;

    case ID_MODEDIT_LOAD_MODULE:
        {
            wxString libPath = getLibPath();    // might be empty

            wxLogDebug( wxT( "Loading module from library " ) + libPath );

            GetScreen()->ClearUndoRedoList();
            SetCurItem( NULL );
            Clear_Pcb( true );
            GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) );
            Load_Module_From_Library( libPath, true );
            redraw = true;
        }

        if( GetBoard()->m_Modules )
            GetBoard()->m_Modules->ClearFlags();

        // if either m_Reference or m_Value are gone, reinstall them -
        // otherwise you cannot see what you are doing on board
        if( GetBoard() && GetBoard()->m_Modules )
        {
            TEXTE_MODULE* ref = GetBoard()->m_Modules->m_Reference;
            TEXTE_MODULE* val = GetBoard()->m_Modules->m_Value;

            if( val && ref )
            {
                ref->SetType( TEXT_is_REFERENCE );    // just in case ...

                if( ref->m_Text.Length() == 0 )
                    ref->m_Text = L"Ref**";

                val->SetType( TEXT_is_VALUE );        // just in case ...

                if( val->m_Text.Length() == 0 )
                    val->m_Text = L"Val**";
            }
        }

        GetScreen()->ClrModify();
        Zoom_Automatique( false );

        if( m_Draw3DFrame )
            m_Draw3DFrame->NewDisplay();

        break;

    case ID_MODEDIT_PAD_SETTINGS:
        InstallPadOptionsFrame( NULL );
        break;

    case ID_MODEDIT_CHECK:
        break;

    case ID_MODEDIT_EDIT_MODULE_PROPERTIES:
        if( GetBoard()->m_Modules )
        {
            SetCurItem( GetBoard()->m_Modules );
            DIALOG_MODULE_MODULE_EDITOR dialog( this, (MODULE*) GetScreen()-> GetCurItem() );
            int ret = dialog.ShowModal();
            GetScreen()->GetCurItem()->ClearFlags();

            if( ret > 0 )
                m_canvas->Refresh();
        }
        break;

    case ID_POPUP_CLOSE_CURRENT_TOOL:
        break;

    case ID_POPUP_CANCEL_CURRENT_COMMAND:
        break;

    case ID_POPUP_PCB_ROTATE_MODULE_COUNTERCLOCKWISE:
        m_canvas->MoveCursorToCrossHair();
        Rotate_Module( NULL, (MODULE*) GetScreen()->GetCurItem(), 900, true );
        redraw = true;
        break;

    case ID_POPUP_PCB_ROTATE_MODULE_CLOCKWISE:
        m_canvas->MoveCursorToCrossHair();
        Rotate_Module( NULL, (MODULE*) GetScreen()->GetCurItem(), -900, true );
        redraw = true;
        break;

    case ID_POPUP_PCB_EDIT_MODULE:
        {
            DIALOG_MODULE_MODULE_EDITOR dialog( this, (MODULE*) GetScreen()->GetCurItem() );
            int ret = dialog.ShowModal();
            GetScreen()->GetCurItem()->ClearFlags();
            GetScreen()->GetCurItem()->ClearFlags();
            m_canvas->MoveCursorToCrossHair();

            if( ret > 0 )
                m_canvas->Refresh();
        }
        break;

    case ID_POPUP_PCB_MOVE_PAD_REQUEST:
        m_canvas->MoveCursorToCrossHair();
        StartMovePad( (D_PAD*) GetScreen()->GetCurItem(), &dc, false );
        break;

    case ID_POPUP_PCB_EDIT_PAD:
        InstallPadOptionsFrame( (D_PAD*) GetScreen()->GetCurItem() );
        m_canvas->MoveCursorToCrossHair();
    break;

    case ID_POPUP_PCB_DELETE_PAD:
        SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
        DeletePad( (D_PAD*) GetScreen()->GetCurItem(), false );
        SetCurItem( NULL );
        m_canvas->MoveCursorToCrossHair();
        break;

    case ID_POPUP_PCB_IMPORT_PAD_SETTINGS:
        SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
        m_canvas->MoveCursorToCrossHair();
        Import_Pad_Settings( (D_PAD*) GetScreen()->GetCurItem(), true );
        break;

    case ID_POPUP_PCB_GLOBAL_IMPORT_PAD_SETTINGS:
        SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
        // Calls the global change dialog:
        DlgGlobalChange_PadSettings( (D_PAD*) GetScreen()->GetCurItem() );
        m_canvas->MoveCursorToCrossHair();
        break;

    case ID_POPUP_PCB_EXPORT_PAD_SETTINGS:
        m_canvas->MoveCursorToCrossHair();
        Export_Pad_Settings( (D_PAD*) GetScreen()->GetCurItem() );
        break;

    case ID_POPUP_PCB_EDIT_TEXTMODULE:
        InstallTextModOptionsFrame( (TEXTE_MODULE*) GetScreen()->GetCurItem(), &dc );
        m_canvas->MoveCursorToCrossHair();
        break;

    case ID_POPUP_PCB_MOVE_TEXTMODULE_REQUEST:
        m_canvas->MoveCursorToCrossHair();
        StartMoveTexteModule( (TEXTE_MODULE*) GetScreen()->GetCurItem(), &dc );
        break;

    case ID_POPUP_PCB_ROTATE_TEXTMODULE:
        RotateTextModule( (TEXTE_MODULE*) GetScreen()->GetCurItem(), &dc );
        m_canvas->MoveCursorToCrossHair();
        break;

    case ID_POPUP_PCB_DELETE_TEXTMODULE:
        SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
        DeleteTextModule( (TEXTE_MODULE*) GetScreen()->GetCurItem() );
        SetCurItem( NULL );
        m_canvas->MoveCursorToCrossHair();
        break;

    case ID_POPUP_PCB_MOVE_EDGE:
        Start_Move_EdgeMod( (EDGE_MODULE*) GetScreen()->GetCurItem(), &dc );
        m_canvas->MoveCursorToCrossHair();
        break;

    case ID_POPUP_PCB_STOP_CURRENT_DRAWING:
        m_canvas->MoveCursorToCrossHair();

        if( GetScreen()->GetCurItem()->IsNew() )
        {
            End_Edge_Module( (EDGE_MODULE*) GetScreen()->GetCurItem() );
            SetCurItem( NULL );
        }
        break;

    case ID_POPUP_MODEDIT_ENTER_EDGE_WIDTH:
        {
            EDGE_MODULE* edge = NULL;
            if( GetScreen()->GetCurItem()
              && ( GetScreen()->GetCurItem()->Type() == PCB_MODULE_EDGE_T ) )
            {
                edge = (EDGE_MODULE*) GetScreen()->GetCurItem();
            }

            Enter_Edge_Width( edge );
            m_canvas->MoveCursorToCrossHair();

            if( edge )
                m_canvas->Refresh();
        }
        break;

    case  ID_POPUP_MODEDIT_EDIT_BODY_ITEM :
        m_canvas->MoveCursorToCrossHair();
        InstallFootprintBodyItemPropertiesDlg( (EDGE_MODULE*) GetScreen()->GetCurItem() );
        m_canvas->Refresh();
        break;

    case ID_POPUP_MODEDIT_EDIT_WIDTH_CURRENT_EDGE:
        m_canvas->MoveCursorToCrossHair();
        Edit_Edge_Width( (EDGE_MODULE*) GetScreen()->GetCurItem() );
        m_canvas->Refresh();
        break;

    case ID_POPUP_MODEDIT_EDIT_WIDTH_ALL_EDGE:
        m_canvas->MoveCursorToCrossHair();
        Edit_Edge_Width( NULL );
        m_canvas->Refresh();
        break;

    case ID_POPUP_MODEDIT_EDIT_LAYER_CURRENT_EDGE:
        m_canvas->MoveCursorToCrossHair();
        Edit_Edge_Layer( (EDGE_MODULE*) GetScreen()->GetCurItem() );
        m_canvas->Refresh();
        break;

    case ID_POPUP_MODEDIT_EDIT_LAYER_ALL_EDGE:
        m_canvas->MoveCursorToCrossHair();
        Edit_Edge_Layer( NULL );
        m_canvas->Refresh();
        break;

    case ID_POPUP_PCB_DELETE_EDGE:
        SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
        m_canvas->MoveCursorToCrossHair();
        RemoveStruct( GetScreen()->GetCurItem() );
        SetCurItem( NULL );
        break;

    case ID_MODEDIT_MODULE_ROTATE:
    case ID_MODEDIT_MODULE_MIRROR:
        SaveCopyInUndoList( GetBoard()->m_Modules, UR_MODEDIT );
        Transform( (MODULE*) GetScreen()->GetCurItem(), id );
        redraw = true;
        break;

    case ID_PCB_DRAWINGS_WIDTHS_SETUP:
        InstallOptionsFrame( pos );
        break;

    case ID_PCB_PAD_SETUP:
        {
            BOARD_ITEM* item = GetCurItem();

            if( item )
            {
                if( item->Type() != PCB_PAD_T )
                    item = NULL;
            }

            InstallPadOptionsFrame( (D_PAD*) item );
        }
        break;

    case ID_PCB_USER_GRID_SETUP:
        InstallGridFrame( pos );
        break;

    case ID_POPUP_PLACE_BLOCK:
        GetScreen()->m_BlockLocate.SetCommand( BLOCK_MOVE );
        m_canvas->SetAutoPanRequest( false );
        HandleBlockPlace( &dc );
        break;

    case ID_POPUP_COPY_BLOCK:
        GetScreen()->m_BlockLocate.SetCommand( BLOCK_COPY );
        GetScreen()->m_BlockLocate.SetMessageBlock( this );
        m_canvas->SetAutoPanRequest( false );
        HandleBlockPlace( &dc );
        break;

    case ID_POPUP_ZOOM_BLOCK:
        GetScreen()->m_BlockLocate.SetCommand( BLOCK_ZOOM );
        GetScreen()->m_BlockLocate.SetMessageBlock( this );
        HandleBlockEnd( &dc );
        break;

    case ID_POPUP_DELETE_BLOCK:
        GetScreen()->m_BlockLocate.SetCommand( BLOCK_DELETE );
        GetScreen()->m_BlockLocate.SetMessageBlock( this );
        HandleBlockEnd( &dc );
        break;

    case ID_POPUP_ROTATE_BLOCK:
        GetScreen()->m_BlockLocate.SetCommand( BLOCK_ROTATE );
        GetScreen()->m_BlockLocate.SetMessageBlock( this );
        HandleBlockEnd( &dc );
        break;

    case ID_POPUP_MIRROR_X_BLOCK:
        GetScreen()->m_BlockLocate.SetCommand( BLOCK_MIRROR_X );
        GetScreen()->m_BlockLocate.SetMessageBlock( this );
        HandleBlockEnd( &dc );
        break;

    default:
        DisplayError( this,
                      wxT( "FOOTPRINT_EDIT_FRAME::Process_Special_Functions error" ) );
        break;
    }

    if( redraw )
        m_canvas->Refresh();
}